模型路由
一个 API Key 调用所有模型
用一个 OpenAI 兼容 Base URL 和 API Key 调用 Claude、Gemini、DeepSeek 等模型。包含配置、模型切换、费用核对与常见故障排查。
用一个 Key 调用所有模型
所谓"用一个 API 路由多个 AI 模型",指应用只保留一个 Base URL、一个 API Key 和一套请求格式,由 model 字段决定这次请求交给哪个上游供应商。不必为每家厂商各存一套凭据,新模型上线也不需要改客户端。
实际收益在运维层面:一个余额、一处轮换泄露的密钥、一套日志、一处切换模型。代价是网关进入了请求链路,因此必须验证它转发了什么、如何计算 Token。本文给出最小可用配置、用同一个 Key 调用不同模型家族的方法,以及如何与账单对账。
发出模型名之后发生了什么
一次请求通常有四样东西决定路由:模型标识、消息负载、流式开关,以及工具定义或缓存控制这类可选字段。网关把模型标识解析到已启用的渠道与价格分组,把请求转换成该供应商的原生协议,再把响应转换成 SDK 期望的格式。
上生产前要确认两点。第一,模型名带版本:试玩环境里能用的名字,未必在你密钥所属分组里存在。第二,抽象不是免费的:提示词缓存、工具调用、结构化输出、推理 Token 只有在网关真正转发时才等价。不要因为一次文本请求成功就假设功能兼容,要用实际依赖的功能逐项验证。
| 字段 | 作用 |
|---|---|
| model | 决定请求走哪个渠道与价格分组 |
| messages / input | 发送给上游的上下文,也是输入 Token 的主要来源 |
| stream | 返回 SSE 流式事件,还是一次性 JSON |
| tools、response_format | 网关是否需要转发供应商特有的能力 |
配置一个 Key 并发出第一次请求
先在API 接入创建密钥,再在价格页确认准备使用的模型。首次检查用 OpenAI 兼容端点即可,即使目标模型不是 OpenAI 模型,网关也会做转换。第一次调用要小:输出上限低、不带工具、不开缓存。
密钥放环境变量,不要写进代码。macOS 或 Linux 用 export API_ROUTE_KEY=...,只影响当前终端;Windows PowerShell 用 $env:API_ROUTE_KEY="..."。下面的示例发送一次 chat completion 并打印返回内容。
export API_ROUTE_KEY="sk-your-key"
curl https://global.api-route.com/v1/chat/completions \
-H "Authorization: Bearer $API_ROUTE_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Name one trade-off of multi-model routing."}],
"max_tokens": 80
}'返回 200 且有 choices 数组,说明请求到达了供应商并返回结果;但这还不能证明流式、工具、缓存或第二个模型家族可用。后续逐项补充验证,并用响应体核对模型名与 usage。
不换 SDK,直接切换模型家族
同一个 Key 可以调用 Claude、Gemini、DeepSeek、Qwen 等不同家族,因为网关在协议之间做转换。聊天类流量统一发到 /v1/chat/completions,只改 model 的值,请求与响应结构保持 OpenAI 兼容。
需要 Anthropic 专属行为,比如提示词缓存或某个 beta 请求头时,改用 /v1/messages 和 Anthropic 请求格式。两个端点共用同一账户余额,这正是单 Key 方案可行的原因。跨模型接口参考:OpenAI Chat Completions 与 Anthropic Messages。
from openai import OpenAI
client = OpenAI(
base_url="https://global.api-route.com/v1",
api_key="sk-your-key",
)
for model in ["claude-sonnet-4-6", "gemini-3.8-flash", "deepseek-v4.1-flash"]:
reply = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "Reply in one sentence."}],
max_tokens=60,
)
print(model, "->", reply.choices[0].message.content)const models = ["claude-sonnet-4-6", "gemini-3.8-flash"];
for (const model of models) {
const res = await fetch("https://global.api-route.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.API_ROUTE_KEY}`,
},
body: JSON.stringify({
model,
messages: [{ role: "user", content: "Reply in one sentence." }],
max_tokens: 60,
}),
});
const data = await res.json();
console.log(model, "->", data.choices?.[0]?.message?.content ?? data.error?.message);
}一个循环里跑两个模型,就足够验证路由层是否按预期工作。每次记录返回的模型名与 usage;如果模型被静默回退到另一个家族,文本看起来仍然合理,但质量与价格已经变了。
按请求选模型,而不是按项目选厂商
当一把 Key 能触达所有模型,决策就从"和哪家签约"变成"这个请求该交给哪个模型"。先给流量分类:短分类与抽取很少需要旗舰模型,长上下文分析需要,代码生成与聊天的取舍也不同。按任务路由,再用自己的评测集衡量质量,而不是看榜单标题。
价格分组和模型名同样重要:同一个模型在默认组与折扣组或企业组可能不同价,密钥所属分组决定实际支付金额。围绕某个宣传数字做预算之前,先核对价格页与调用日志里显示的分组。
| 负载类型 | 优先优化 | 典型选择 |
|---|---|---|
| 分类、抽取、打标 | 每千次调用成本 | 小尺寸快模型 |
| 长上下文分析、RAG 回答 | 上下文窗口与缓存成本 | 中端模型配合提示词缓存 |
| 复杂编码与 Agent 循环 | 正确率与工具使用 | 旗舰模型、低温度 |
| 批量生成 | 输出单价与吞吐 | 中端模型配合批处理 |
核对路由与账单
放量之前确认三件事:同一把 Key 能列出计划调用的模型、响应返回的是你要的模型、日志扣费与 usage 对得上。列模型是最便宜的检查,能发现被绑定到窄分组的密钥。
curl -s https://global.api-route.com/v1/models \
-H "Authorization: Bearer $API_ROUTE_KEY" \
| jq -r '.data[].id' | sort再把单次响应与调用日志里对应的行比较:模型、输入与输出 Token 分类、是否出现缓存字段。缓存请求应单独报告读取量;如果网关从不报告,就把缓存当作未验证,而不是折扣。为每个模型家族保留一条记录样本,便于发现后续价格或路由变化。
常见故障与对应含义
第一周遇到的问题多数是配置,而不是模型质量。下表列出优先排查的错误。反馈问题时给出请求时间、HTTP 状态码、模型名和请求 ID,不要贴出密钥本身。
| 现象 | 可能原因 | 先查什么 |
|---|---|---|
| 404 模型不存在 | 该模型未对当前密钥分组启用 | 用 /v1/models 列模型,再与价格页对照 |
| 401 或 403 | 密钥缺失、被撤销,或用了错误的请求头 | 使用 Authorization: Bearer;若已泄露立即轮换 |
| 400 指向某个 schema 字段 | 供应商不支持该关键字且网关未转换 | 先去掉该字段重试,并反馈具体参数 |
| 流式卡住或一次性返回 | 代理缓冲,或不支持该流式开关 | 先关流式重试,再用短提示测试 |
| 费用高于预期 | 分组不同,或发生的是缓存写入而非读取 | 把 usage 与日志行对比并确认分组 |
如果响应是 200 但表现像另一个模型,用固定提示词连续请求几次并比较输出,同时核对返回的模型名。一致性问题通常指向路由或回退策略,而不是提示词本身。
生产环境检查清单
- 密钥放在密钥管理服务或环境变量里,并准备第二把用于轮换。
- 固定显式模型标识而不是浮动别名,并记录验证过的版本。
- 每次配置变更后,对每个模型家族发一次固定的冒烟请求。
- 对错误率和单次请求成本设告警,而不只看总支出。
- 放量前把第一笔账单与自己记录的 usage 对一遍。
这五项到位后,一个 Key 和一个 Base URL 就足以在不同模型家族之间路由,而不用重建客户端。先用小额余额创建账户,确认密钥可用的模型列表,再按快速入门完成首次请求。