一次多模型路由策略的简化记录
补档说明:本文属于「AI 工程落地周记」系列,计划发布时间为 2025-10-05 16:10。当前先保留为草稿,后续补充真实案例、代码片段和复盘细节后再发布。
有一阵子我们把多模型路由做得越来越“聪明”:
- 先按任务类型分
- 再按风险等级分
- 再按上下文长度分
- 再按历史命中率分
- 失败后还有二级 fallback
纸面上看,这套策略非常精细。真正上线后,问题却越来越明显:
- 成本走势很难解释
- 某个请求为什么走了某个模型很难追
- 调一条规则,别的路径会不会被带偏不清楚
- 出现效果抖动时,排查几乎像在查一个“规则黑箱”
后来我们做了一次很克制的重构:不是继续加规则,而是把路由策略砍掉一大半。结果反而更稳了。
复杂的不是模型数量,而是路由层的可解释性
多模型路由最容易让人上瘾的地方在于:每加一条规则,都像是在补一个洞。
例如:
- 长上下文走大模型
- 高风险走强模型
- 结构化输出失败再回退一次
- 某类短问答走便宜模型
局部看都合理,但当规则叠到一定程度后,系统的真实成本就不在模型上,而在路由本身的复杂性上。
因为你需要额外维护:
- 规则优先级
- 冲突处理
- 命中日志
- fallback 路径
- 每条路径的评测与回归
这已经不是“选模型”了,而是在维护一个推理调度系统。
我们当时为什么决定简化
真正触发简化的不是某次大事故,而是这些持续的小信号:
fallback 比例解释不清
某些请求成本波动很大
线上 trace 太长但结论不明确
同样问题在两周内路由路径经常变
这些信号说明一个问题:路由规则已经开始吞噬团队的认知预算。
后来我们把它砍成了三层
我们最后把原来一大串判定逻辑收敛成三层:
第一层:默认模型
绝大部分请求先走一个性价比最好的默认模型。
第二层:明确升级条件
只有满足少数几个清晰条件才升级,例如:
- 上下文超长
- 高风险分类命中
- 结构化任务且旧模型已知不稳定
第三层:单次 fallback
如果默认模型失败,允许一次受控 fallback,但不再做多级递归回退。
大致像这样:
function routeRequest(input: RequestContext) {
if (input.riskLevel === 'high') return 'strong-model'
if (input.contextTokens > 12000) return 'long-context-model'
return 'default-model'
}
function fallbackModel(primary: string, reason: string) {
if (reason === 'schema_parse_failed') return 'strong-model'
return null
}
这套逻辑不算“最聪明”,但它有一个特别大的优点:人能看懂。
简化之后实际改善了什么
1. 路径可解释
一个请求为什么走这条路,基本能一句话说明白。
2. 评测能对齐
路由分支少了之后,每条路径都更容易单独做评测和回归。
3. 成本更容易控
你终于能清楚知道:
- 默认模型吃了多少流量
- 升级条件触发了多少次
- fallback 到底是正常保护,还是系统异常信号
4. 排障速度更快
以前排一个异常请求,先要理解一长串路由树。
现在路径短了,根因也更容易收敛。
我现在对多模型路由的一个偏见
我越来越倾向于认为:
多模型路由的上限,不是由你能写多少规则决定的,而是由团队能稳定理解多少条路径决定的。
一旦路径数超过人脑能长期掌控的范围,系统就会开始以“局部聪明、整体难管”的方式变差。
什么时候该加规则,什么时候该删规则
我现在会用两个问题判断:
- 这条规则能否稳定提升某一类明确场景?
- 这条规则的命中和收益能否被单独观测?
如果答案都不够清楚,我更愿意不加。
因为路由规则一旦上线,就不是一行 if,而是一条要长期被维护的行为分支。
总结
这次多模型路由策略的简化记录,最后留下的结论很直接:
路由不是越细越高级,很多时候越简单越可控,越可控才越接近真实收益。
对 AI 系统来说,真正有价值的不是把每个请求都“精细优化”到极致,而是用足够少、足够清楚、足够可观测的路径,把大部分请求稳定接住。
