当 AI 功能表现异常时,大多数工程师做的第一件事就是再次点击“运行(run)”。这种思路认为,模型是具有随机性的,所以这次运行可能只是运气不好。当第二次尝试产生看起来合理的结果时,工单就被关闭了。团队继续前进。而真正的 Bug——过期的工具响应、检索缺失、仅在包含特定 token 的输入时才触发的系统提示词冲突——仍然完好无损地留在生产环境中,等待下一个用户触发它。
这就是“重跑反模式(rerun antipattern)”,它是 AI 团队从聊天机器人时代继承下来的最昂贵的调试习惯。它看起来很严谨,因为模型确实是非确定性的。它看起来像是一种方差探测。但几乎没有人在重新运行之前写下假设,没有人预先决定多少次运行才算证据,也没有人考虑 token 的成本。正在发生的事情更接近于“老虎机式调试”:你不断拉动杠杆,直到红灯停止闪烁,然后你走开,并确信机器没问题。
重跑看起来像方差,但表现得像幸存者偏差
这种物理动作确实存在一个合理的版本。一个深思熟虑的 N-of-K 样本——比如在 temperature 为 0.3 的情况下运行 10 次,并带有一个书面假设,如“我预计引用步骤在合约 30% 的案例中会失败”——是一种真正的诊断技术。它测试故障模式是罕见的还是常规的,并给你一个分母。研究人员已将其正式化为“pass@k”,并表明重采样中的方差缩减是任何诚实的 LLM 评估的承重原语。《The Good, the Bad, and the Greedy》这篇论文现在已成为一个标准参考,解释了为什么在评估中忽略非确定性会产生误导性的排名。
而“绝望式重跑”从外部看完全一样,但它没有假设,没有记录 K 值,也没有决定什么才算成功的规则。它在结构上是一个幸存者偏差机器。在 10 次无声的重跑中,工程师只记住了成功的运行,最终没有发布任何修复,也没有学到任何东西。那些仅在特定形状的输入(长上下文、特定的工具输出、用户查询中的特殊标点符号)上出现的故障模式,正是重跑无法揭示的,因为循环中没有任何环节在刻意改变输入。
一个有用的测试:如果你不能回答“什么能让我相信这个 Bug 是真实的而不是抖动,以及我需要多少次运行才能确定”,那么你不是在进行方差探测。你是在拉动老虎机的杠杆。
为什么重跑掩盖了真实的 Bug
模型确实是非确定性的,而这正是该反模式躲藏的挡箭牌。但非确定性的空间比大多数工程师想象的要小得多,而它所掩盖的 Bug 通常根本不是随机的。
即使在 temperature 为 0 的情况下,相同的输入也不能保证相同的输出。GPU 归约(reductions)中的浮点数非结合性、改变内核调度的动态批处理大小、决策取决于批处理中其他序列的混合专家(MoE)路由——这些都会将熵泄漏到“确定性”推理中。Thinking Machines 最近的研究将问题专门追溯到了批处理不变性,而 Eval4NLP 2025 关于托管模型确定性的论文则量化了在所谓相同配置的运行中,准确率波动可高达 15 个百分点。所以,是的,模型确实可以为相同的输入返回不同的 token。
但这只是噪声底噪。它不是导致功能失效的原因。重跑反模式最能可靠掩盖的是那些“确定性但有条件”的 Bug:由于缓存 TTL 错误而返回过期数据的工具、在特定日期范围内有漏洞的检索索引、指令在狭窄的用户意图类别上相互矛盾的系统提示词、仅在链条深度超过三步时才将小的上游错误复合为大的下游错误的智能体循环。每当输入匹配触发条件时,这些都会失败;而每当输入不匹配时,它们都会通过。重跑不会改变输入。因此,重跑无法区分这两种情况。它只能告诉你,模型有时会走上一条不触发 Bug 的路径,而这正是用户在提交工单时就已经知道的信息。
那些拥有最强后端调试直觉的工程师往往最容易掉入这个陷阱,因为来自确定性系统的肌肉记忆——“如果它不稳定,就反复运行直到它稳定,然后查看 diff”——在底座是非确定性但 Bug 本身不是随机的情况下,会产生完全错误的行为。
先追踪,再复现
相反的立场是将单次失败的运行视为一个完全可分析的产物(artifact)。在决定 Bug 是否值得复现之前,先捕获一次端到端的追踪(trace),包括每一个提示词、每一个工具调用、每一个检索结果和每一个中间状态。这是快速调试 AI 系统的团队与那些乱撞的团队之间的分水岭。
追踪能让你回答重跑无法回答的问题。模型是否看到了错误的上下文?工具输入是否以某种智能体默默吸收的方式畸形了?检索调用是返回了零个文档,还是错误的文档?一个工具调用是否因为第一次响应未通过 schema 验证而重试了五次,从而在过程中烧掉了 token 并破坏了对话历史?你无法仅从输出文本中回答这些问题。但你可以从结构化追踪中找到所有答案。
现在的工具已经非常标准。Langfuse、LangSmith、Opik、Pydantic Logfire 等都趋向于同一种模型:一个 Trace 是整个用户交互,一个 Span 是其中的一个工作单元(LLM 调用、工具调用、检索),可视化界面会向你精确展示时间、token 和逻辑控制流的去向。LangGraph 的 Time Travel 功能更进一步,通过在每个超步(super-step)边界检查点记录图状态,你不仅可以检查失败的运行,还可以从任何先前的状态 fork 出来,修改输入,并从该点开始确定性地重新执行。这才是真正的复现:相同的输入、相同的工具响应、相同的检索,以及对你正在测试的一个变量进行受控变量实验。从头开始重新运行相同的提示词并祈祷奇迹出现,这不叫复现。
这种纪律也比人们预想的更廉价。如果你对任何报告的故障采取的第一行动是“提取 trace ID 并阅读它”,第二行动是“如果 Bug 在输入完全相同的检查点重复出现,它就是一个真正的 Bug,而不是抖动”,你关闭工单的速度会比重跑派快得多,而且你是通过修复 Bug 而不是靠巧合来关闭它们的。
没人预料到的 Token 账单 AI 团队几乎总是太晚才发现还有一个财务维度。每一次“绝望式重跑”都是一个计费事件。原始的 Agent 循环会以大约 O(N²) 的速度增加 Token 成本,因为每一步都会对整个对话历史重新计费,所以一个 20 步的 Agent 重运行成本并不是单步价格的 20 倍 —— 而是要高出一个数量级。如果再乘以一个工程师在调查期间每天重跑 10 次,乘以几个工程师,再乘以事故持续的时间,你就会得到一笔出现在任何电子表格之外的调试预算。
成本归因问题是二阶陷阱。大多数团队会对生产环境的用户流量使用 user_id 和 feature_name 标签来统计 Token。但几乎没有人会为调试会话统计 Token,这意味着在季度末出现的毛利率变动是不透明的。财务部门会问“发生了什么变化?”,工程部门会说“生产环境没有任何变化”,双方都是正确的,因为变化在于工程团队自身的调试行为,而这从未被标记。
解决方法并不高大上:为每次交互式运行标记一个可以追溯到人的 session_id,并将调试 Token 作为一个正式的账目项。一旦团队能够看到“这次事故在重跑 Token 上花费了 $4k,而最终的修复只是一个单行的缓存 TTL 更改”,关于重跑纪律的文化讨论就会自然发生改变。成本数据完成了原则无法实现的劝说工作。
构建一个不依赖重跑的运行手册 如今大多数 AI 运行手册 (Runbook) 中并没有明确写下“重跑”这一步。当运行手册用尽时,工程师就会伸手去点重跑,这表明运行手册太短了,而不是说重跑是正确的下一步。
一个能抵御这种诱惑的运行手册需要具备典型事故手册所缺少的三个要素。首先,Trace 优先的分诊步骤:在采取任何其他行动之前,找到失败交互的 Trace ID 并加载它。其次,复现纪律:从检查点 (Checkpoint) 使用原始输入回放 Trace,以确认 Bug 可以复现,然后才开始有系统地改变输入以定位问题。第三,在确实需要时,为变差探测 (Variance Probes) 提供明确的预算 —— “如果 Bug 无法从检查点确定性地复现,请使用相同输入运行 N=20 次,并在更改任何内容之前记录观察到的失败率。”
最后一步是将“绝望式重跑”转变为合法诊断的关键。它是相同的物理动作 —— 重复运行 Prompt —— 但带有假设、分母、记录在案的停止条件以及记录结果的地方。写下“运行了 20 次,观察到 3/20 的失败,且全部发生在用户消息包含表情符号的输入中”的工程师是在进行变差调试。而连点 6 次“运行”直到其中一次看起来正常为止的工程师,什么也没做。
当纪律落实时会发生什么变化 采用 Trace 优先调试的团队报告了两个在单次事故的杂音中很容易被忽略的变化。他们的平均根因分析时间下降了,但更重要的是,根因分析时间的方差下降得更多。长尾事件 —— 即那些有人重跑了两天后才意识到问题是过时的 Embedding 的事件 —— 消失了。那些结果证明是巧合、三周后又以不同形式出现的“隐性修复”也消失了。
另一个变化是文化上的。工程师们不再使用诸如“它通常能工作”和“可能只是不稳定”之类的模棱两可的语言来描述 AI Bug,因为 Trace 要么显示确定性的失败,要么不显示。一旦你拥有了一个事实,你就拥有了一个事实,而事实比直觉更容易辩论。AI 团队的 Bug 报告开始读起来像后端 Bug 报告,堆栈跟踪被 Trace ID 取代,其他工程部门也能跟上思路。
这个原则可以简化为一句话,值得贴在每位 AI 工程师的桌子上方:一次失败的运行是一个完全可分析的人造产物,而不是一个可以重新投掷的骰子。按照这种方式对待它,反模式就会自然消亡。
会员专享
余下内容仅对会员开放。 会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
— 完整文章,包含未公开存档的部分 — 可落地的工作框架,附带权衡与决策依据 — 新文章抢先看,先于公开发布 登录以继续阅读→ 随时取消 · 一次订阅,畅读全部