线上失败怎么变成 Failure Corpus?从一次事故到持续回归

Failure Corpus 不是错误日志堆积,而是把真实失败结构化成可复现、可归因、可回归的质量资产。本文给出 Failure → Root Cause → Regression Case 的完整闭环。

发布 ·更新 ·约 9 分钟 ·hugfeature

AI Eval 系列 #08
上一篇:Offline Eval 和 Online Eval 有什么区别?

很多 AI 系统上线之后,失败其实不少。

但几个月后回头看,会发现真正留下来的只有日志、截图、一张 Bug 单,或者一句“这个问题之前好像修过”。

这不叫质量资产。

真正有价值的做法是把失败沉淀成 Failure Corpus:一套可以被检索、复现、归因、重放和持续回归的真实失败集合。

一、Failure Corpus 和 Bug List 不一样

Bug List 更关注:发生了什么问题、谁来修、现在状态是什么。

Failure Corpus 更关注:

  • 在什么输入和环境下失败;
  • 系统实际执行了什么;
  • 失败属于哪一类;
  • 应该怎样独立验证;
  • 修复后如何保证不再出现。

所以它的最终目的不是“记录问题”,而是:

让同类失败以后可以自动被挡住。

二、一条 Failure 至少要保留什么

最小结构可以包含:

failure_id: F-2026-017
task_type: test-case-generation
severity: high

input:
  prd: ...

environment:
  model: ...
  prompt_version: ...
  harness_version: ...

actual:
  output: ...
  trace_id: ...

expected:
  must_cover:
    - approval_threshold

failure:
  type: missing_constraint
  evidence: ...

root_cause:
  layer: context

regression:
  case_id: REG-017

这里最关键的是三件事:输入、证据、失败类型。

没有这三件,后面很难复现。

三、第一步不是分类,而是保证可复现

线上失败发生以后,先问:

同样的输入还能不能重现?

如果模型具有随机性,就多跑几次。

例如 5 次执行里 3 次失败,这已经告诉你:这是概率性失败,而不是一次偶然截图。

同时要记录 Model Version、Prompt Version、Tool Version、Context、Business Rule Version、Harness Version 和环境状态。

否则修复前后无法公平比较。

四、第二步:区分 Symptom 和 Root Cause

例如症状是:

生成的测试用例遗漏审批阈值。

但根因可能是:

  • PRD 没被完整加载;
  • Context 被截断;
  • 模型理解失败;
  • Prompt 没要求覆盖;
  • Judge 没发现遗漏。

如果只把 Failure Type 写成 missing test case,价值有限。

更好的方式是至少区分层级:

Input
Context
Model Decision
Tool
State
Harness
Grader
Environment

这样后面才能知道应该修哪一层。

五、Failure Taxonomy 不要一开始设计得太复杂

第一版建议从 5~10 类开始,例如:

instruction_violation
missing_constraint
wrong_tool
wrong_argument
state_desync
unsupported_claim
side_effect_violation
loop_or_retry
missing_evidence
grader_error

遇到新失败再扩。

分类体系应该来自真实失败,而不是先设计一个看起来完整的分类树。

六、第三步:把 Failure 变成 Regression Case

不是所有线上失败都值得进入回归集。

我会优先收:

  • Critical / High Severity;
  • 重复出现;
  • 用户真实投诉;
  • 已经修复;
  • 代表一种新的 Failure Mode;
  • 很容易再次发生。

Regression Case 必须重新定义成功条件。

例如原始失败是:

Agent 忘记审批阈值。

Regression 不应该只是保存旧输出,而应该定义:

must_include:
  - approval_threshold

critical_error:
  - approve_without_threshold_check

这样未来模型即使换一种表达方式,也能正确判断。

七、第四步:绑定 Fix 和 Evidence

每条 Regression Case 最好知道它为什么存在。

例如:

introduced_by: F-2026-017
fixed_by: commit-abc
root_cause: context-truncation
verification:
  - context_contains_rule
  - output_covers_rule

以后如果它再次失败,就能快速判断:老问题回来了,还是新原因导致同样症状。

八、不要只保存失败输出,要保存 Trace

对于 Agent,Final Answer 往往不是根因所在。

例如最终表现只是“任务失败”,但 Trace 可能显示:

Step 3 Tool Timeout
Step 4 自动 Retry
Step 5 切换到错误环境
Step 6 State 未重新验证

真正的问题其实是 Recovery Policy。

所以 Failure Corpus 对 Agent 来说应该尽量保存 Goal、Context、Trace、Tool Calls、State Changes、Artifacts、Final Result 和 Evidence。

九、Failure Corpus 应该支持两个方向的检索

第一类是按业务检索,例如采购、审批、库存、权限,回答:

这个业务过去发生过哪些 AI 失败?

第二类是按 Failure Mode 检索,例如 state_desync、wrong_tool、missing_evidence,回答:

这个技术失败模式在哪些业务里出现过?

第二种对 Reliability 尤其重要,因为同一种 Runtime Failure 可能跨多个业务重复出现。

十、Corpus 不是越大越好

如果 Corpus 里有 5000 条重复低价值失败,会变得越来越难维护。

例如 20 个 Case 都是“长上下文下遗漏早期约束”,可以保留少量代表 Case、若干业务变体和一个统一 Failure Type。

重点是:

覆盖 Failure Mode,而不是堆数量。

十一、什么时候 Failure 才算真正关闭

传统 Bug 常见的是:

代码修了
→ close

AI Reliability 更合理的关闭条件应该是:

Failure reproduced
+
Root cause identified
+
Fix implemented
+
Independent verification passed
+
Regression case added
+
Gate includes regression

也就是:

没有 Regression,就不算真正修完。

十二、Failure Corpus 最终会成为系统的“免疫记忆”

它会逐渐回答:

  • 我们以前在哪些地方失败过;
  • 为什么失败;
  • 怎么验证已经修复;
  • 下一次改动会不会再次触发。

当它和 Eval、Trace、Quality Gate 串起来之后:

Failure
↓
Evidence
↓
Root Cause
↓
Regression
↓
Gate

真实事故才真正变成了系统能力。

下一篇继续进入 Agent 场景:

Trace 到底应该怎么 Grade,才能发现“结果对了但过程错了”?

参考资料

继续阅读这个系列

AI Eval:从大模型评测到 Agent Reliability →
  1. 大模型评测到底在评什么?Benchmark、Eval、业务评测一次讲清
  2. 排行榜第一,为什么到了你的业务里可能不好用?
  3. Model Eval 和 Agent Eval 有什么区别?从单次输出到完整执行轨迹
  4. 怎样构造一套真正有用的业务 Eval Dataset?
  5. LLM-as-a-Judge 怎么做才靠谱?从 Rubric、偏差到人工校准
  6. Eval 指标怎么设计?为什么 Pass Rate 远远不够
  7. Offline Eval 和 Online Eval 有什么区别?一套 AI 系统为什么两个都需要
  8. 线上失败怎么变成 Failure Corpus?从一次事故到持续回归 · 当前篇
  9. Agent Trace Grading 怎么设计?结果正确,过程也可能已经失控
  10. 怎么把 AI Eval 接进 CI / Quality Gate?让评测真正阻断坏版本
  11. 需求不完整时,测试用例生成的 Gate 应该怎么判?
  12. 测试用例 Agent 的门禁落地:一条需求缺口,应该挡住哪些用例?

沿着问题继续探索

从执行机制走向验证与交付。

相关文章

在 GitHub 反馈 ↗