这篇学完你能回答什么
- AI 应用上线前怎么评测?评测集从哪来、多少条起步、怎么分层?
- 离线评测 92 分、上线投诉翻倍,你从哪里开始查?
- 换了新模型,评测集上涨了 2 个点,能上吗?
从一个真实故障讲起
一个企业内部知识库问答系统,上线前评测 92 分。评测集 120 条,判据是「答案是否命中标准答案的要点」,人工写的标准答案,GPT 系模型判分。所有人都觉得可以发了。
上线两周,客服工单里「这机器人答非所问」的投诉是灰度前的 2.3 倍。
复盘时做了一件本该在上线前做的事:从线上抽 200 条真实 query,和评测集摆在一起对比。
| 维度 | 评测集 | 线上真实流量 |
|---|---|---|
| 完整问句 | 87% | 39% |
| 残句/关键词(「年假 几天」「病假条谁签」) | ~0 | 61% |
| 发生在第二轮及以后(带「上面那个」「那如果……呢」这类指代) | 0 | 44% |
| 问的是知识库里根本没有的内容 | 0 | 12% |
这三条加起来解释了绝大部分差距。而这个评测集的来源是:产品经理和两个工程师,在需求评审后的一个下午,对着知识库目录写出来的 120 条题。
它测的是「知识库里有的东西,模型能不能答对」。线上要的是「用户实际会怎么问,以及问了知识库里没有的东西时会怎样」。这是两件不同的事,但两个 92 分看起来一模一样正当。
更要命的是第三行和第四行。多轮指代和「库里没有」这两类,在评测集里出现次数是零——不是分数低,是根本没有分数。一个指标为零的维度,在看板上是不可见的。团队看到的不是「多轮场景 30 分」,而是「多轮场景不存在」。
这个故障的真正教训不是「评测集要更大」,是「评测集的分布必须和线上一致,而且你必须真的把两个分布摆在一起看过」。 分数是不是 92 不重要,重要的是这 92 分是在什么样的输入上拿到的。
对着知识库目录出题断点
产品经理和两个工程师,一个下午写了 120 条
离线评测 92 分
判据是「答案是否命中标准答案的要点」
所有人都觉得可以发
两个 92 分,看起来一模一样正当
投诉是灰度前 2.3 倍
客服工单里全是「答非所问」
抽 200 条线上 query
和评测集摆在一起,差距一眼看见
核心概念:先打比方,再给定义
打比方:评测集不是期末考试,是回归测试套件(regression test suite)。
期末考试考完就作废,回归测试套件是资产——每次改动都要跑,越攒越厚。而且没人会因为「这次单测全过了」就宣称系统没 bug,大家心里清楚它只证明一件事:已知的那些 bug 没有回来。
评测集完全一样。它的作用是防止已知问题复发,不是证明系统好。想明白这句,后面所有判断都会顺。
几个术语(首次出现,中英对照 + 人话):
- 评测集(eval set / golden dataset,也叫黄金集):一组固定的输入 + 一套判分方式。判分方式可能是标准答案,也可能只是一条判据。人话:一套每次改动都要重跑的题。
- 离线评测(offline evaluation):在固定评测集上跑。输入不变、可重复、可回归。人话:关起门来考试。
- 线上评测(online evaluation):对真实流量采样打分。输入每天在变,通常没有标准答案。人话:在真实考场上抽卷子看。
- 业务指标(business metric):转化率、工单解决率、人工复核通过率、退货率。人话:老板真正在意的那个数。
三条线(本章主线)
线 A 离线评测集 固定输入 / 有标注 / 可重复 → 决定「能不能发」 线 B 线上采样评测 真实输入 / 无标注 / 分布在动 → 决定「发完之后有没有变坏」 线 C 真实业务指标 滞后但唯一真实 → 终审
三条线只能互相佐证,不能互相替代。 它们两两之间的背离各自对应一个明确的诊断:
| 现象 | 诊断 |
|---|---|
| 线 A 涨、线 B 不动 | 评测集与线上分布脱节(开篇故障就是这一类) |
| 线 B 涨、线 C 不动 | 你在优化 judge,不是在优化产品 |
| 线 C 涨、线 A 不动 | 收益可能来自别的变更,别把功劳记在模型上 |
| 线 A 不动、线 B 掉 | 输入分布变了(新渠道、新活动),或者线上有离线复现不出的环境因素 |
这张表是本章最常被引用的东西——任何一个「这个改动要不要上」的问题,标准答案都是先说清楚你打算用哪条线来判。
同一套题,改一次跑一次
考场安静、题目也不会变 —— 它测不到你从没出过的题
固定输入 / 有标注 / 可重复
决定「能不能发」。分数的绝对值几乎没有意义,有意义的是同一套题在两个版本之间的差值
每天的卷子都不一样
没有标准答案,只能抽样看,且抽到的分布每天在动
真实输入 / 无标注 / 分布在动
决定「发完之后有没有变坏」。对真实流量采样打分,输入每天在变
原理拆解
| 要回答的问题 | 算法 / 口径 | 算出来 | 读法 |
|---|---|---|---|
| 多少条题才够 | n = z² · m̂(1 - m̂) / ε² | 95% 置信、±5%、预期 80% → n ≈ 246 | 误差收到 ±3% 要 ~700 条 |
| n=100 能分辨多大 | 独立比例的置信区间 | 基线 80% 时约 ±7.8 个百分点 | 涨 2 个点连半个区间都没走出去 |
| 同一套题两个配置 | McNemar 只看结论翻转的题 | 100 题里翻转 10 条:6 比 4 | 远不显著;9 比 1 才开始有话说 |
| 跑一次算不算数 | K = 3~5,每个配置各跑 K 遍 | 报 mean ± std | 采样参数退场后,单次只是一次采样 |
配对检验按数据形态选:二元(对 / 错、pass / fail)用 McNemar,连续分(0.0–1.0)用配对 t 检验,Likert(1–5)用 Wilcoxon 符号秩。同样 n=100,配对检验能分辨的差异比独立比例小得多 —— 「评测集不大也能用」的前提就在这里。
防泄漏三条:评测集 ≠ 开发集(开发集随便对着它调 prompt,评测集只在跑分时看);评测集与微调训练集必须异源;再留一份保留集 holdout,从不参与任何迭代,只在重大版本前跑一次。
temperature 直接返回 400,方差比过去更难按住。一、离线/在线鸿沟的四个来源
离线 92 分
│
┌───────────────┼───────────────┬───────────────┐
▼ ▼ ▼ ▼
① 输入分布不同 ② 判据不同 ③ 上下文不同 ④ 数据泄漏
问法/长度/轮次 要点命中 vs 单轮干净输入 vs 评测集与开发集
/比例/难度 解决了问题 历史+状态+工具 同源,prompt
结果堆叠 对着它调出来的
│ │ │ │
▼ ▼ ▼ ▼
线上 2.3 倍投诉① 输入分布不同 —— 最常见,也最容易被忽略,因为它不报错。检查方法很朴素:把评测集和线上采样的 query 各自统计长度分布、轮次分布、意图分布,摆在一张表里看(开篇那张表就是这么来的)。一个下午能做完,但绝大多数团队从来没做过。
② 判据不同 —— 离线判「要点命中」,用户判「有没有帮我把事办了」。要点全命中但结论埋在第三段,离线满分线上被骂。而且这个偏差会随着你对着判据优化而不断放大。
③ 上下文不同 —— 承接四种上下文失败形态(污染 / 干扰 / 混淆 / 冲突)。离线是一次干净的单轮调用;线上是第 7 轮,前面堆了 3 次工具返回、1 次压缩、和一条用户中途改主意的指令。只测第一轮的评测集,一种都测不出来。
④ 数据泄漏 —— 最隐蔽。典型形态是评测集和调 prompt 用的例子同源,或者更常见的,prompt 是对着评测集一轮轮调出来的。此时分数上涨里有多少是真提升,你分不清。
二、评测集的三层结构
不是一个评测集,是三个,跑的频率和拦截权限都不同:
| 层 | 规模 | 跑的时机 | 耗时 | 拦不拦发布 |
|---|---|---|---|---|
| 冒烟集 smoke | 5–20 条 | 每次提交 | 秒级 | 拦(挂了说明链路断了) |
| 门禁集 gate | 几十 ~ 两百条 | 每次发布 | 分钟级 | 拦 |
| 全量集 full | 几百 ~ 上千条,含长尾 | 每周 / 大改动 | 小时级 | 不拦,只报告 |
判据:能进门禁集的,必须是「错了就该拦住发布」的用例。 把「锦上添花」的题放进门禁,结果一定是门禁天天红、所有人学会无视它——一个从不亮绿灯的门禁等于没有门禁。
三、评测集从哪来(四个来源,按含金量排序)
- 线上真实失败(最贵、最值钱)。每一条都是花了真实代价换来的。
- 线上真实成功流量的分层抽样。它保证的不是难度,是分布——开篇故障缺的就是这一类。
- 领域专家写的边界样例。覆盖罕见但后果严重的情况:越权、敏感、法规、极端数值。
- 模型批量扩写。最便宜。
铁律:第 4 类只能用来扩写,不能用来打底。 用模型生成的题去测模型,你测到的是「两个模型共同认为重要的部分」。真正会翻车的地方,恰恰是两个模型有共同盲区的地方——而合成数据在那里是空白的。所以听到「我们评测集有 5000 条」,第一句该问的是「谁标的」。
四、防泄漏三条
- 评测集 ≠ 开发集。 开发集随便看、随便对着它调 prompt;评测集只在跑分的时候看,不允许逐条读着改 prompt。
- 评测集与微调训练集必须异源(承接第 4 章的口径)。同源切分出来的评测集,测的是记忆不是能力。
- 留一份保留集(holdout),从不参与任何迭代,只在重大版本前跑一次。它是回答「我们这半年是真变好了,还是只是把门禁集刷穿了」的唯一手段。
五、统计关:「涨了两个点」是不是结论
第一步,先算置信区间。 单个比例的样本量公式:
n = z² · m̂(1 - m̂) / ε² (z=1.96 对应 95% 置信;m̂ 是预期的指标值;ε 是可接受的误差半径) 95% 置信、误差 ±5%、预期准确率 80% → n ≈ 246
反过来算:n=100、基线 80% 时,95% 置信区间大约是 ±7.8 个百分点。 涨 2 个点连半个置信区间都没走出去。
第二步,别用独立比例的算法。 上面那个 ±7.8pt 是「两组独立样本」的口径,而评测通常是同一套题、两个配置各跑一遍——这是配对数据。配对检验只关心结论发生翻转的那些题:
| 数据形态 | 该用的检验 |
|---|---|
| 二元(对/错、pass/fail) | McNemar |
| 连续分(0.0–1.0) | 配对 t 检验 |
| Likert(1–5) | Wilcoxon 符号秩 |
举例:100 题里 90 题结论相同,剩下 10 题 A 对 B 错 6 条、A 错 B 对 4 条——远不显著;9 比 1 才开始有话说。同样 n=100,配对检验能分辨的差异比独立比例小得多——「评测集不大也能用」的前提,就是你得会用配对检验。
第三步,模型自己也是方差源,而且 2026 年你按不住它。
按已冻结的口径 7,Opus 4.7+ / Sonnet 5 上传非默认的 temperature / top_p / top_k 会直接返回 400 —— temperature=0 这条老路已经没了。这意味着单次跑分不再是「确定性结果」,而是一次采样。正确做法是:
K = 3~5
for cfg in [baseline, candidate]:
for seed in range(K):
scores[cfg][seed] = run(eval_set, cfg)
report mean(scores[cfg]) ± std(scores[cfg]) # 每个配置报均值和方差
mcnemar(correct[baseline], correct[candidate]) # 只看结论翻转的题
一句话:没有配对检验、没有方差的「涨了两个点」不是结论,是噪声。
工程实践(截至 2026-08)
行业现状:看得见 ≠ 评得准
LangChain《State of Agent Engineering》(调研期 2025-11~12,n=1340):
| 项 | 全体 | 生产阶段团队 |
|---|---|---|
| 已上可观测 | 89% | 94% |
| 有细到单步/工具调用的 tracing | 62% | 71.5% |
| 跑离线评测 | 52.4% | — |
| 跑线上评测 | 37.3% | 44.8% |
可观测已经是基础设施,评测还不是。 这个落差就是本章存在的理由——大部分候选人能讲清楚 trace 长什么样,讲不清楚一个分数在什么条件下才配当决策依据。
评测集规模:三套数字,其实是三个阶段
面试里问「多少条起步」,标准答案不是一个数字,是先问处在哪个阶段:
| 阶段 | 你在做什么 | 规模 | 判据 |
|---|---|---|---|
| 0 · 还不知道自己会怎么错 | 错误分析:人工看线上 trace,给每条失败写一句话,再归并成类别 | 先看 100 条;约 20 条不再出现新类别就可以停(理论饱和) | 此时谈样本量毫无意义——你连指标是什么都还没定 |
| 1 · 已有失败分类,要建门禁 | 每个失败类别配用例 | 每类 20–50 条手工确认,总量几十到两百 | 这是判据集不是统计集:作用是钉死行为,不是估计比例 |
| 2 · 要拿分数做 A/B 决策 | 比较两个配置谁更好 | ±5% 需 ~250,±3% 需 ~700 | 回到统计;能用配对检验则可显著下调 |
这里有一个值得如实写出来的分歧:
- Anthropic 官方口径倾向 volume over quality——「更多题目 + 稍差一点的自动判分」优于「少量题目 + 高质量人工判分」,并鼓励用模型批量扩写测试用例;
- **实践派主流(Hamel Husain、LangChain 官方 checklist)**主张 20–50 条手工确认的胜过几百条没人看过的合成数据。
这两条不矛盾,差在「判分是谁做的」。 Anthropic 那条成立的前提是判分由代码做(精确匹配、schema 校验、单测)——此时每条样本边际成本接近零,多多益善。一旦判分要靠人或靠 judge,每条都有标注成本和噪声,小而精就重新占优。
可直接引用的判据:判分越便宜越可靠,评测集就越该大;判分越贵越主观,评测集就越该小而准。
避坑清单
- 别把评测集当期末考试。 分数绝对值几乎没有意义,有意义的是同一套题在两个版本之间的差值。跨评测集比分数(「我们 92 分,他们 88 分」)是纯粹的噪声。
- 别让评测集只增不减。 定期把「最近所有版本都 100% 通过」的用例降级到冒烟集——它们已经失去区分度,只在消耗预算。这和行业级 benchmark 的饱和是同一个现象,只是发生在你自己的仓库里。
- 别忘了把 effort 档位当成评测矩阵的一个维度。 提档位会改变输出 token 数、工具调用次数和成本——换档位和换模型一样,要走完整回归。
- 给评测集编版本号,并和跑分结果绑在一起存。 改了集合却不改版本号,历史分数曲线就全废了。
| 层 | 规模 / 时机 / 耗时 | 拦不拦发布 |
|---|---|---|
| 冒烟集 smoke | 5–20 条 · 每次提交 · 秒级 | 拦 —— 挂了说明链路断了 |
| 门禁集 gate判据最严的一层 | 几十 ~ 两百条 · 每次发布 · 分钟级 | 拦。能进这一层的必须是「错了就该拦住发布」的用例;锦上添花的题放进来,门禁就天天红 |
| 全量集 full | 几百 ~ 上千条含长尾 · 每周或大改动 · 小时级 | 不拦,只报告 |
- 规模按阶段定
- 阶段 0 先看 100 条(约 20 条不再出新类别就停);阶段 1 每类 20–50 条;要做 A/B 决策,±5% 需 ~250
- 来源按含金量
- 线上真实失败 > 成功流量分层抽样 > 专家写的边界样例 > 模型批量扩写;第 4 类只能扩写,不能打底
- 行业现状 n=1340
- LangChain 调研:已上可观测 89%,跑离线评测只有 52.4%,跑线上评测 37.3%
- 别让它只增不减
- 把「最近所有版本都 100% 通过」的用例降级到冒烟集 —— 它们已经没有区分度,只在消耗预算
- effort 档位也是一维
- 提档位会改变输出 token 数、工具调用次数和成本,换档位和换模型一样要走完整回归
- 给集合编版本号
- 并和跑分结果绑在一起存。改了集合却不改版本号,历史分数曲线就全废了
面试视角
- ① 澄清这个应用的失败长什么样:答错、答漏,还是答得对但没用
- ② 基线现在的分数是多少,在多大的集合上,什么判据
- ③ 加挂要加什么(更大的集合 / judge / 线上采样),代价是什么
- ④ 评测怎么知道这个改动真的有效 —— 配对检验 + 方差
- ⑤ 演进线上失败怎么回流成新用例
- 「评测集有 5000 条」—— 一被问「谁标的」就露馅
- 「用 GPT 打分,准确率 92%」—— 没有分布、没有来源、没有区间
- 「上线前跑一遍就行」—— 把评测当验收,不当回归
- 线上失败修完就算完,没有一条回流成新用例
- 「涨了两个点,效果挺明显的」—— 最容易被一句话问倒的地方
- 报得出评测集的来源构成:多少来自线上失败、多少是抽样、多少是扩写
- 说得出评测集分布和线上分布差在哪,以及是怎么发现的
- 说得出门禁集和全量集的区别,以及某条用例为什么进了门禁
- 讲得出一次漏到线上的问题,以及事后补了哪条用例
- 反问「多少条题、是不是同一套题配对跑的、重跑几次方差多大」
面试官会怎么问
- 「你们上线前怎么评测的?」(开场,几乎必问)
- 「评测集多少条?从哪来的?」(第一刀:有没有真建过)
- 「离线分很高但上线效果差,可能是什么原因?」(第二刀:有没有真踩过)
- 「换个模型评测集涨了两个点,你敢发吗?」(第三刀:有没有统计直觉)
答题结构建议
沿用 Q2-25 的五步骨架,落到评测这件事上:
① 澄清 这个应用的失败长什么样?是答错、答漏、还是答得对但没用?
② 基线 现在的分数是多少,在多大的集合上,什么判据
③ 加挂 我要加什么(更大的集合 / judge / 线上采样),代价是什么
④ 评测 我怎么知道这个改动真的有效——配对检验 + 方差
⑤ 演进 线上失败怎么回流成新用例
分水岭信号
暴露只读过:
- 「我们建了评测集,用 GPT 打分,准确率 92%」——只有分数,没有分布、没有来源、没有区间。
- 「评测集有 5000 条」——一被问「谁标的」就露馅。
- 「上线前跑一遍就行」——把评测当验收,不当回归。
- 「涨了两个点,效果挺明显的」——没有统计直觉,这是最容易被一句话问倒的地方。
证明真做过:
- 能说出评测集的来源构成(多少来自线上失败、多少来自抽样、多少是专家写的、多少是扩写的)。
- 能说出评测集分布和线上分布的差在哪,以及是怎么发现的。
- 能说出门禁集和全量集的区别,以及为什么某条用例进了门禁、某条没进。
- 能说出一次因为评测集没覆盖而漏到线上的问题,以及事后补了哪条用例——这是数据飞轮真实运转的唯一证据。
- 被问到「涨两个点」时,反问「多少条题上涨的两个点、是不是同一套题配对跑的、重跑几次方差多大」。这一句反问的杀伤力,大于前面所有回答。
小结与延伸
三句话小结:
- 评测集是回归测试套件,不是期末考试——它证明「已知问题没回来」,不证明「系统好」。
- 离线/线上鸿沟的四个来源里排第一的是输入分布不同,它不报错,只能靠把两个分布摆在一起看才能发现。
- 「涨了两个点」在没有配对检验和方差之前不是结论;而 2026 年采样参数退场后,方差比过去更难按住。
延伸阅读(本教程内):
继续深入
本篇归属第 5 章「评测与可观测」,去做这一章的题。