模型服务灰度回滚与 bad case 快速止血落地

日期:2026-08-20

一、项目背景

我们给客户做模型服务发布,新版本推理服务评测都过了,信心满满放百分之五灰度。结果线上冒出一批格式错乱的坏回答,json 字段丢了,前端解析直接崩。用户投诉上来我们才发现,因为监控只看吞吐和延迟,没人盯输出质量。回滚要靠重新发版,二十分钟起步,那段时间坏回答一直往外吐,运维和算法互相甩锅,一个说你模型有问题,一个说你发版流程有问题。

根子在于,模型服务的坏不像传统服务那样报错,它是静默地输出错的、格式乱的东西,监控盲区大。我们进场时,他们刚经历一次因为回滚慢导致的客诉高峰,品牌方在群里追着问。说到底,模型灰度必须能秒级止血,不能等发版。

二、落地场景

方案围绕快速止血搭。版本灰度发布:新版本只接小部分流量,按比例放大。实时 bad case 捕获:监控输出格式、长度异常、关键词黑名单,命中即告警。一键回滚:发现坏版本,路由切回稳定版,不必重新发版。回滚后流量归位:确认稳了再把灰度流量调回正常分布。根因复盘:回滚后自动抓取坏样本,喂给算法做修复。

三、关键技术挑战与解决思路

回滚零停机是核心。我们最早回滚要冷启动新实例,切换时用户感知到卡顿甚至报错,谈不上无感。后来改成双版本常驻,稳定版一直在线,灰度版挂旁边,回滚只是切路由不切进程,毫秒级完成。这一步把回滚影响从二十分钟抖动变成用户无感。

bad case 捕获不能只靠人工看。我们建了输出校验层,对每一条响应做格式 schema 校验和异常长度检测,再叠加业务关键词黑名单,比如出现乱码标记或异常标签就告警。初期误报多,正常长回答也被标,我们加了长度和比例阈值,误报降下来。我们早期那版告警太敏感,运维被假警折腾烦了就忽略真警,后来调了置信度才不狼来了。

灰度放大策略也得稳。不能一上来放太多,我们按一到五到二十到五十逐步放,每档观察十分钟输出质量再进下一档。这样即便出问题,影响面也小,回滚代价低。

回滚之后的验证也不能省。切回稳定版不代表坏版本的问题没了,我们加了一个影子回放,把坏版本期间的真实流量在稳定版上重跑一遍,确认输出正常才彻底关掉灰度。这步帮我们避免过假回滚,表面切回去了,其实下游某个适配还指向坏版本。另外坏样本要回流,每次 bad case 触发回滚,我们把这批样本自动归集进回归测试集,算法下次发版先过这关,同类问题不再犯。说实话,回滚只是止血,根因在算法那边,我们和算法团队约定了坏样本必须进他们的修复闭环,不然回滚救得了一时救不了一世,这套协作机制比工具本身更关键。

灰度期间我们加了稳定版和灰度版的指标对照。同样流量下,两版的延迟、格式错误率、坏回答率并排看,一旦灰度版某个指标明显劣于稳定版就自动告警,不必等用户投诉。之前只看全局,灰度那点流量湮没在整体里,劣化发现得晚。对照看板上线后,有次新版本的坏回答率比稳定版高零点几个点,远低于人工察觉阈值,但对照看板当场标红,我们在影响扩大前就切了回滚。这种同屏对比比单看绝对值灵敏得多。

四、效果数据

bad case 从发现到止血,从原来的二十多分钟压到约三十秒,因为切路由而非发版。回滚成功率百分之百,再没出现回滚过程中二次故障。坏回答影响面从灰度全量缩小到最多百分之五,且多在低档灰度期就被掐。回滚后根因定位时效从一天缩到两小时。文中数据为项目复盘口径,已做脱敏。

五、可复用经验总结

模型服务灰度必须能秒级止血,坏回答识别加一键回滚比重新发版快几十倍,这是保命的。回滚要做成切路由不切进程,双版本常驻,别冷启动新实例,我们第一版冷启动那套用户感知明显。bad case 捕获别太敏感,误报多了真警也被埋,调置信度比加规则重要。说实话,灰度档位我们也是踩过才定下阶梯式,一上来放二十的话,出问题就是二十的锅。输出校验层值得常驻,不只灰度期用,稳定版偶尔也会因为上游数据脏而抽风,这层是长期的眼。

案例片段(已脱敏): 灰度路由与一键回滚节选(配置节选): 某次 v2.4 灰度到百分之五,守卫捕获到一批响应缺失必填字段,三十秒内路由切回 v2.3,用户无感。事后复盘,是 v2.4 对新提示词的长度裁剪过激,把结构截断,算法据此修复后重新灰度,本次坏回答影响面控制在约三百次调用内。

versions:
  stable: v2.3
  canary: v2.4
route:
  canary_ratio: 0.05
  rollback: switch_route_only
badcase_guard:
  schema_check: true
  anomaly_len: {min: 5, max: 8000}
  keyword_blacklist: [乱码标记, 异常标签]
steps: [0.01, 0.05, 0.2, 0.5]

案例片段(已脱敏): 一次守卫误报,把正常的长回答标成异常,运维点回滚,稳定版流量瞬间翻倍导致短暂排队。我们复盘发现是 max 长度阈值设太低,长回答被误伤。调高阈值并加比例告警,异常占比超千分之五才触发回滚,后误报归零。这让我们明白,自动回滚的扳机得稳,宁可慢半分钟也别误伤正常流量。