跑之前先预注册 benchmark
六条规则,把一次 AI 评测钉死到结果出来之后你掰不动它——每一条都能追溯到某一轮独立审查,而那一轮正是抓到我们违反它的那轮。附方法模板、飞行前检查清单,以及一份偏离日志格式:跑测中途发现方法本身错了,它也能保持诚实。
本页如何生产
由 AI agent 起草。 由与生产方不同模型族的模型逐条对照来源与原始数据做了对抗式审查,无未决 P0。尚未经人工通读。 证据最近核验于 2026-09-09。
下面每一条规则,都源于某位评审者抓到我们违反了它。每一处都点名了是哪一轮。
关于评测 AI 系统的建议,大多在说测什么。这一页说的是更窄的一件事,按我们的经验也更 决定性:在数字存在之前,把方法就地钉死。这样等结果出来不合意时,你没法悄悄把问题改掉。
这不是从文献里学来的。我们是把一次评测准备拿去发表,被独立审查连着拦了五轮——然后把它 砍掉——才学到的。每一轮都找到一种不同的方式,让一个看着合理的结论跑到它证据的前头。 下面这些计数,逐字抄自我们自己的记录:
| 轮次 | 裁决 | 发现 | 真正要命的缺陷 |
|---|---|---|---|
| R1 | BLOCKED | 19 P0 / 3 P1 / 1 P2 | 一个排名式 benchmark,其输入、分数和方法沿革都拿不出证据 |
| R2 | BLOCKED | 8 P0 / 3 P1 | 效度下限是在我们已经知道它会排除哪些跑测之后才写的 |
| R3 | BLOCKED | 9 P0 / 3 P1 | 标题层的结论撤回了,数据层没有 |
| R4 | BLOCKED | A7 / B4 / C2 | 一个前置指标失败,把下游指标全部序列化成了零 |
| R5 | BLOCKED | A6 / B3 / C1 · A3 / B8 / C1 | 按产品下的结论还活在跑测日志里;测量仪器没记版本 |
(R1–R3 按 P0/P1/P2 严重度计数;从 R4 起评审者改用 A/B/C 收敛分级,所以那些不是 P0 计数,别拿来当成 P0 比。R5 是两场并行审查——见规则 1。)
谁该用它——谁该跳过
适合你,如果:你打算公开发布一个比较不同系统的数字,或者这个数字会有人照着行动; 而且你请得起一个没参与这项工作的评审者。
跳过它,如果:你还在探索。探索就该便宜、快、不声张——这套纪律的代价,只有在你决定 结果要出门的那一刻才值得付。事后再来补这个决定,正是预注册要防的失败模式。所以早点决定, 拿不准就往预注册这边靠。
六条规则
规则 1 —— 写方法的人不能是跑方法的人
来自 R2。我们的效度下限——一个 case 要算数,至少需要多少次成功的跑测——是事后补上去 的,而它决定了哪些 case 被报成「无结果」。写它的时候,排除名单已经摆在眼前。这事谈不 上不诚实;它只是没法被证明是独立的,而对一个要公开的数字来说,这是同一个问题。
结构上的修法很便宜:把角色分开。下面那个实例里,方法由负责编排的那个会话写,由一个 不同的 agent 执行,这一点作为刻意选择写进了方法本身。不跑实验的人没法把方法调到讨好结果 的方向,因为他一个结果都没看见。
同一套逻辑往上一层也成立,在审查这一层。我们的审查跑在与产出工作不同的模型族上——生产者 不能给自己发证。第五轮并行跑了两个评审者,结果是我们手上最硬的一条方法论发现:
去重之后有七条 A 类发现。只有两条重叠。一个评审者自己找到了四条另一个漏掉的; 另一个找到了一条谁都没看见的。两组都是 A 类。
面对散布在好几层里的缺陷,单个评审者的召回明显不全。加第二个评审者买到的,比用同一个 评审者再跑一轮要多。
规则 2 —— 把方法冻成陌生人也能核的形式
「我们先写了方法」是一句关于过去的论断,读者无从核对。把它变成可核的:给冻结的那段取 哈希,把哈希发出来。
我们的方法文档冻结在第 1–10 节(第 1–122 行)。这几行在跑测前后哈希一致:
head -n 122 method.md | md5sum
edc553bc3dca31a760c2c109dea9a9c5 # 跑测前
edc553bc3dca31a760c2c109dea9a9c5 # 跑测后
注意被取哈希的是什么。整个文件的哈希确实变了——而且是故意的——因为第 122 行以下 全是一份只追加的偏离日志。一份永远不许追加的冻结文档,就是一份人们照样会偷偷改的文档。 把构成承诺的那一段冻住;在它下面留一份不断生长的记录;给那一段取哈希,不是给整个文件取。 声称文件没变过会是假话,而且一戳就破。
规则 3 —— 公开声明效度下限和止损线,并写明它们约束本次跑测
有两样东西必须在第一次测量之前写好:
- 效度下限——本次跑测要算数,就必须通过的那几项对照。我们定的是四项:环境正常应答、 既有规则未被污染、真 404 就是真 404、移除测试材料后基线不变。任何一项对照失败,整次跑测 作废;数据不公开,这次尝试记为未完成。
- 止损线——什么时候放弃。我们的:五分钟内没有有效响应就停;三次请求给出三个不同结果, 就把那一格记为不可观测,在它稳定下来之前不要扩大样本——这是「不做 p-hacking」的 机械化形态;总共三十分钟,到点就停,把已有的记下来。
让这两条真正生效的,只有一句话:「本条规则约束本次跑测。」 少了它,一条在跑测中途写下 的止损线,就成了事后挑选结果的工具——这正是 R2 那个缺陷,只不过穿上了安全装备。
规则 4 —— 「测不到」不等于得零分
来自 R4。在更早那次评测里,有一个指标是它后面四个指标的前置。它一失败,剩下四个就 完全没法观测——而数据模型没地方放这件事,于是它们被序列化成了 0。接着读者,以及每一张 下游表格,都在本来没有测量的地方看到了四个糟糕的分数。
修在数据模型里,不在文字里:三个取值,不是两个。
| 取值 | 含义 |
|---|---|
effective | 表现符合规范 |
silently-ignored | 没起作用,也没报任何错误信号 |
not-observable | 前置条件未满足——这一格没有测量值 |
还有两条纪律守着第三个取值,让它保持诚实。在跑测之前定好映射——哪一种观测落进哪个桶,
趁桶还空着的时候写下来。以及计数即使为零也要报:我们那次完整跑测记的是
not-observable = 0,并且明说了,因为「没有东西测不到」是一个结果,而一个悄悄缺席的类别
只是个缺席。
规则 5 —— 撤回一个结论时,证据层也要一起扫
来自 R3,R5 又犯一次。排名那条论断撤回之后,标题层干净了——而中位数分数表还在往外 发,只是改了个名。一个按产品下的结论,在标题层撤回了、在数据层还站着,那它就没被撤回。
第五轮在更深一层找到同一个形状:点名到具体产品的结论还活在内部跑测日志里,全是对我们有利 的,而页面本身早就不再说这些了。
这里附带着一条机械层面的教训,它让我们吃了一个线上缺陷。那次评测最终被砍掉时,删除它的
那个提交声称悬空引用已清理。它 grep 了路由。它没 grep 名字。一天之后,两个指向
已删除工作的承诺还在生产页面上对外服务——是用一条朴素的 curl 发现的,不是靠推理推出来
的。
grep 主题的名字,别只 grep 它的 URL。一条路由只属于你删掉的那个东西。而它的名字 散落在所有曾经提到过它的地方。
规则 6 —— 测量仪器必须记下自己的版本
来自 R5 的第二位评审者。有一个指标被定义为「用第二个应用打开这个成品」。外部那次跑测
记下了那个应用的精确构建哈希。我们自己那三次跑测只记了一条光秃秃的 soffice 命令——没有
版本,哪儿都没有。可页面上还是把这项检查描述成用某个具体的 LibreOffice 版本做过的,而日志
撑不起这句话。接收端是测量仪器的一部分;接收端不带版本,测量就不可复现。
同一条规则反过来照到了我们自己的审查流程上,这是整页里最让人不舒服的一条发现。前五份审查 报告没有一份记下是哪个模型、哪条命令产出的——拿任何一个工具名去这五份里搜,什么都搜不到。 因为这个缺口,我们自己第一份关于审查链的书面记述把机制写错了:它从报告的文风去推断评审者 是谁。纠正它靠的是去读原始的派发记录。
如果一场审查的全部价值就是「有一个独立的一方看过」,那么是谁看的就是那条发现本身 ——而且必须由流程在当场记下来,不能事后从语气里重建。
现在每份报告开头都带一段溯源信息:模型、派发命令、基线提交、裁决、整改提交。
一个完整跑通的实例
按这套规则跑的最新一次研究很小:在静态托管上,哪些重定向规则写法会无声失败。它是个好示范, 恰恰因为它不起眼。
| 纪律 | 如何体现 |
|---|---|
| 规则 1 | 方法由一个会话写,由一个不同的 agent 执行 |
| 规则 2 | 第 1–10 节的哈希在跑测前后都是 edc553bc… |
| 规则 3 | 四项对照全过;三条止损规则一条都没触发——第一项对照约 2 秒应答,限值 300 秒;整次跑测约 17 秒,限值 30 分钟 |
| 规则 4 | 三取值数据模型;not-observable 最终为 0,这个零被报了出来 |
| 规则 5 | 范围限制事前写进方法:本地模拟器,不对生产环境下任何论断 |
| 规则 6 | 工具版本、node 版本、脚本哈希、冻结输入快照指纹,全部记录在案 |
冻结线以下记了十条偏离,D1 到 D10。其中两条正是整件事的意义所在:
- D5——方法错了,我们没有回头改它。跑测中途我们发现,自己的判读表把「到达了跨域目标」
和「返回了本地内容」混为一谈。按那条有缺陷的规则,已经有两格被判成
effective。我们把 裁决原样留在冻结规则产出它的位置上,在旁边记下真实观测,并注明方法的下一个版本需要一个 溯源测试。如果为了得到我们现在相信的答案去改写规则,预注册所保护的一切都会被毁掉。 - D8——第一次尝试中断了,以及为什么重跑是合法的。一个 shell bug 导致最后一条规则 压根没被真正请求过。这是在看过任何结果码之前发现的,所以重来不是一个依赖结果的选择 ——而且中断那次的原始输出也留着。看过数字之后再重跑,性质就完全不同了。
这套东西买到了什么,没买到什么
- 已核验:六条规则每一条都能追溯到我们自己审查史里点名的一轮;上面的计数逐字抄自那份 记录。那个实例是真跑过的——冻结的方法、取过哈希的区段、四项对照全过、144 次请求、记下 D1–D10 十条偏离。
- 未核验:这些规则是否可推广。这是一个项目的历史,不是关于预注册效果的研究。
- 明确不作论断:那个实例没有经过换模型族的独立审查。它演示了这套纪律,不代表这套 纪律已获它认证。
- 诚实的底线:产出这些规则的那次评测,确实是按预注册的方法做的——最后还是撤回了。 两次最终裁决都是 BLOCKED,而审查是被人为叫停的,不是因为通过了。叫停审查不等于批准。 预注册限制了一个错误结论能走多远。它没让那个结论变对。
局限
一个项目,五轮,没有对照组。规则 1 和 6 预设你有一个未必有的第二评审者和第二执行者;规则 2 到 5 一个人也能做。而六条全过,换来的是一个站得住的方法,不是一个有用的结果——我们那个 就站得住,照样被砍了。
把资产拿走
| 资产 | 它是什么 |
|---|---|
| 方法模板 | 那十个冻结小节,连同最容易漏掉的那几条条款 |
| 飞行前检查清单 | 第一次测量之前要过的 18 道二元闸门 |
| 偏离日志模板 | 只追加的格式,以及让它可信的「跑测前/跑测中/跑测后」区分 |
下一个动作
拿上方法模板,把第 3 节填了——固定输入和样本量——填给下一次你本来打算随手跑掉的评测。 然后给第 1 到第 10 节取哈希,在开始之前把哈希粘进你的跑测日志。就这一条命令,决定了 你手上是一个你遵循过的方法,还是一个你能证明自己遵循过的方法。
来源
EleutherAI
lm-evaluation-harness — a versioned harness for reproducible LM evaluationgithub.com · 核查于 2026-09-09