大数跨境

离线评测全绿,上线照样翻车:灰度 + 熔断才是我给 LLM 上的最后一道保险

离线评测全绿,上线照样翻车:灰度 + 熔断才是我给 LLM 上的最后一道保险 小兵的AI视界
2026-08-20
4
导读:离线评测全绿,上线照样翻车:灰度 + 熔断才是我给 LLM 上的最后一道保险
图片

我是小兵,一个动手派AI架构师。「AI工程化实战」系列第 3 篇。

那场 2:17 的翻车,不是没人监看,是没人在盯

下午 2:17,灰度发布放到 10%。

离线评测全绿,监控面板一片祥和。新版这轮优化了 prompt,让回复更短更快——谁也没想到,“更短”的代价是“不再追问”。2:18,转人工率就破了基线 3 倍——只是当时没装熔断器,这个信号没人接。

2:56,客服甩了张截图:用户问“颜色跟图片差太多,我要退,运费谁出?”,新版回“亲,退货需您自理运费哦”——可色差是描述不符,该商家出运费。

3:00,人肉回滚完成——曝光整整 43 分钟、约 2600 次请求。

不是没人监看,是监控在“看”、人没在“盯”——等红点飘满屏幕,船已经沉了一半。

为什么离线全绿还会翻车?因为离线评测是静态快照,Golden Set 三个月就过期,你测的是上个月的业务——新版这轮只是让回复更短、少问一句,歧义长尾就翻了车。真正要回答的是两个问题:不好的时候,谁先知道?谁先兜住?

自动熔断把“谁先知道”从 43 分钟压到 1 分钟(2:17 放量,2:18 转人工率破阈值就跳闸),把“谁先兜住”从人肉切流变成状态机自动回滚。下面按影子验证、分层放量、阈值推导、状态机的顺序展开。

第一步:影子验证,但别轻信“全绿”

影子模式 = 新旧版本并行,接全量真实请求,新版只计算、不对外输出。

判偏差分两级。第一级结构一致性:新版输出能不能过订单契约,过不了就是结构不合法,直接进合规致命。

第二级语义相似度:跟旧版做字段级加权比对,业务高危字段(状态、金额、商品)权重 3 倍——抽错了会写库、发货错。

然后按分数进三级处置:无害放行、业务风险阻断放量并人工复核、合规致命立即熔断一票否决。

这里必须泼盆冷水:影子全绿 ≠ 可全量。影子的暗区在于,它只镜像“旧版被请求过的流量”。用户提问后旧版答错了,用户就不会追问第二次,这段“本该有后续”的暗区流量根本没发生,新版再好也测不到。

影子通过,只意味着“新版在旧版答对的路上没跑偏”,不意味着“新版能覆盖旧版没答对的路”。所以影子只是第一道闸,后面还得走金丝雀。

第二步:金丝雀分层放量,每档双门禁

分档 1% → 5% → 10% → 30% → 100%。每档两个门禁,都过了才进下一档。

时间门禁:该档至少待够指定分钟数(1% 档 120 分钟),让指标在真实流量下攒够统计样本,也防“晚上 11 点顺手放量”的静默推进。

指标门禁:该档窗口内指标不熔断才放行。只要熔断一次,放量打回 1% 重新走,绝不断点续传。

放量维度按用户 ID 哈希取模前缀:每个用户被散列到固定槽位,放量 = 单调扩大“放行前缀”。

为什么不能每档换模数?如果你 1% 档用 %100、5% 档换 %20,升档 = 换模数 = 全量重映射,已放量的用户被切回旧版,同一次会话新老版本交替——上半句旧版答、下半句新版答,语义断裂。

固定槽位 + 单调阈值只补边界槽位,用户全程走同一版本。金融/政务等高价值强监管客户,exclude 名单一票否决,永不参与灰度。

第三步:熔断阈值,先抄表再懂为什么

阈值分两层,取向正好相反。先把结论抄走,落地就靠这张表:

信号
阈值(先抄)
一句话为什么
校准旋钮
违规
5 分钟 ≥ 3 次
3 次基本不可能是正常抖动
按档位流量缩放
Token 成本比
≥ 2.0x
翻倍是回退/重试风暴
写死
P99
≥ 3x 基线
3 倍是降档/饱和,不是抖动
写死
转人工率
≥ 3x 基线 且 ≥ 3 次
解决率的实时代理
写死
解决率
下滑 ≥ 10pp
业务波动 ±6pp,5pp 落在噪声带
3σ 校准
样本门槛
窗口 < 200 不判
样本不够,率全是噪声
min_samples

先对齐口径,后面不再重复解释:解决率= 这条会话用户问题有没有被解决的比例(线上抽样 + LLM 判卷 + 用户反馈三路合成,不是现成数字);转人工率= 用户点“转人工”的比例;违规= 护栏漏出的违规输出次数;Token 成本比= 新版单请求成本 ÷ 旧版;P99= 响应延迟的 99 分位,99% 的请求比它快、剩下 1% 是最慢的长尾;样本= 窗口内请求数。

快层(合规/成本/延迟/转人工率):宁可误伤。漏判的代价(合规处罚、账单爆炸)远大于误判的代价(一次自动回滚,10 分钟就能重新放量),所以零样本门槛:成本/P99 一次命中立即熔断,转人工率和违规一样是“基线本身就有残余”的计数型,要累计到阈值(下详)。

违规阈值按档位流量缩放,不是固定 3 次。固定 3 次只对 1% 档成立——到 10% 档,基线正常也有一半以上概率误熔断,放量会卡死在 1% 档。

成本比 ≥ 2x:单请求成本翻倍是 prompt 回退、重试风暴的量级。1.5x 可能是批次波动,2.0x 是确定的事故。P99 ≥ 3x 基线:正常抖动约 ±20%,3 倍是降档或上游饱和。

  • 转人工率 ≥ 3x 基线(且窗口内 ≥ 3 次):转人工是解决率的实时代理——用户点“转人工”是实时点击事件,不像解决率要等会话结束、等判卷、等 200 个样本。基线约 2%(每 50 个会话 1 次转人工),3 倍即 6%,外加 ≥ 3 次卡小样本噪声。开头那场事故,2:18 转人工率就破了 3 倍。(实时的是“信号”,分钟级的是“跳闸”。)

慢层(业务解决率):宁可不误。解决率天然波动(我见过业务基线 ±6pp),误伤导致团队不信熔断。所以双门槛:样本门槛(窗口内请求 < 200 一概不判,样本不够算出来的率全是噪声)+ 3σ 校准(上线前观察旧版一周,先算出它平时自己晃多少,阈值就设到这个晃动之外)。

照抄 5pp?你的业务波动 ±6pp,一周误伤 5 次。

沿用老纪律:阈值是写死的,统计是活的。10pp、转人工率 3x、违规 3 次、成本 2x、P99 3x 是“写死的起点”,样本门槛、3σ 校准、违规阈值按档位缩放,就是“统计是活的”三个旋钮。

第四步:三态熔断状态机,谁先知道、谁先兜住

CLOSED(正常,全量新版)→ OPEN(熔断,全量旧版)→ HALF_OPEN(冷却后小流量试探)。

为什么不用通用熔断器那套多态?熔断对象是“版本”不是“下游依赖”,决策只有“路由新版还是旧版”二选一。Hystrix 那套按调用方隔离、并发试探、失败计数桶,在这里全是多余状态——状态越多,“谁先知道”越慢。

自动回滚是两件事同时做:流量侧把路由切回旧版,配置侧调 rollback API 把灰度占比压到 0。每次跳闸写一条回滚记录,既是复盘证据,也是审计证据。

HALF_OPEN 试探必须是“有限”的:配额(如 5 个试探)+ 通过率(如 80%)双条件。试探失败说明事故没过去,立刻回 OPEN 并升级人工,绝不让试探流自动放大成下一次事故。

还有个容易忽略的约束:冷却期必须 ≥ 违规统计窗口,否则第一个试探,会被窗口里还没过期的违规信号当场打回。

踩坑一:影子全绿,全量翻车

影子跑 3 天全绿,全量上线当天用户投诉暴涨。回放 shadow trace 发现,新版只在“旧版答对了”的流量上被验证过。

旧版答错 → 用户放弃追问 → 这段暗区流量根本没进影子,而新版恰恰在暗区(旧版答错的疑难问题)上全面退化。

修复:影子通过 ≠ 可全量,全量前必须走金丝雀分层放量;暗区用线上“疑难问题池”(旧版转人工的会话)补测。

踩坑二:阈值拍脑袋,熔断器被注释

照抄文档 5pp,上线第一周熔断 5 次。每次回滚后查旧版同窗口指标——旧版也长这样。团队第 6 次把熔断器注释掉,回到人肉盯群。

排查:业务基线解决率本身波动 ±6pp(节假日、促销、晚间高峰),5pp 阈值落在噪声带里,等于让业务周期波动决定熔断。

修复:3σ 校准 + 样本门槛。熔断器被注释一次,团队就再也不信了——重建信任比写阈值贵得多。

最后说两句

这套东西拆开看,每层管一件事:影子验证确认“新版在旧版答对的路上有没有跑偏”,金丝雀决定敢不敢再放一点,熔断决定什么时候收手、收手后怎么确认。

合起来,“上线”从赌一次运气,变成有护栏、能自动回滚的过程——离线评测是快照,灰度+熔断是接住变化的那道闸。

回到开头那场 2:17 的事故:如果转人工率这个快层信号在 2:18 就替我们跳闸,2600 次请求的曝光,一行回滚记录都不会发生。

但还有一个前提问题:灰度/熔断能回滚,是因为你“精确知道该回滚到哪个版本”。目前我们的回滚粒度是“整个服务”——而 LLM 应用的真正逻辑载体是 Prompt。下一篇《Prompt 即代码》,把提示词变成可版本化、可评审、可回滚的资产。否则这套体系,回滚时只能切整个服务,拉不回你真正的逻辑。

我是小兵,一个动手派AI架构师。这里只写自己跑过、摔过、复盘过的AI工程化案例。如果你想持续收到这类实战内容,点击关注,下篇见。


【声明】内容源于网络
0
0
小兵的AI视界
专注 AI 领域:AI前沿资讯/开源精品/实用工具,大模型应用开发/部署推理/微调实践,助你领航 AI。
内容 481
粉丝 0
小兵的AI视界 专注 AI 领域:AI前沿资讯/开源精品/实用工具,大模型应用开发/部署推理/微调实践,助你领航 AI。
总阅读2.6k
粉丝0
内容481