大模型应用为什么需要回归测试?
简化版
大模型应用的行为由模型、Prompt、检索、工具、解码参数和安全策略共同决定,任何一处升级都可能让原本正常的场景变坏。回归测试用于持续验证核心能力、历史事故和高风险边界没有被破坏。
测试不能只做字符串精确匹配。格式、工具状态和代码结果可用确定性断言;开放回答用事实清单、Rubric、LLM Judge 与人工抽检;随机输出则通过多次采样、通过率和置信区间比较。发布门禁应绑定严重度和可回滚版本。
大模型回归测试验证的是行为契约,而不是要求每次生成完全相同的句子。
详细版
一次变更的依赖链可能是:
model / prompt / tokenizer / retriever / index / tools / policy
-> application behavior
-> quality, safety, latency, cost
例如新模型让事实正确率从 88% 升到 91%,但工具调用成功率从 96% 降到 89%,安全过拒率从 4% 升到 12%。只看一个总分会错误批准发布。
| 输出类型 | 推荐断言 |
|---|---|
| JSON/API 参数 | Schema、字段范围、权限规则 |
| 代码/SQL | 编译、单元测试、沙箱执行 |
| RAG 回答 | 引用存在、证据支持、事实清单 |
| 开放文本 | Rubric、配对 Judge、人评抽检 |
| Agent 任务 | 最终状态、Trace 合法性、副作用 |
| 安全行为 | 风险分类、拒答边界、泄露检查 |
完整版教学
1. 为什么模型升级会产生非局部回归
生成模型的能力耦合,高质量写作优化可能增加冗长,安全对齐可能提高过拒,模型更换还会改变工具参数格式和 Prompt 敏感度。
所以“新模型总体更强”不能替代目标应用的回归证据。
此外,供应商可能在同一接口名称下更新服务端实现,检索索引也会因新文档改变排序。即使业务代码没有提交,系统行为依然可能漂移,因此需要定时回归而不只在代码变更时运行。
2. 哪些变更必须触发回归
模型权重、供应商版本、系统 Prompt、Few-shot、Tokenizer、检索索引、Embedding、Reranker、工具 Schema、策略阈值和推理参数都应版本化。
任何真实依赖变化都触发相应切片测试,并周期性跑完整套件,防止依赖图漏标。
3. 回归集应该包含什么
包括稳定核心任务、边界场景、高风险政策、历史线上事故和关键工具链。每个测试记录失败严重度和责任模块。
新事故修复后应加入回归集,但要去重并保护隐私,避免集合无限膨胀。
4. 为什么精确字符串匹配通常不适合
“北京是中国的首都”和“中国首都是北京”语义相同,字符串却不同。过度 Snapshot 会把正常措辞变化当回归。
精确匹配适合固定协议 Token、关键字段和不可变文案;事实内容更适合结构化断言或语义评分。
能确定性验证的部分不要交给 LLM Judge;不能精确匹配的部分也不要硬做字符串快照。
5. 如何测试随机输出
固定 Seed 可提高复现,但线上解码和服务仍可能变化。对重要任务可运行多个样本,比较通过率而不是单次成败。
若基线 200 次通过 180 次,新版本通过 170 次,应计算比例差和置信区间;10 次差异可能来自波动,也可能是真回归。
6. Pairwise 比较为什么有用
把基线和候选答案匿名、随机顺序交给同一 Judge 或人评,判断胜/平/负,可减少绝对评分尺度漂移。
| 结果 | 含义 | 发布处理 |
|---|---|---|
| 候选显著胜出 | 有提升证据 | 继续检查安全与成本 |
| 大量 Tie | 实际差异小 | 根据成本/稳定性决策 |
| 候选显著落后 | 质量回归 | 阻断或定位切片 |
| Judge 顺序翻转高 | 评分不可靠 | 先校准 Judge |
7. Agent 回归为什么要验证最终状态
Agent 最终文字说“已完成”不代表动作成功。应在隔离沙箱检查数据库、文件或工单的最终状态,并验证没有多余副作用。
Trace 还要检查工具白名单、参数、重试次数和人工确认节点。路径不同可以接受,但权限违规不可接受。
8. RAG 回归要拆哪些层
分别测试检索 Recall、Rerank、上下文组装、生成忠实度和引用解析。端到端答案变差时,分层指标能快速定位。
索引更新也会导致回归,应保存文档版本和查询时点,防止用旧真值评判新政策。
9. 安全回归如何避免被总分稀释
越权、隐私泄露和高危帮助不能与普通措辞错误平均。按严重度设置独立 Gate,Critical 样本通常零容忍。
同时评估过度拒答,避免安全策略通过拒绝所有请求获得表面零违规。
10. CI 中如何分层运行
每次提交跑静态、单元和 Canary;合并前跑核心回归;夜间跑更大集合;发布候选跑全量、人评抽检和红队。
失败输出应含最小可复现配置、基线 Diff、Trace 和责任切片,才能真正支持修复。
为了控制反馈时间,可并行运行互不依赖的切片,并在 Critical Gate 失败后取消后续昂贵任务。所有层级仍应把结果写入同一版本化报告,避免只在控制台留下无法审计的日志。
11. 怎样定义发布门禁
预先定义不可回归指标、允许波动和最小实际提升。不要等看到结果再挑对候选有利的阈值。
critical_safety_failures == 0
tool_success_rate >= baseline - 0.5pp
grounded_accuracy >= baseline
p95_latency <= SLA
cost_per_success <= budget
豁免必须有负责人、期限和回滚方案。
12. 如何处理 Flaky Tests
先判断随机采样、外部工具、Judge 不稳定或真值歧义。记录重复运行分布,修复依赖和评分,而不是简单扩大重试次数。
长期 Flaky 的门禁会让团队习惯忽略红灯,最终失去测试可信度。无法稳定评分的样本应进入隔离区,修复后再恢复。
13. 版本、缓存与可复现性
报告应绑定模型、Prompt、数据集、Judge、工具和环境版本。缓存 Key 覆盖所有依赖,避免旧答案混入新实验。
保留基线产物和关键 Trace,才能在数周后重现“为何这个版本被批准”。
14. 常见误区与追问
- 误区:大模型输出随机,所以无法回归测试。 可对结构做确定性断言,对语义做统计比较。
- 误区:只固定 Seed 就足够。 模型、算子、工具和索引版本仍会变化。
- 误区:总分上升就没有回归。 高风险或关键工具切片可能显著恶化。
- 误区:所有输出都应做 Snapshot。 开放文本的正常改写会造成大量假失败。
- 误区:失败多重试几次通过即可。 应定位 Flaky 根因并明确统计规则。
- 追问:新事故如何进入回归集? 脱敏、去重、根因分类、双重标注后加入对应切片。
- 追问:怎样避免测试过拟合? 保留私有滚动集与线上抽样,不只针对固定 Core 调参。
15. 加强记忆
- 测完整系统:模型、Prompt、RAG、工具和策略都是版本依赖。
- 断言分层:能执行就执行,能结构化就结构化,开放语义再用 Judge。
- 随机用统计:多次采样、通过率、配对比较和置信区间。
- 风险独立 Gate:Critical 不被总体均值稀释。
- CI 分层:提交 Canary、合并核心、夜间扩展、发布全量。