线上每一个被用户投诉、被人工拦下或被监控报警的失败,都是一次免费的、来自真实分布的测试样本。如果修完就过去,团队会在下一个版本反复踩同一个坑;只有把它沉淀成可回归的用例,评测资产才会随时间增值。
一条 Badcase 的生命周期
| 阶段 | 动作 | 产出 |
|---|---|---|
| 捕获 | 从投诉、日志、监控、人工抽检中标记失败样本 | 原始 Trace |
| 脱敏 | 去除个人信息、密钥、内部标识 | 可共享样本 |
| 归因 | 判断失败类型与根因 | 失败标签 |
| 复核 | 第二人确认期望行为与严重度 | 已确认用例 |
| 入库 | 写入回归集并关联来源 | Golden 用例 |
从线上到回归集的六步
- 捕获:统一入口收集失败样本,保留完整的输入、输出和上下文 Trace,不要只截一句话。
- 脱敏:按固定规则清洗 PII、凭证和内部路径;原始 Trace 与脱敏样本分开存,用来源 ID 关联。
- 去重:同一根因的大量相似样本只保留有代表性的几条,避免回归集被单一问题淹没。
- 归因:给每条样本打上失败类型标签(见下),这是后续统计和止血的依据。
- 复核:由非提交人确认"期望行为"和严重度,避免把模型的正确拒答误判成失败。
- 入库:写入 Golden 集,记录来源 ID、标注人、标注版本和纳入日期。
失败归因的标签体系
把"它答错了"拆成可统计的类别,才能判断该修模型、修检索还是修 Prompt:
- 检索失败:相关内容没召回,或召回了无关内容。
- 事实错误:有依据却答错,或无依据却编造。
- 指令遵循:忽略格式、长度、语气或安全约束。
- 拒答失衡:该答的拒答,不该答的照答。
- 安全越界:提示注入、越权、泄露系统提示。
- 稳定性:同一输入多次结果不一致。
最小化记录格式
一条回流用例至少包含来源、输入、期望和标签,建议用结构化格式保存,方便批量回归:
case_id: bc-2026-0142
source_trace: trace-9f3a1c # 关联原始 Trace,可追溯
scenario: 退款政策问答
input: "超过7天还能退款吗"
expected: "说明7天条件,并在无依据时明确拒答"
failure_type: 事实错误
severity: P1
evidence: ["kb/refund-policy.md"]
labeled_by: reviewer-02
added_at: 2026-11-04
回流节奏与配额
- 定期而非攒批:每周固定回流一次,让回归集稳定增长,而不是上线前突击补样本。
- 设配额防偏科:限制单一根因的样本占比(例如不超过回归集的 15%),避免模型被某类问题"过拟合"。
- 分级执行:冒烟用例每次提交都跑,完整回归集在发版或合并请求时跑。
常见误区
- 只存结论不存 Trace:事后无法复现,用例也就失去了价值。
- 提交人自己判定通过:缺少第二人复核,容易把主观偏好当成标准。
- 把回归集数量当增长指标:数量不是目标,覆盖关键风险才是;无效样本要定期清理。