跳到主要内容

3% 的回归不会让报警器响起:应对统计性故障的轮值工作

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的轮值制度(on-call rotation)最初是为了捕获一种特定类型的故障,但绝非那种真正会让你的 AI 产品崩溃的故障。它监控的是停止响应的服务、飙升的延迟曲线、超过 1% 的错误率。这些都是阶跃函数(step functions):原本运行正常的东西突然失效了,这种不连续性足以在凌晨 3 点叫醒一名工程师。整个体系——阈值、运维手册(runbooks)、升级策略——都假设故障会自我宣告。

对于一个包含模型在环(model in the loop)的系统,真正关键的失效模式恰恰相反。上周二,你的提取流水线准确率为 94%。这周二,它变成了 91%。没有服务崩溃。每个请求都返回了 200。延迟平稳。输出依然是格式良好的 JSON。但你 3% 的用户现在得到了微妙的错误答案,而且他们不会提交 Bug,因为答案看起来是正确的。由于没有触发条件,寻呼机(pager)保持沉默。等到有人注意到时——通常是愤怒的客户,通常是在几周后——这种回归(regression)在整个过程中一直在静默地累积恶化。

这是没人放入轮值阶梯的空白区。我们聘请 SRE 是为了维护确定性系统(deterministic systems),然后我们在其之上部署了概率性系统(probabilistic systems),并假设同样的监控方式可以平移。事实并非如此。从结构上看,统计型失效对确定性告警是不可见的,填补这一空白需要重新定义“故障(incident)”的含义。

为什么你现有的告警对此视而不见

确定性告警之所以有效,是因为确定性系统有正确和错误之分。500 错误是错的。空指针是错的。当 SLO 为 200ms 而请求耗时 30 秒时,那是错的。你在可接受与不可接受的边界设置一个阈值,指标要么越界,要么不越界。信号就是那个越界的瞬间。

模型质量没有这样的边界。你无法指出任何一个单一的响应并说“这就是 Bug”。准确率为 91% 的模型会产生单独看起来合理的输出;失效只存在于聚合中,表现为分布的偏移。你不能写 if accuracy < 0.92 then page,因为你通常无法实时获得准确率——能够告诉你答案是否正确的真值标签(ground-truth label)要在几天后才会送达,如果它真的会送达的话。当人类下周审查输出时,或者用户下个月流失时,或者永远没有反馈时,让你计算准确率的信息要么延迟,要么干脆缺失。

因此,你只能监控两样可以立即获得的东西——输入的输入和输出的输出——并尝试从它们的形态中推断质量。这是一种根本不同的学科。你不是在断言正确性;你是在检测变化。而变化是一个统计学主张,这意味着单一数据点说明不了任何问题。一个怪异的输出是噪声。一千个分布发生漂移的输出则是信号。你的告警必须针对分布(distributions)而非事件(events)运行。

更糟糕的是,原因往往完全在你的代码之外。你的供应商在同一个端点后面静默更新了模型权重。你锁定的版本被弃用了,你被强制升级了。因为市场部门在新的地区启动,用户构成发生了变化。这些都不会出现在 diff、部署日志或堆栈跟踪中。发生变化的系统并不受你控制,唯一的证据是你没有绘图的曲线发生了缓慢的偏转。

你真正可以观察的两种分布

由于真值具有延迟性,你需要利用实时到达的两种信号构建早期预警系统:输入内容的分布和输出内容的分布。

输入漂移(Input drift) 考察的是今天进入模型的数据是否与验证模型时的数据一致。如果你的分类器是针对英文支持票据调优的,而突然间出现了 20% 的西班牙语,模型本身并没有退化——但其有效准确率退化了,因为它现在是在分布外(off-distribution)运行。这里的标准工具是人口稳定性指数(Population Stability Index, PSI),它将特征的分布分桶,并对比今天与参考窗口的差异。常规解读是:低于 0.1 为稳定,0.1 到 0.25 值得关注,高于 0.25 意味着人群偏移足以产生负面影响。对于连续特征,Kolmogorov-Smirnov 检验可以通过 p 值回答同样的问题;对于分类特征,可以使用卡方检验(chi-square)。这些都不需要标签。它们只需要你保存了一个基准(baseline)。

输出漂移(Output drift) 考察的是模型响应的形态是否发生了变化,无论输入是否改变。这是捕获供应商静默更新的关键。如果昨天你 8% 的输出是拒绝回答,而今天变成了 15%,那么肯定有什么东西变了——也许是供应商收紧了安全过滤器,也许是你的提示词与新模型版本产生了不良互动。你不需要知道原因,就能知道分布发生了偏移。对于自由文本输出,现代的方法是将响应嵌入(embed)并观察嵌入向量的分布,因为 LLM 的漂移通常发生在语义空间,而不是表面的 token 计数。一个巧妙且低成本的变体:将模型的第一个 token 的对数概率(log-probabilities)视为样本,并运行双样本置换检验(two-sample permutation test),这能以对每个输出评分的一小部分成本捕获分布偏移。

核心的观念转变是:这两者都是先行指标(leading indicators),而非定论。漂移是线索,而不是失效的证明——数据可能会移动,而性能保持完全稳定。如果你把每一次 PSI 的波动都当作故障处理,你会让自己陷入告警疲劳。这套方法的纪律在于:利用漂移来决定看哪里,然后在宣布回归之前,用更接近真值的数据进行确认。

构建确认层:代理指标与采样评估

漂移(Drift)告诉你天气变了,但它不会告诉你庄稼是否已经枯萎。要从“某些东西发生了偏移”过渡到“质量下降”,你需要能够持续计算的、更廉价的正确性代理指标 (proxies)

最实用的做法是建立一个采样评估循环 (sampled eval loop)。你无法让真人对每一个输出都进行打分,但你可以抽取一小部分样本(例如 1%)并对其进行评分——可以是由另一个裁判模型 (judge model) 根据评分细则 (rubric) 执行,或者对于最高风险的部分,由人工审阅者执行。这为你提供了一个虽有噪声但无偏的质量估计,它每天都会更新,而不是等到标签(labels)到货时才更新。采样规模足够小,以至于成本可以承受;又足够大,使得一个真实的 3% 回归在统计上是一眼可见的,且只需一两天,而不是一个季度。

在此之上,再增加一层护栏代理指标 (guardrail proxies)。这些指标与质量相关,且计算成本几乎为零:Schema 验证通过率、拒绝率、输出长度分布、违反业务规则检查的响应比例、智能体的工具调用成功率。这些都不等同于质量,但每一个都是廉价的“金丝雀”。畸形 JSON 的突然增加或平均响应长度的缓慢增长,这类信号往往预示着质量下降,且能即时显现。将它们视为烟雾报警器,引导你前往采样评估环节进行确认。

由此产生的是一种漏斗式架构。顶层是廉价、即时、有噪声的信号(漂移、护栏代理指标),它们频繁触发并引导注意力。中间层是更昂贵、更慢、更可靠的信号(采样评估),用于确认或排除异常。底层是真实的基准真相(ground truth),虽然到达较晚,但它锚定了整个系统,确保你的代理指标不会悄悄失准。每一层的存在都是为了决定是否值得调用下一层更昂贵的机制。

切分一切,因为聚合指标会撒谎

这就是让统计回归(statistical regressions)如此危险的陷阱:整体准确率下降 3%,在某个特定客群中可能就是 30% 的崩塌,而由于其他客群保持稳定,这一现象被完全掩盖了。你的核心指标看起来就像是一个舍入误差,但在移动设备上的西班牙语用户眼中,产品已经坏掉了。

聚合监控在结构上对此是盲目的。唯一的防御手段是按切片 (per slice) 计算你的指标——按语言环境、设备、客户层级、输入渠道、模型版本、租户——并针对切片而非全局数字进行告警。基于切片的监控能够定位漂移,并暴露出隐藏在子群体内部的回归。代价是,你现在拥有数十甚至数百个指标序列,对所有序列进行朴素的阈值设置(naive thresholding)会让你淹没在来自细小、嘈杂片段的误报中。

这正是统计告警 (statistical alerting) 优于静态阈值的价值所在。你不再使用固定界限,而是在某个切片的指标显著偏离其自身历史行为时发出警告——例如针对该切片滚动基线的 z-score,或是一个累积微小持续偏差直至不可忽视的 CUSUM 图。CUSUM 在这里尤其适用:它专门用于捕捉阈值容易漏掉的微小、持续的偏移,因为它累积的是一段时间内的漂移,而不是等待单个点跨越边界。一个持续一周的 3% 回归对阈值来说是隐形的,但在 CUSUM 图上会发出刺眼的尖叫。

统计告警还具有适应性。AI 产品的正常行为并不是平稳的(not stationary)——你的流量组合在变,你的提示词在进化,你的用户群在增长。1 月份设置的静态阈值到 3 月份就是错的。自适应基线会持续重新学习什么是“正常”,因此它针对的是真正的偏差,而不是系统缓慢的合理演变。大多数团队最终采用的是混合方案:保留粗略的阈值作为处理明显、严重故障的第一道防线,并在上方叠加统计性的分切片检测,以捕捉微妙的故障。

统计失效时的 On-Call 到底是什么样的

在操作层面上,这改变了工作的形态。确定性的事故是二元的——要么正在发生,要么已解决——运维手册 (runbook) 是恢复服务的一系列步骤。而统计性事故是一个假设:“X 片段的质量可能从 T 时间开始下降了。”On-call 工程师的第一项工作不是修复,而是确认它是真实的,因为漂移标志只是线索,其中很大一部分将是虚警。

因此,运维手册的顺序发生了反转。它始于对信号本身的初步评估 (triage):这是真实的分布偏移,还是小切片中的采样噪声?然后是定位:哪个功能、哪个群体、哪个时间窗口?接着是与外部事件的关联:服务商版本变了吗?我们发布了提示词修改吗?流量构成变了吗?最后才是缓解措施:回滚提示词、固定之前的模型版本、将受影响的切片路由到备用方案,或者启动重新训练。这里运用的技能更接近数据分析而非救火,参与轮值的人需要习惯于根据分布进行推理,而不仅仅是查看仪表盘上的红点。

文化上的转变是最难的部分。受过确定性系统训练的工程师想要一个表示“正确”的绿色勾选标记。统计系统的可观测性无法给你这个——它只能向你展示变化,并帮助你判断这种变化是否糟糕。你正在用清晰的“通过/失败”的舒适感,去交换持续的概率判断带来的不适感。完成这一转型的团队不再问“模型对不对?”,而是开始问“模型的质量是否在悄悄为某些人变差,而我能否在他们发现之前发现?”

这个问题是由于你目前的传呼机 (pager) 无法回答的。构建那个能够回答它的层——用漂移检测引导注意力,用采样评估和护栏代理指标进行确认,用分切片的统计告警捕捉隐藏在聚合指标下的回归——这样,3% 的下降就不再是你三周后从愤怒的客户那里才发现的失败。它会变成你在周二下午捕捉到的问题,而且在被发现时,它仍然只是 3%。

References:Let's stay in touch and Follow me for more thoughts and updates