跳到主要内容

没有根本原因的事后分析

· 阅读需 10 分钟
Tian Pan
Software Engineer

事故排查会议(incident bridge)安静得有些异样,这意味着大家都卡住了。一份支持工单显示,智能体(agent)告诉客户其退款已获批准,而事实并非如此。你有完整的追踪记录:提示词(prompt)、检索到的账户记录、工具调用、模型的推理过程以及最终的消息。你重放了一遍,智能体的操作是正确的。你又重放了一遍,依然正确。十次中有九次,产生该事故的追踪记录反而生成了正确的结果。会议上终于有人提出了那个复盘模板(retro template)无法处理的问题:那么,根本原因是什么?

根本没有。至少不是模板所指的那种。五个为什么(five-whys)的链条是这样运作的:“智能体告诉了客户错误的信息” → “因为模型生成了批准” → “因为它采样了一个断言批准的 Token 序列” → “因为……这是概率分布所允许的。”最后一个“为什么”最终以耸耸肩告终。“模型采样了一个错误的 Token”在技术上是正确的,但在操作上毫无用处。它没有指明修复方案,没有分配负责人,也没有弥补差距。你可以把它写进报告,但每个读到它的人都知道,你记录的是一个巧合,而不是一个原因。

这不是换了新装的老问题。事故审查一直以来都在与复杂系统作斗争 —— Richard Cook 在几十年前的《复杂系统如何失效》(How Complex Systems Fail)中就指出,明显的失败需要多重故障,事故并没有孤立的原因,只有促成因素。LLM 系统所做的,是让这个本就摇摇欲坠的假设彻底破裂。当同样的输入在不同的运行中产生成功和失败时,根本原因分析(root-cause analysis)所追溯的确定性因果链根本就不存在。复盘模板假设了系统并不具备的确定性。

复盘模板本身就是 Bug

大多数事故处理流程都继承自制造业和航空业,在这些领域,缺陷就是缺陷:零件不符合规格,螺栓扭矩不对,一旦你修复了那个特定的问题,故障模式就关闭了。“五个为什么”方法直接编码了这一假设。它遵循单一的因果链条,刻意向底部一个可修复的问题收窄。当确实存在一个可修复的问题时,这种方法运作得非常出色。

LLM 故障不具备那样的结构。伤害你的输出是从分布中抽取的,在给定上游一切因素的情况下 —— 提示词措辞、检索到的上下文、工具结果排序、系统指令、采样温度 —— 分布给错误输出分配了非零概率。这些因素中没有一个是单独“导致”失败的。它们共同设定了一个概率,而采样器掷了骰子。询问“为什么失败”就像在问为什么某次硬币投掷结果是反面。诚实的答案是“因为 P(反面) 大于零”,这个答案既正确又毫无价值。

迹象表明你是在与模板作斗争,而不是在处理事故:你的报告中有一个根本原因字段,必须有人来填写,而唯一真实可写的却是关于采样的一句话,且无法推导出任何行动项。当你表单必填项的诚实答案是一个“非答案”时,错的是表单,而不是事故。

从“为什么”到“如何”,从原因到概率

逃生舱口有两个动作,这两个动作在事故处理实践中都不是新鲜事 —— 只是它们以前从未承担过重任。

首先是停止问为什么(why),开始问如何(how)。John Allspaw 的“无限如何”(Infinite Hows)重构理念源于无责事后分析(blameless-postmortem)文化,它询问的是事故发生必须具备哪些条件,而不是指责哪一个单一故障。应用到随机系统(stochastic system)中,这可以清晰地映射:与其问“为什么模型批准了退款”,不如问“系统是如何进入‘批准退款是一个合理的下一个 Token’的状态的?”这个问题有真实的答案。检索到的记录在退款状态上模糊不清。提示词从未明确说明智能体缺乏批准权限。检查资格的工具在检查授权的工具之前返回了结果,所以模型看到了“符合资格”而没看到“尚未授权”。每一个都是你可以实际改变的促成因素,而且没有一个要求模型必须是确定性的。

第二个动作是停止将事故视为单一事件,开始将其视为一种概率(rate)。你正在审查的失败是从分布中提取的一个样本,因此诚实的分析单位是 P(失败),而不是“这次失败”。这重构了整个报告。你不再是解释一个错误的输出,而是解释为什么错误输出的概率高到足以在生产环境中触发,以及你做了什么改变来降低它。一份写着“我们将‘符合资格但状态模糊’切片上的 P(幻觉批准) 从估计的 4% 降低到了 0.3%”的报告是诚实的、可操作的、可验证的。而一份写着“我们修复了 Bug”的报告则是对一个在经典意义上没有 Bug —— 只有概率 —— 的系统的谎言。

以概率复现,而非彻底复现

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates