上一篇《一次 finish_reason=length 翻车》只解剖了一个坑:推理模型把输出 token 全烧在思考上,最终答案为空,评分器判错。这篇把视野拉满——一次完整的 LLM 评测,从题目到分数,沿途到底埋了多少坑? 我按评测管线把它们切成五层共 25 个,每个坑都挂上 arXiv 论文或成熟工程文章,并给出防线。这不是穷举,是一张能当 checklist 用的地图。
名词速查
| 术语 | 一句话解释 |
|---|---|
| 评测管线 | 数据集 → 模型生成 → 判据评分 → 指标统计 → 环境链路,五层串起来的完整流程 |
| 基准污染 | 测试题混进训练语料,模型背题而不是做题,分数虚高 |
| 位置偏差 | 模型偏好特定位置的选项/答案,与内容无关(MCQ 偏好 C 位、judge 偏好先出现的回答) |
| 长度偏差 | LLM 裁判系统性偏爱更长的回答,与质量无关 |
| Judge 漂移 | 裁判模型被供应商静默更新,被测对象一行没改、分数却变了(phantom regression) |
| pass@k | 采样 k 次至少成功一次的概率,有标准的无偏估计公式 |
| ECE | 期望校准误差,分箱统计置信度与真实正确率的差距,对分箱方式敏感 |
| candidate boundary | 评测声明的「被测边界」:只测模型权重,还是测模型+harness+环境的整个系统 |
| Goodhart 定律 | 「当一个指标成为目标,它就不再是好指标」——固定基准会被针对性优化到饱和 |
一张图:五层 25 坑
flowchart TD
subgraph D["① 数据层 · 题与答案"]
direction LR
D1["基准污染/背题<br/>2406.04244 · 2603.16197"]
D2["黄金答案脆弱<br/>扰动即掉点"]
D3["任务不自然<br/>2602.18029"]
D4["基准饱和/被刷榜<br/>Goodhart"]
end
subgraph G["② 生成层 · 模型输出"]
direction LR
G1["推理 token 截断<br/>2507.04023"]
G2["格式/指令遵循失败<br/>2311.07911"]
G3["Overthinking<br/>2504.13367 · 2604.10739"]
G4["选项位置偏差<br/>2309.03882 · 2406.19470"]
G5["Prompt 格式敏感<br/>2606.30219"]
G6["通用优化反伤<br/>2601.22025"]
end
subgraph S["③ 评分层 · 判据与裁判"]
direction LR
S1["匹配/归一化"]
S2["判据自身 bug"]
S3["Judge 三偏差<br/>2306.05685"]
S4["Judge 长度偏差<br/>2407.01085"]
S5["Judge 版本漂移<br/>2602.18029"]
S6["轨迹还是终态<br/>2602.03238"]
end
subgraph T["④ 统计层 · 指标计算"]
direction LR
T1["pass@k 有偏估计<br/>2107.03374"]
T2["校准分箱脆弱<br/>1706.04599 · 1904.01685"]
T3["小样本假确定<br/>Wilson 区间"]
T4["seed/解码方差<br/>2504.07086"]
end
subgraph P["⑤ 链路层 · 环境与复现"]
direction LR
P1["硬件/框架差异<br/>2504.07086"]
P2["服务链路≠模型标识<br/>2609.10494"]
P3["API 版本漂移<br/>2407.04069"]
P4["上下文长度虚标<br/>2601.08847"]
P5["丢样本/token 口径"]
end
D --> G --> S --> T --> P
先装坐标系:学术三维 vs 管线五层
学术界怎么切这件事?A Systematic Survey and Critical Review on Evaluating LLMs(arXiv:2407.04069) 把评测挑战归为三维:可复现性(同样条件能否复现结果)、可靠性(指标是否测了它声称测的东西)、鲁棒性(条件微扰后结论是否还成立)。这个分法学术上干净,但工程上不好用——你拿到一个异常分数,不知道去哪一层排查。
所以本文用管线五层:数据层、生成层、评分层、统计层、链路层。坑出现在哪一层,防线就建在哪一层。两套分法不冲突:三维是「病灶性质」,五层是「病灶位置」。
第一层:数据层——题和答案本身就有问题
1.1 基准污染:背题不是做题
测试数据混进训练语料是最古老也最顽固的坑。一份对六个前沿模型的检测发现:MMLU 整体污染率 13.8%,STEM 类 18.1%,哲学类高达 66.7%(arXiv:2603.16197)。综述见 Benchmark Data Contamination Survey(arXiv:2406.04244);Line Goes Up?(arXiv:2502.14318) 的判断更悲观:基准一旦公开发布,很快就会被吸收进训练语料,「分数上行」不代表「能力上行」。
防线:私有 held-out 集兜底;关键结论不依赖单一公开基准;用可再生成语料抗污染——RIKER(arXiv:2601.08847) 的范式是从已知 ground truth 反向生成文档,题目每次可再生,污染从根上不成立;上线前跑污染检测管道(开源方案见 arXiv:2310.17589)。
1.2 黄金答案脆弱
题面轻微扰动,分数就变:把数学题里的人名换一个,准确率可掉约 10 个点(苹果相关研究的公开报道,36氪出海转述)。模型在记「答案模式」而不是理解题。防线:配置多个等价答案;语义等价匹配;把改名、换数、调顺序的扰动诊断纳入流水线,报告扰动前后的区间而不是单点。
1.3 任务不自然(naturalness trap)
Towards More Standardized AI Evaluation(arXiv:2602.18029) 引述了一条尖锐的失败模式:大量基准是「人类从不做的 IQ 测试题」——人工模式匹配、十九分类情感、「医生我胳膊疼请选 C」式的别扭设定。它提出 Usefulness Criteria:一个能解这套基准的系统,真的能让人更高效吗?SWE-bench 成立,是因为题目来自真实 GitHub issue;合成味越重的基准,信号越低。防线:建题前先回答「这是不是用户真实会做的任务」。
1.4 基准饱和与 Goodhart 定律
固定基准会被针对性优化到饱和,2602.18029 把话说死:基准刷新是持续的基础设施成本,不是一次性任务。防线是把基准集当活资产——定期轮换、保留时间切片、监控头部模型分数的天花板效应。
第二层:生成层——模型输出的坑
2.1 推理 token 截断(上一篇的主角,简述)
推理模型的思考与可见输出共享 max_tokens 预算,思考烧光配额、finish_reason=length、content=null,评分器无答案可提取。LLMThinkBench 的实测数字值得记住:推理模型对简单题平均多花约 18 倍 token,token 受限时准确率骤降最高约 36%(arXiv:2507.04023);机制与修复详见上一篇。
2.2 格式 / 指令遵循失败:懂题但不按格式说话
- IFEval(arXiv:2311.07911) 用 25 类「可验证指令」(超过 400 字、关键词出现至少 3 次)量化指令跟随,分 strict/loose 两档,两档差距就是「被无关噪音带偏」的程度。
- LIFEBENCH(arXiv:2505.16234) 测长度指令遵循,结论反直觉:几乎所有模型实际都达不到厂商标称的最大输出长度,长上下文模型也不例外。
- CDCT(arXiv:2512.17920) 证明「约束遵循」与「语义正确」是两个近乎正交的维度(相关系数仅 0.193)——这是「格式失败必须和答错分开统计」最硬的学术依据。
防线:宽容解析器(支持多种答案写法)+ 单独统计格式违反率,不要把格式失败混进准确率分母。
2.3 Overthinking:简单题上想得太多
- ThoughtTerminator(arXiv:2504.13367):推理模型按题目难度分配 token 的「校准」普遍很差,越简单的题越容易过度思考。
- When More Thinking Hurts(arXiv:2604.10739):思考 token 的边际收益递减,过度思考甚至会让模型放弃先前已经正确的答案。
- Budget-Dependent Rankings(arXiv:2608.12150) 扫了 64→4096 七档 token 预算、5.6 万次推理:3–19% 的样本出现「预算越多准确率越低」的非单调行为,且模型排名会随预算反转。结论:评测必须声明 token 预算并做预算条件化报告,不能默认「给够 token 就是公平」。
2.4 选项位置偏差:MCQ 的老毛病
模型偏好固定位置而不是内容:Selection Bias in MCQs(arXiv:2309.03882) 记录了普遍的「C 位偏好」;Changing Answer Order Can Decrease MMLU Accuracy(arXiv:2406.19470) 打乱选项顺序后所有被测模型都掉点,只是敏感度不同;Position Bias Behind Ceiling Effects(arXiv:2607.20864) 点破后果:偏好 A 位的模型,在「标准答案恰好落 A 更多」的基准上分数虚高。防线:选项全排列/随机置换多跑几轮,报区间。
2.5 Prompt 格式敏感性:换个说法就变脸
EvalSafety Gap(arXiv:2606.30219) 的数字:GPT-3.5 在 320 种 prompt 格式 × 53 个任务下,准确率跨度高达 56 个点,且模型变大、加 few-shot、做指令微调都不消除这种敏感;独立实验在 SWE-bench/MMLU/HumanEval 上发现仅格式微调就能造成最高 76 个点的差异(acceptance-bench)。防线:固定 prompt 模板版本;关键对比用同一模板;报告多模板区间。
2.6 「通用 prompt 优化」反而有害
When Generic Prompt Improvements Hurt(arXiv:2601.22025) 有个刺眼的实验:给 prompt 追加一段「通用规则」后,Qwen 在 RAG 套件上从 26/30 崩到 9/30。通用优化不是单调改进,在一个任务上加分的措辞会在另一个任务上扣分。防线:每次 prompt 改动都按潜在回归对待,过任务专属评测集再上线。
另有一个工程坑:安全拒答(refusal)被算成答错。拒答是安全行为,答错是能力失败,混成一个 0 分会同时污染两类结论,必须单独分桶。
第三层:评分层——判据和裁判在撒谎
3.1 字符串匹配与归一化(工程坑)
1,000 与 1000、$1000、1000.00、**1000**,纯文本精确匹配全会判错;大小写、全半角标点同理。防线是数值归一化、剥离 markdown、target 列表支持多等价答案,并同时保留「原始提取值」和「归一化分数」双轨:前者 debug,后者聚合。
3.2 判据自身的 bug
判据是代码,就会有 bug:合并逻辑错、边界条件错、提取正则错。这类失败完全无声——不报错、不告警,只是指标悄悄偏。防线是先测判据,再测模型:用作弊构造用例(全对样本、全错样本、边界样本)给判据做单元测试,这套方法在站内《先测判据,再测 Agent》里展开过。
3.3 LLM-as-judge 的三块经典偏差
Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena(arXiv:2306.05685) 一次点名三块:位置偏差(先展示的答案占便宜)、冗长偏差(长答案占便宜)、自我增强偏差;LLM Evaluators Favor Their Own Generations(arXiv:2404.13076) 更发现模型能认出自己的输出并给高分,自我识别能力与自我偏好强度线性相关。防线:配对评测交换顺序各评一次、参考答案锚定、多裁判投票、人评定期抽检一致性。
3.4 Judge 的长度偏差:最容易被忽视
裁判偏爱长答案是可量化、可剔除的混杂因素。Length-Controlled AlpacaEval 用回归把长度差异控制为零后,自动评测与 Chatbot Arena 人评的 Spearman 相关从 0.94 升到 0.98(论文 PDF);Explaining Length Bias(arXiv:2407.01085) 进一步把胜率分解为「合意度(与长度无关)+ 信息量(随长度增长)」,指出长度是通过信息量间接影响判决。防线:长度受控胜率、等长区间比较,别让「啰嗦」伪装成「好」。
3.5 Judge 版本漂移:phantom regression
裁判模型被供应商静默更新后,被测对象一行没改,分数却变了,制造假回归信号(arXiv:2602.18029)。防线是裁判模型版本锁定、裁判输出持久化、定期用固定 golden set 体检裁判本身。
3.6 判据轴选错:盯轨迹还是盯终态
多路径任务里,把标注答案写死成「唯一正确轨迹」,会系统性误杀善于探索和纠错的模型——BFCL v3 因此把口径从 AST 轨迹匹配换成沙盒终态 diff(站内有源码级深读)。更上位的观点来自 「LLM Agent Performance」Is Not a Single Evaluation Target(arXiv:2602.03238):Agent 分数由模型、harness、环境、evaluator、推理预算共同塑造,报告分数前必须声明被测边界(candidate boundary)和条件策略(condition policy)——「固定参考栈比模型」和「比整套 Agent 系统」回答的是两个问题。
第四层:统计层——公式和样本量
4.1 pass@k 的有偏估计
朴素估计 1−(1−c/n)^k 系统性高估。Codex 论文 Evaluating LLMs Trained on Code(arXiv:2107.03374) 给出无偏组合估计 pass@k = 1 − C(n−c,k)/C(n,k),前提是 n 个独立同分布的完整采样;Beyond Pass@k(arXiv:2608.14711) 批评了一种常见误用:把「一次提交里的单元测试数」当 n——它们是同一份代码的相关子结果,不是独立样本。防线:记录真实 n/c,用无偏公式,按任务聚合。
4.2 校准指标的分箱脆弱
On Calibration of Modern Neural Networks(arXiv:1706.04599) 把 ECE 带火,也记录了现代网络的过自信;Measuring Calibration in Deep Learning(arXiv:1904.01685) 随后数了 ECE 的毛病:分箱数量、等宽 vs 自适应、L1 vs L2 范数,都能改变结论,并建议自适应分箱 + L2 + 类别条件化。防线:分箱策略写进配置固定下来,同时报 ECE + MCE + 可靠性图,单值 ECE 可以被分箱选择悄悄美化。
4.3 小样本的假确定性
12 条样本跑出 91.7%,标准误 0.083,一条样本翻转就是 8.3 个点。点估计在小样本上方差大得没有决策价值,必须带 Wilson 区间或 bootstrap 区间(口径见站内《评测分数的统计家族》)。
4.4 seed 与解码参数方差
A Sober Look at Progress in LM Reasoning(arXiv:2504.07086) 严格控制变量后复算近期工作:大量「RL 提升」依赖未报告的方差来源(解码参数、随机种子、prompt 格式),真实增益远低于论文宣称,且在 AIME’24 这类小基准上容易过拟合。防线:多种子平均、报告方差、对比时锁死全部解码参数。
第五层:链路层——环境在换底牌
5.1 硬件、软件与评测框架差异
同一模型、同一数据、同种子,只换评测框架(lighteval vs evalchemy),S1.1-7B 在 AIME24 上就是 22.2 vs 17.7;严格控制后仍有 2–5% 的不可约噪声(arXiv:2504.07086)。防线:报告硬件、框架、版本;关键对比在同一栈内完成。
5.2 服务链路 ≠ 模型标识
同名模型经不同网关/供应商接入,字段位置(思考内容放在哪个字段)、token 口径、缓存行为都可能不同。IBIB(arXiv:2609.10494) 主张按完整服务路由测量,而不是按模型名测量;2602.03238 同样要求显式声明 harness/环境/evaluator/预算。防线:记录「服务链路指纹」,换链路重测,模型对比只在同一链路上做。
5.3 API 模型版本漂移
浮动别名(同一个模型名)背后会被供应商静默更新,旧结论不可复现——2407.04069 把「模型版本信息缺失」列为可复现性的首要障碍。防线:记录精确版本/snapshot,关键评测定期重跑并留档。
5.4 上下文长度虚标
RIKER(arXiv:2601.08847) 用 210 亿 token 测了 33 个模型:标称上下文长度普遍超过可用容量,超过 32K 后显著退化;「找得到存在的事实」和「不编造不存在的事实」还是两种独立能力。防线:在自己的长度分布上做实测,不信标称值。
5.5 丢样本与 token 口径(工程坑)
限流重试覆盖原记录、completed < total 却显示完成、reasoning/cache token 不拆分导致成本失真。防线是任务完成度断言(完成数==总数)、重试计数上报、样本 ID 唯一性校验、成本按 input/output/reasoning/cache 拆分。
三条跨层主线
把 25 个坑并排看,有三条主线贯穿所有层:
- 静默性:最危险的坑不报错。 推理截断返回 HTTP 200、judge 漂移没有异常、分箱换了没人知道、样本丢了任务照样「完成」。所有防线的共同方向是把「悄悄发生」变成「显式报出」:查 finish_reason、断言完成数、锁定版本、固定分箱、记录区间。
- Goodhart 化:任何固定物都会被优化穿。 公开基准会污染、固定 prompt 格式会被适应、固定裁判会被讨好、固定基准会饱和。对策不是追求「终极基准」,而是让评测对象保持流动:私有集、置换选项、多裁判、定期刷新。
- 条件化:分数只有在声明条件后才有意义。 token 预算(2608.12150)、服务链路(2609.10494)、被测边界(2602.03238)、prompt 模板、种子——脱离这些条件的单一分数不可比较。报告的标准句式应该是「在 X 条件下,Y 模型为 Z」,而不是「Y 模型是 Z」。
评测防坑清单(评测前 / 中 / 后)
评测前
- 题目过 Usefulness Criteria;私有 held-out 集就位;黄金答案配多等价答案
- MCQ 生成选项置换版本;prompt 模板打版本号
- 锁定模型精确版本、服务链路、解码参数、token 预算;裁判模型版本锁定
评测中
- 每个响应查 finish_reason,截断/拒答/格式失败单独分桶,不进准确率分母
- 断言 completed == total、重试计数为 0、样本 ID 唯一
- 推理模型按任务限制思考预算;成本按 token 类型拆分
评测后
- pass@k 用无偏估计并记录 n;校准固定分箱、ECE+MCE+可靠性图同报
- 准确率带 Wilson/bootstrap 区间;多种子结果报方差
- judge 结果做换序、长度受控;关键对比附多模板/多预算区间
- 结论句式带条件:「在 X 条件下」;异常分数按五层管线倒查
诚实的提醒
- 「五层 25 坑」是我按工程管线做的切法,是分析工具不是行业标准;部分坑(如位置偏差)跨生成层和评分层,归类有主观成分。
- 文中数字(13.8% 污染、56 点格式跨度、18 倍 token、22.2 vs 17.7、26/30→9/30)均来自对应论文原文,各研究口径不同,直接横比要谨慎;人名替换掉 10 点来自媒体对苹果研究的转述,我未读到论文原文。
- 清单是工程经验与论文证据的合并,没有证据表明逐条执行就能消除全部偏差——评测的本质是用有限观测逼近不可见的真实能力,这套清单降低的是「被自己骗到」的概率。
小结
三行压缩:
- 一张地图:评测坑分五层——数据(污染/答案脆弱/不自然/饱和)、生成(截断/格式/overthinking/位置偏差/格式敏感/优化反伤)、评分(归一化/判据 bug/judge 三偏差/长度偏差/版本漂移/判据轴)、统计(pass@k/分箱/小样本/seed)、链路(框架/路由/版本/长度虚标/丢样本)。
- 三条主线:静默性(坑不报错)、Goodhart(固定物被优化穿)、条件化(分数必须带条件)。
- 一个动作:把每条防线做成评测流水线里的显式断言,而不是事后排查的经验。
5 分钟第一步
不用改任何模型代码,先给现有评测结果做一次「五层体检」,每层只问一个问题:
- 数据层:这批题有公开污染风险吗?黄金答案只有一种写法吗?
- 生成层:有多少样本 finish_reason 不是 stop?格式失败率是多少?
- 评分层:judge 换序后结论翻转吗?长度受控后排名变吗?
- 统计层:每个分数带置信区间吗?n/c 记录了吗?
- 链路层:模型精确版本、框架版本、token 预算写下来了吗?
五个问题里只要有一个答不上来,那层的分数就先别用于决策。
参考来源
综述与方法论:
- A Systematic Survey and Critical Review on Evaluating LLMs(arXiv:2407.04069)——可复现/可靠/鲁棒三维框架
- Towards More Standardized AI Evaluation: From Models to Agents(arXiv:2602.18029)——naturalness、judge 漂移、基准饱和
- 「LLM Agent Performance」Is Not a Single Evaluation Target(arXiv:2602.03238)——被测边界与条件策略
- acceptance-bench: The hidden fragility of LLM benchmarks
数据层:
- Benchmark Data Contamination Survey(arXiv:2406.04244)
- Line Goes Up? Inherent Limitations of Benchmarks(arXiv:2502.14318)
- An Open-Source Data Contamination Report(arXiv:2310.17589)
- Contamination Across Six Frontier Models(arXiv:2603.16197)
- RIKER: Scalable Contamination-Resistant Evaluation(arXiv:2601.08847)
生成层:
- IFEval(arXiv:2311.07911)、LIFEBENCH(arXiv:2505.16234)、CDCT(arXiv:2512.17920)
- ThoughtTerminator(arXiv:2504.13367)、LLMThinkBench(arXiv:2507.04023)、When More Thinking Hurts(arXiv:2604.10739)、Budget-Dependent Rankings(arXiv:2608.12150)
- Selection Bias in MCQs(arXiv:2309.03882)、Changing Answer Order Can Decrease MMLU Accuracy(arXiv:2406.19470)、Position Bias Behind Ceiling Effects(arXiv:2607.20864)
- EvalSafety Gap(arXiv:2606.30219)、When Generic Prompt Improvements Hurt(arXiv:2601.22025)
评分层:
- Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena(arXiv:2306.05685)
- LLM Evaluators Recognize and Favor Their Own Generations(arXiv:2404.13076)
- Length-Controlled AlpacaEval(PDF)、Explaining Length Bias in Preference Evaluations(arXiv:2407.01085)
统计层:
- Evaluating LLMs Trained on Code / pass@k(arXiv:2107.03374)、Beyond Pass@k(arXiv:2608.14711)
- On Calibration of Modern Neural Networks(arXiv:1706.04599)、Measuring Calibration in Deep Learning(arXiv:1904.01685)
- A Sober Look at Progress in LM Reasoning(arXiv:2504.07086)
链路层:
站内回链:
- 一次 finish_reason=length 翻车:LLM 评测的静默失败分几层——本篇姊妹文,单坑解剖
- BFCL v3 深读:多轮函数调用的评测口径——轨迹 vs 终态判据
- 先测判据,再测 Agent:业务评测样本的构造方法——判据体检
- 评测分数的统计家族:Wilson 区间——小样本区间
- LLM-as-Judge 学习笔记、IFEval 指令跟随学习笔记
- Inspect AI 实操:从零到一轮评测