凌晨 3 点处理一个没有报 500 错误的 AI 功能报警
传呼机在凌晨 3:02 响起。你眯起眼睛盯着手机,预料着那些常见故障:数据库故障转移、CDN 边缘节点失联,或者是某个八个月没人碰过的服务出现了 500 报错峰值。然而,警报显示的是:summarizer.eval-on-traffic.helpfulness rolling-1h: 4.21 → 4.05 (Δ -0.16)。没有 HTTP 错误。没有延迟峰值。没有服务宕机。系统在过去一小时内处理的每一个请求都返回了 200,并且响应体解析正常。然而,情况显然比午夜时分变糟了,而值班轮换要求你查明原因。
这种值班任务是标准的运维手册中从未提及的。出故障的东西并没有“坏掉”——它只是退化(regress)了。你多年来追踪的错误预算是以可用性和延迟来衡量的,而触发此次报警的故障模式在两者中都不可见。报警是真实的,客户受到的影响也是真实的,而你通常的诊断循环——检查部署日志、检查依赖图、查找错误的发布版本、执行回滚——在你意识到那个“错误的发布”可能只是昨天下午 4 点上线的一个 30 行系统提示词(system-prompt)的修改时,便碰了壁。在代码审查中,那次修改看起来完全无害。
当一半的故障模式都不会触发现有警报时,值班的形式就发生了变化。解决这个问题的团队会在 SRE 能力之外培养出第二种能力——评测驱动的事件响应(eval-driven incident response)。而那些没能做到的团队,则只能在两周后通过 Twitter 上的吐槽或客户流失报告才发现质量下降。从业者目前的报告显示,从隐性质量退化开始到第一个升级为投诉的用户反馈之间,存在 14 到 18 天的滞后。这不只是报警系统的问题,而是缺少了一类报警。
为什么在没有 500 报错的情况下触发了报警
传统的报警系统监控的是 AI 功能错误表面的错误半部分。一个由大语言模型(LLM)驱动的接口可以返回 HTTP 200 以及结构有效的响应,但其内容仍然可能是错误的、语气不当的、无根据的(ungrounded)、拒绝了不该拒绝的请求、答应了不该答应的要求、引用了不存在的来源,或者以极高的自信产生幻觉(hallucinating)。这些故障模式都不会出现在 p95 延迟或错误率中。它们体现在用户行为上——重试、编辑、放弃会话、点踩(thumbs-down),以及针对实际生产流量运行的评测信号中。
这第二类信号——流量评测(eval-on-traffic)——正是触发你传呼机的原因。系统会对实时请求的一个采样子集持续由裁判模型(judge model)或确定性检查器进行评分,滚动分数被视为一级指标,该分数的退化会像 CPU 飙升一样触发升级流程。这种机制现在已经足够成熟,大多数 LLM 观测平台都默认支持这种模式。而将该分数与 SLO(例如:“在 24 小时窗口内,99% 的总结响应在‘有用性’上的得分必须 ≥ 4.0”)挂钩,正是将基于感觉的“今天模型感觉变差了”转化为具有消耗率(burn rate)的报警条件的逻辑所在。
关键属性在于这一信号具有领先性。当质量下降时,点踩、重试率和会话放弃率最终都会发生变化,但那往往是几天后的事了,因为需要有足够多的用户遇到退化并费力表达不满。到那时,你的流失用户群已经形成了。而流量评测在几分钟内就会发生波动,因为裁判模型运行在用户刚刚看到的同一批流量上。
新的诊断循环
针对“服务宕机”的运维手册已有数十年的历史,且已形成条件反射。而针对“服务隐性退化”的运维手册则完全不同,大多数在生产环境中发布 AI 功能的值班团队仍处于摸索阶段。从一开始,诊断问题的方式就不同了。
第一个问题不再只是对照部署图询问“过去 24 小时内变更了什么”。问题依旧,但覆盖范围扩大了两倍:
- 是否上线了模型迁移? 模型厂商的版本升级是最常见的隐性退化诱因——
claude-X.Y → X.Z看起来只是版本号的变动,但其行为表现却像是逻辑上的差异。正是由于这个原因,许多团队会锁定模型 ID,并将迁移操作置于评测套件的门控之下。 - 是否合并了提示词变更? 从任何实质性的定义来看,系统提示词和少样本示例(few-shot examples)都是代码,但它们通常通过与服务代码不同的路径发布,有时发布者甚 至不在值班序列中。值班人员必须知道去检查提示词仓库,而不仅仅是服务仓库。
- 工具、检索器(retriever)或知识源是否发生了变化? 索引重建、向量模型(embedding model)更换以及分块(chunking)策略调整,在下游都会表现为质量退化,而在上游看起来却只是基础设施工作。
- 裁判模型本身是否发生了漂移? 这是最棘手的一种。裁判提示词也是提示词;裁判模型也可能迁移;裁判模型的校准集可能会过时。有时“退化”最后被证明是裁判模型在略有不同的标准上重新设定了基准。每月针对裁判模型运行校准集的团队能发现这一点;而不这样做的团队每个季度都要追逐两三次“幽灵退化”。
- 输入分布是否发生了偏移? 营销活动、合作伙伴集成或局部地区的推行,都可能在不改变任何代码的情况下改变请求的形式。模型并没有变差,它只是在处理更多它原本就处于弱势的分布部分。
这个循环的产出是一个假设,而不是一个修复方案。修复通常包括以下三点之一:回滚提示词或模型版本锁定、缩小推送范围,或者接受退化并针对评测套件提交一个 Issue——这个评测套件本应在功能上线前就捕捉到这种退化。对于习惯了“回滚并进行无责复盘(blameless-postmortem)”的工程师来说,第三种做法可能感觉不够痛快,但它确实是正确的——对于软性退化,大多数“修复”其实是评测指标的改进,而非代码补丁。
