为什么要给 LLM 网关加熔断
线上调用大模型,最尴尬的不是它答错,而是它不答。上周主模型一次区域性抖动,我们三条业务链路集体卡住,最长的一条等了 42 秒还在转圈。事后复盘时我发现,我们把可用性完全交给了上游,而网关层连一个像样的降级开关都没有。
于是动手做了模型侧的断路器。思路并不新鲜,就是把服务治理里那套熔断器搬到 LLM 调用上,只是判定指标和恢复策略要重写一遍。
具体怎么做的
第一层是滑动窗口错误率。 不能用瞬时错误率,模型调用的延迟分布天然是长尾的,P99 抖动一下就能把开关打穿。我用了 30 秒窗口、200 次最小样本量,错误率超过 25% 才打开熔断。窗口太短误伤,太长失效慢,这两个数字是拿历史流量回放出来的。
第二层是超时分级。 主模型和备用模型的超时不能设成同一个值。主模型给 8 秒,备用模型给 15 秒,因为备用模型往往是尺寸小一些的模型冷启动,第一次调用有额外开销。更关键的是,熔断期间要把主模型的超时预算分一部分给备用,否则切过去照样超时。
第三层是半开探测。 熔断打开后每 10 秒放 3 个真实请求过去探路,而不是自己造测试请求。造出来的请求没有真实上下文长度,探活结果会骗人。
真正麻烦的是切换之后
切流只是开头,真正的坑在于两个模型的输出格式压根对不上。
主模型习惯输出带解释的 JSON,备用模型会多写一段以下是结果;主模型的枚举值稳定,备用模型偶尔把 pending 写成 PENDING。我们的做法是把 schema 校验从业务层抽到网关层,所有响应先过一遍归一化:去除首尾自然语言包裹、枚举值大小写折叠、字段缺失走默认值。归一化失败的样本进死信队列,不进业务。
另一件事是语义漂移没人管。降级期间备用模型的回答质量是下降的,但监控只看错误率和延迟,等用户投诉才发现。现在会在降级窗口内自动做影子对比:同一批 prompt 事后回放到主模型,比对结论一致性,每天出一份漂移报告。这个功能平时用不上,但真出事的时候它是唯一能告诉你降级期间损失多大的东西。
成本上的取舍
多模型冗余意味着要养两家供应商的配额,实测下来成本增加约 18%。这笔钱我认为值,但前提是把缓存做好——降级期间备胎模型的输入完全命中主模型那套缓存的话,实际推理调用增加不到 6%。
熔断阈值别直接抄网上的默认值。25% 这个数字在我们场景成立,是因为下游有重试;如果你的调用方本身有三次重试,同样的阈值会让熔断窗口被重试流量灌满,越熔断越严重。这种情况反而要把阈值调低、把最小样本量调高。