给AI系统做回归测试:LLM评测的工程实践

传统系统改了一个函数,跑一遍单测,全绿就提交。LLM 应用里这套办法失效:输出是随机的,同一个问题,这次返回"好的",下次返回"好的没错"。改了一版 prompt,怎么知道没把别的东西改坏?答案和软件工程一样:搞一套回归测试集。

专属插画
给AI系统做回归测试:LLM评测的工程实践

给AI系统做回归测试:LLM评测的工程实践

传统系统改了一个函数,跑一遍单测,全绿就提交。LLM 应用里这套办法失效:输出是随机的,同一个问题,这次返回"好的",下次返回"好的没错"。改了一版 prompt,怎么知道没把别的东西改坏?答案和软件工程一样:搞一套回归测试集。

先把"输出"压缩成"判分"

评测的关键不是比谁输出更像样,而是把输出压缩成一个"判定"。打分方式分两类:

- **确定性规则**:JSON 能解析、必填字段非空、必须包含或不包含某些关键词、SQL 语法合法、答案命中参考答案。能写成代码的一律写成代码,零成本、零抖动。

- **LLM 当裁判**:开放式质量(语气是否合适、是否漏掉潜在风险、解释是否完整)交给另一个模型按 1-5 分打分,要求它必须给出理由,评分标准(rubric)逐条写进 prompt。

一条经验法则:能用规则判的,不要请裁判模型。裁判本身也会抖,每多套一层模型就多一层噪声,而且按 token 付费。

举一个具体的:保险条款问答机器人,规则层写三条——输出必须包含"免赔额、等待期、报销比例"三个短语,总字数不超过 300,必须是 JSON 且字段非空;裁判层 rubric 只写两条——有没有引用错误条款编号(5 分制),解释有没有多于三句话的段落(5 分制)。两层合起来的输出一对分数加一份错误明细,不是那篇回复本身。评审的人看的是"哪条挂了、挂在哪",不用重读一遍模型输出。

测试集要固定,要进版本库

- **30-100 条够了**,再多边际收益很低。Case 从线上真实日志里挑,必须包含:线上真实问过的、被用户投诉过的、边界值、出现频率最高的 Top 10 请求。

- **存进 git**:题目、参考答案、rubric 一起版本化。测试集是资产,不是临时文件。下次换模型,你靠它对比。

- **锁变量**:采样温度固定,模型版本、prompt 版本都锁死。一次只动一个变量,否则测试集告诉你"有变化",你不知道锅在谁。

给 CI 设门禁

改动前跑一遍全量测试集,记录每个 case 的通过与否作为基线;改完再跑一遍,对照。红绿标准建议三条:

1. 总通过率不低于基线;

2. 单个 case 不许从"过"变"挂"(新增"挂"可以讨论,但要有解释);

3. 规则类硬错误(JSON 解析失败、必填字段缺失)直接 fail,零容忍。

把这套流程接进 CI:prompt 变更、模型升级、依赖版本变化,先跑 eval job,不绿不许合并。这就是给概率系统做的"提交前检查"。

每次跑完要不要留一份报告?要。报告格式固定四块:总分、分类别通过率、新增挂掉 case 的逐条原因、新变绿的 case 列表。目标是让一个人三十秒内回答"这次改动坏掉了什么"。做不到这一点,eval 就是黑盒积分,没人会长期看,门禁也就形同虚设。

三个常见坑

1. **测试集污染**:题目混进了模型训练数据,或出现在 few-shot 示例里,分数虚高,你看不到真实变化。换新模型后先人工抽查 10 条,再信聚合数字。

2. **过拟合测试集**:对着 50 个 case 反复调 prompt 调到全绿,上线又开始犯老毛病。定期淘汰旧 case、补新 case,让测试集跟上线上分布。

3. **单 case 判生死**:一条失败不代表改动是坏的,一条通过也不代表是好的。只看聚合数字和回退名单,别盯着单条输出纠结。

评测到底解决什么问题

评测不追求高分,追求"不退回"。改动前 100 分制下 85 分,改动后掉到 72,你得找出是哪类 case 掉的、为什么,改回 86 再上线。对 AI 系统来说,回归测试的价值不是保证模型正确,而是你弄坏东西的时候,团队不用等用户投诉才知道。

留言区

欢迎分享你的想法!

发表留言

0/500

加载留言中…