- 经验来源
- 本文基于我在一个生产级 AI 应用里设计、重构「多模型路由与熔断层」的一线实践,已剥离具体业务背景,只保留可迁移的架构判断。
- 判断边界
- 文中的阈值、并发数、冷却时间都是结合具体规模调出来的经验值,不是普适配置。落到你的系统请以自己的流量画像和 SLA 为准。
为什么单一供应商是经营风险,而不只是技术问题
对单一模型供应商的依赖是一种真实的经营风险,而不是一句"加个 fallback 就好"的工程细节。API 抖动、限流、区域故障、悄无声息的涨价——任何一项都直接打在用户体验和成本账单上。当这些应对逻辑散落在二十个调用点里,每个点各写一段 try/catch、各配一个超时、各自决定要不要切备用模型时,你其实是把供应链管理这件事外包给了"写得最随手的那个调用点"。
所以我把这一层的定位写成一句话:上游对接多家供应商,下游给所有 AI 功能提供按"角色"抽象的统一入口。业务只声明"我要干什么活",模型选择、降级、恢复全部由这一层兜住。它把"换模型"从一次研发排期变成一次后台配置,把"供应商故障"从一次线上事故变成一次自动降级。
判断一个 AI 系统成不成熟,别看它正常流程跑得多漂亮,看它的失败路径设计得有多认真。
按"任务角色"路由,而不是按调用点路由
第一个关键决策是路由的粒度。我没有按"哪段代码在调模型"来路由,而是把全站 AI 调用收敛成有限的几类任务角色:高复杂度推理、日常回复、创意生成、意图分类、结构化抽取、摘要、主动消息、检索扩写、视觉、语音脚本、评测裁判。每个角色独立配置主模型、兜底模型和思考模式。
好处是新增供应商或调价时,运营在后台按角色逐个切换、灰度观察,完全不碰代码。但"配置化"不等于"全交给运营自由发挥"——意图识别、检索改写这类结构化/前置角色会被强制关闭 thinking,防止模型把推理过程写进需要被解析的结果或检索 query 里。自由度是按角色发的,不是一刀切。
质量红线:不是所有任务都接受降级
很多人把"降级"理解成一个全局开关:供应商挂了就全站切小模型。这是错的。我给任务分了"可用性档位":高复杂度推理这类"算错代价很高"的活,宁可返回 503 也不降级到小模型——一次"请稍后再试"远比一个看起来对、其实算错了的答案便宜;而常规对话类任务则自动切到兜底模型继续服务。
关键在于把"哪些活能将就、哪些活不能"显式写进路由规则,而不是默默给用户一个降质答案。降级是一种风险定价决策,应该被人显式做出,而不是在故障的慌乱里由某段代码顺手决定。
| 任务类型 | 供应商故障时 | 理由 |
|---|---|---|
| 高复杂度推理(涉及精确计算) | 返回 503,不降级 | 算错的代价高于一次重试 |
| 常规对话 / 摘要 | 自动切兜底模型 | 质量略降可接受,可用性优先 |
| 意图分类 | 熔断后落默认意图 | 分类器可降级,服务不能不可用 |
三态熔断 + 全局单飞探针
每家供应商一个熔断器,三态:健康 / 半开 / 熔断。连续失败自动跳闸,把流量切走;冷却期后只放一个真实请求去做恢复探测,探测成功全量恢复,失败回到熔断态重新冷却。供应商恢复后系统自动回切,不需要人工干预。
多实例部署时这里有个容易踩的坑:如果每个实例各自探测,一个刚要恢复的供应商会被 N 个实例同时打上去,瞬间又被打挂——这叫恢复期踩踏。我的做法是用分布式锁保证全局只有一个探针,熔断状态、探针锁、并发配额全部经 Redis 跨实例共享,N 个实例对"供应商是否健康"有一致视图。Redis 自身故障时,整层优雅退化为单实例行为,不阻断请求。
错误分级:分得清"它坏了"和"我错了"
这是最值得单独讲的一条纪律。只有可用性错误(5xx、超时、网络故障)才计入熔断;4xx 类错误说明服务可达、是请求本身的问题,绝不触发熔断。否则一个有 bug 的提示词会把整个供应商拉闸、殃及全部依赖它的功能——你的某次参数写错,不该变成全站模型不可用的事故。
限流(429)单独处理:按服务端指示退避重试,并且设单次与累计双重预算,不无限等待。把"它坏了"和"我错了"在错误处理层就分开,是这层能稳定运转的前提。
复杂度驱动升级:贵模型只花在难问题上
熔断解决"坏了怎么办",升级解决"该用多强的模型"。同一句话用最强模型答既慢又贵,用便宜模型答又可能在难题上翻车——所以在路由层之上再叠一层按问题复杂度动态选档:简单问题走便宜的常规模型,复杂问题升级到强模型加思考模式。
这套机制里我最满意的一个判断是信号怎么拿:让本就要跑一次的意图分类小模型顺带打一个 0–1 的难度分。这几乎是零额外成本、语言无关、还可解释的复杂度信号——比单独再调一次 LLM 判断难度划算得多。再融合确定性关键词分(作下限保底)和工具数 / 对话深度,得到一个可解释的升级决策,每次升级都带"为什么"(哪个信号触发的)。
怎么证明它有用:反事实指标
这层基建有个尴尬的属性:它做得好的时候没人感知。没有故障、没有超支、没有人投诉,恰恰是它在正常工作。所以它的衡量重心不能放在正向指标上,而要放在反事实指标上——每一次自动降级、每一次自动恢复,都是一次"如果没有这层就会发生的线上事故"。降级事件日志,就是这层基建的 ROI 台账。
我实际盯的几类信号:按角色拆分的降级请求占比;熔断开启次数与时长;探针首次即恢复的比例(太低说明冷却期配置不合理);高复杂度任务的 503 率(升高说明主供应商不稳,该去谈供应商或扩兜底,而不是放松降级红线);以及各角色的单位调用成本趋势,作为换模型 / 调档位的决策依据。
总结:业务声明意图,平台兜底执行
如果只带走一句话,我希望是这句:多模型路由的设计哲学是"业务声明意图,平台兜底执行"。业务代码只说"我要干什么角色的活",至于用哪家模型、坏了切谁、贵模型什么时候才上场,全部收敛到这一层。它和意图识别的熔断保底、记忆系统的召回降级是同一套纪律:任何增强能力的故障都不能成为服务不可用的原因,且每次降级都被记录、可量化。
这层的演进顺序也值得抄:一期先解决"能不能换"(议价权)→ 二期解决"坏了怎么办"(可用性)→ 三期解决"规模化下还对不对"(跨实例一致性与精细度)。每一期都对应一个真实发生过的痛点,而不是一开始就追求完美架构。
欢迎通过邮件和我交流:shaoyanyan91@163.com