AI 网关模型路由策略:按成本、能力与延迟如何选
模型路由是 AI 网关的核心能力——同一个请求,选对模型可以在满足质量要求的前提下大幅降低成本或延迟。本文梳理三类主要路由策略的原理、适用场景及配置思路。
如果你是从「先跑通一个单模型代理」过来的,大概率踩过这个坑:某天早上突然发现某个上游返回 429(超限流)或者账单突然翻倍,排查半天才发现是某个后台任务默默把所有请求都打到了最贵的模型上。路由策略要解决的正是这类问题——把「选哪个模型」这件事从写死在业务代码里,挪到网关这一层统一决策,业务代码只管发请求,模型怎么选、出问题了切哪个备用,都交给网关。下面按实际踩坑的顺序讲。
三类路由策略概览
| 策略类型 | 核心逻辑 | 适用场景 |
|---|---|---|
| 成本优先 | 在满足上下文长度等硬约束后,选当前单价最低的模型 | 大批量异步任务、对质量容忍度较高的场景 |
| 能力匹配 | 按任务类型(代码/推理/摘要)预设模型偏好 | 多类型任务混合、各任务质量要求不同 |
| 延迟感知 | 实时测速或历史 P95 延迟,选响应最快的上游 | 实时对话、用户交互类产品 |
| 固定映射 | 模型名直接映射到特定上游 | 已定型选型、不希望自动切换 |
| 优先级/权重 | 主路由优先,主路由不可用时按权重轮询备用 | 容灾兜底、多供应商冗余 |
成本优先路由
成本优先策略的实现依赖网关实时维护一张价格表(input token 单价 + output token 单价),每次请求时根据约束条件过滤候选模型,再按单价排序选最低的。
关键约束过滤(过滤掉不满足的候选):
max_tokens是否超出模型上下文窗口- 是否需要 function calling / JSON mode 等能力
- 地域合规:数据是否只能发往境内
典型配置思路(以 LiteLLM 为例):
model_list:
- model_name: "cheap-chat"
litellm_params:
model: "gemini/gemini-1.5-flash"
- model_name: "cheap-chat"
litellm_params:
model: "deepseek/deepseek-chat"
router_settings:
routing_strategy: "cost-based-routing"
这段配置看着简单,但有两个容易被忽略的细节。第一,model_name 相同的多条 litellm_params 之间,网关默认会按价格表排序取最低价,价格表是需要人工维护并定期更新的,不是网关自己去官网抓取的。如果供应商悄悄调价(尤其是海外模型按美元计费,人民币汇率波动也会影响你换算出来的实际到手价),价格表没同步更新,路由就会基于过时数据做决策——轻则选错模型多花钱,重则选中一个已经涨价到超预算的模型。建议给价格表加一个「最后校验日期」字段,每周人工核对一次官方定价页(截至 2026-06,各家价格页更新频率不固定,DeepSeek 和 Gemini 这类竞争激烈的赛道调价更频繁)。
第二个坑是上下文窗口不匹配导致的静默降级。比如 cheap-chat 里配了两个模型,一个支持 128K 上下文,另一个只支持 32K,如果你的请求恰好带了一段较长的历史对话(比如 40K token),按成本排序取到了那个 32K 的模型,请求会直接报错而不是自动跳过——很多人以为约束过滤是「自动」生效的,其实取决于你的网关版本和配置方式,LiteLLM 需要显式开启 token_healing 或在 model_info 里声明 max_input_tokens,网关才会真正做硬过滤,不然价格表里的模型即使装不下你的输入也会被选中,然后你收到的报错是类似「context length exceeded」这种,排查起来容易先怀疑是业务代码传参错了,实际上是路由层没做窗口校验。
成本路由适合批量数据处理(文档摘要、数据清洗、翻译流水线),这类场景对响应速度不敏感,用最低价模型可降低 60%–80% 的推理成本。但有一点要提前想清楚:便宜模型的输出质量方差通常更大,同样一批 1000 条摘要任务,用旗舰模型可能 990 条都合格,换成最便宜的模型可能合格率掉到 850 条左右——省下来的钱要不要拿一部分做人工抽检或二次校验,这笔账最好在上线前就估算好,而不是等业务方投诉了才回头补救。
能力匹配路由
不同模型在不同任务上各有所长:GPT-4o 代码能力强,Claude 3.5 长文理解出色,DeepSeek-V3 中文推理有优势。能力匹配路由允许按请求标签或模型别名预先指定偏好。
实现方式一:模型别名映射
# 应用层用语义化的模型别名
client.chat.completions.create(
model="task:coding", # 网关映射到 gpt-4o
messages=[...]
)
client.chat.completions.create(
model="task:summarize", # 网关映射到 claude-3-5-sonnet
messages=[...]
)
实现方式二:请求头/元数据标签
部分网关支持在请求头中传入标签,网关根据标签选路由规则,业务代码与路由逻辑解耦。
这两种实现方式怎么选,看你团队的协作模式:
| 维度 | 模型别名映射 | 请求头/元数据标签 |
|---|---|---|
| 改路由规则要不要动业务代码 | 不用,网关侧改配置即可 | 通常也不用,但需要业务代码已经在传标签 |
| 适合团队规模 | 单团队、模型偏好统一 | 多团队共用一个网关,各自打标签 |
| 排查问题时的可读性 | 高,日志里直接看到 task:coding 这种语义化名字 | 中,需要额外查标签定义文档 |
| 灰度切换新模型的粒度 | 按别名整体切,粒度较粗 | 可以按标签组合做更细粒度灰度 |
实践中我更推荐先用别名映射把常见任务类型跑起来,等团队大了、任务类型多到别名爆炸式增长(比如出现 task:coding-python、task:coding-go 这种越拆越细的情况)再引入标签体系,一开始就上标签容易过度设计。
还有一个容易被忽略的点:能力匹配路由需要配一条兜底规则。比如 task:coding 映射到 GPT-4o,一旦 GPT-4o 那边限流或者挂了,网关如果没有为这个别名配置备用模型,请求会直接失败而不是自动切到 Claude 或者 DeepSeek 的代码能力。这就涉及到下一篇要展开的容灾与自动降级 failover,能力匹配和优先级/权重路由通常是搭配使用的,别名对应的不是单个模型,而是一个「优先级列表」。
延迟感知路由
对实时对话类产品,首 token 延迟(TTFT)直接影响用户体验。延迟感知路由的常见实现:
- 主动探活:网关定期向各上游发送轻量心跳请求,统计响应时间,更新延迟排行。
- 历史 P95 延迟:基于近 N 分钟的真实请求延迟,选 P95 最低的上游。
- 最少连接数:选当前并发请求数最少的上游,间接降低排队延迟。
上游实时延迟监控(示意)
OpenAI GPT-4o: P95 = 1.2s ← 当前选中
Anthropic Claude: P95 = 1.8s
阿里通义 Qwen-Max: P95 = 0.9s ← 时区低峰时更快
网关应能动态切换,在某上游延迟突增时自动转移流量,而不等到出现超时才响应。
这里有个概念很多人会混淆:TTFT(首 token 延迟)和总响应时间不是一回事。做延迟感知路由时,如果你监控的是总响应时间,会出现一个反直觉的现象——某个模型输出特别啰嗦(同样问题多吐 300 个 token),总耗时看起来比另一个模型长,但用户实际感知到的「等了多久才开始看到字」(也就是 TTFT)可能反而更短,因为它流式输出的首字延迟很快、只是后面吐字吐得久。如果你的产品是打字机效果的对话界面,路由决策应该盯着 TTFT 而不是总耗时,两者选错了监控指标,路由出来的「最快」模型体验上并不是真的最快。
再说一个真实会碰到的报错场景:网关做主动探活时,如果心跳请求发送频率太高(比如每 5 秒探测一次所有上游),一部分供应商会把这类心跳流量也计入你的请求配额,长期跑下去你会发现账单里多出一块「莫名其妙」的调用量,翻日志才发现是探活本身在消耗配额。解决办法要么用官方提供的专门健康检查接口(不消耗计费配额,一般文档里会标注),要么把探活间隔拉长到 30 秒以上、并用极短的 max_tokens(比如 1)降低成本。
延迟感知路由还有一种更轻量的实现:不主动探活,而是在真实业务请求里顺带打点,把每次请求的实际延迟记下来,用滑动窗口算 P95,代码逻辑跟这段一致:
上游实时延迟监控(示意)
OpenAI GPT-4o: P95 = 1.2s ← 当前选中
Anthropic Claude: P95 = 1.8s
阿里通义 Qwen-Max: P95 = 0.9s ← 时区低峰时更快
这种「被动式」延迟统计的好处是不额外产生探活流量,缺点是冷启动阶段(新上游刚接入、还没有历史数据)没法立刻判断快慢,得先按固定权重跑一段时间攒够样本量,再切换到纯延迟感知模式,一般建议攒够 50-100 次真实请求的样本再启用。
组合路由:先过滤,再排序
生产环境通常组合使用多个维度:
请求进入
│
├─ 硬过滤:模型能力、上下文长度、合规地域
│
├─ 权重过滤:优先级高的上游优先考虑
│
└─ 软排序:在候选集内按成本或延迟排序选最优
例如:先过滤掉不支持 function calling 的模型,再从剩余候选中选成本最低的,成本相同时选延迟最低的。
举一个具体的数字例子帮你理解组合路由的决策过程。假设某次请求要求支持 function calling、上下文不超过 64K,候选池里有 4 个模型:
- 硬过滤:候选池里有个模型只支持 8K 上下文,直接被淘汰,剩 3 个。
- 权重过滤:其中一个模型这周被标记为「维护中」权重设为 0,实际参与排序的剩 2 个。
- 软排序:剩下两个模型成本分别是每百万 token 2 元和 3 元,选 2 元这个;如果两者成本恰好相同,再比 P95 延迟,选延迟更低的。
整个过程网关内部通常是几十毫秒内完成的,不会成为请求延迟的主要瓶颈,你如果发现路由决策本身耗时明显(比如超过 100ms),大概率是价格表或延迟统计数据存在远程调用(比如每次都去查一次数据库或者调一次配置中心),这块建议做本地缓存,用发布/订阅或者定时拉取的方式更新,而不是每个请求都同步查一次。
常见问题
路由策略能动态调整吗? 主流网关(LiteLLM、OneAPI、力达云聚合 API)均支持通过管理界面或 API 实时修改路由规则,无需重启服务。生产环境建议做灰度变更,先调低一部分流量到新策略观察效果。
成本优先路由会不会导致质量下降? 会有质量波动风险。建议设置质量兜底:对高价值请求(如用户直接交互)固定使用高能力模型,只对后台批处理任务启用成本优先。通过模型别名或请求标签区分两类流量。
如何验证路由策略是否生效?
查看网关的请求日志,确认实际使用的上游与预期路由规则一致。大多数网关会在响应头或日志中记录 x-upstream-model 等字段。
成本路由会不会陷入 429 重试死循环? 这是实际生产里最容易踩的坑之一,值得单独展开说。如果候选池里排最前面的低价模型恰好被限流返回 429,路由策略如果只是简单地「排序取最低价」而不结合重试退避,可能会出现请求失败后立刻重试同一个模型、再次撞上限流的情况,短时间内打出一串 429,日志里全是同一个错误码刷屏。正确的做法是限流响应要触发临时降权而不是无脑重试:网关捕获到某上游连续返回 429 后,应该把它的权重临时调低(比如 30 秒内不再优先选它),让请求自动转移到候选池里的下一个模型,同时用指数退避(比如首次重试等 1 秒,失败再等 2 秒、4 秒)避免瞬间对同一个模型造成第二波压力。如果你用的网关没有内置这个能力,最简单的应急方案是业务代码里捕获 429 后手动切换到备用模型别名重试一次,而不是原样重试同一个请求。
JSON mode 或 function calling 参数传了但模型不支持怎么办? 不同模型对结构化输出的支持程度不一样,有的模型收到不认识的参数会直接报 400(参数格式错误),有的则会静默忽略该参数、返回一段看起来正常但没有按 JSON 格式约束的文本,这种「静默失败」比直接报错更麻烦,因为业务代码解析 JSON 时才会炸,而且报错信息跟路由完全对不上号,容易误判是模型「抽风」了。能力匹配路由这一层最好提前维护一张「模型能力矩阵」,把哪些模型支持 function calling、哪些支持 JSON mode、哪些两者都不支持列清楚,路由时按这张矩阵做硬过滤,而不是把参数原样透传给不支持的模型再指望它优雅降级。
多个路由策略能叠加使用吗?会不会互相冲突? 可以叠加,本文「组合路由」一节讲的就是叠加用法,但要注意执行顺序——先做硬约束过滤(能力/上下文/合规),再做软性排序(成本或延迟),顺序反了会出问题:如果先按成本排序、排序完了才做能力过滤,可能出现「最便宜的模型被选中后才发现它不支持这次请求需要的能力,只能整体推倒重新排」,白白多了一轮判断逻辑,效率上不如一开始就把顺序定死。
延伸阅读:
- 多模型聚合 API 完整指南
- 多上游负载均衡原理与配置
- 容灾与自动降级 failover
- 更多聚合 API 内容见 聚合API 专题
想快速体验智能路由?申请力达云聚合 API 内测,内置多策略路由,按需切换。