基准背后的基准
基准是一个数据集和一个评判者。评判者听起来像是个细节,但它才是最难的部分。
一个基准测试包含两部分:任务,以及判定你是否成功的评审。所有人都把评审当作事后才考虑的东西,但它决定了你发布的每一个数字,而一个薄弱的评审会让整个测试变得容易被奖励作弊。
所以我们花了很长时间来构建自己的评审。一个对齐的评审必须在四个方面保持一致:
- 同一轨迹两次。重新评审一次已完成的运行,得到相同的分数。
- 跨任务。任务 90 与任务 3 适用同样的标准。
- 跨模型和框架。Browser Use 和 Codex 以相同的方式评分。
- 在运行层面。如果模型 A 胜过模型 B,重新评审时这个结果不应该翻转。
这些都不是免费的。先从分数中有多少是真实的开始。
是什么影响分数
两件事。其中只有一件是模型。
智能体噪声来自网络和模型。某个网站封禁了你。第 12 步走错了路。你会测量到它。你无法消除它。
评审噪声是同一次已完成的运行,评审两次,却得出两个不同的结论。这个我们能消灭。
智能体噪声
我们在同样的 106 个任务上运行了 GPT-5.5 五次。相同的模型。相同的框架。相同的配置。
每次运行大约解决 89 个。但从来不是同样的 89 个。
每一列是一个任务。每一行是一次运行。绿色表示成功。
64 个任务每次都成功。2 个从不成功。中间的 40 个就是全部问题所在。相同的模型,相同的任务,随机地通过和失败。一个误读的过滤器。一次错误的点击。提前一步放弃。
运行一次你得 85%。给它五次尝试,106 个任务中有 104 个至少成功过一次。
所以单次运行衡量的不是模型能做什么。它衡量的是模型做这件事的频率。
评审噪声
现在固定智能体。我们从那组数据中取了 104 次已完成的运行——那些我们有人工标注的——只改变了做评分的模型。
同样的思路:每一列是一个任务,每一行是一个评审,全部在阅读完全相同的工作。
基准测试中 45% 的结果取决于你问的是哪个评审。最宽松的报告 83.7%,最严格的报告 62.5%。二十一个百分点,比人们比较的大多数模型之间的差距还要大。
如果评审对分数的影响比模型还大,你就无法判断某个改动是否真的有帮助。
构建评审
一个包含完整轨迹的提示词
第一个评审是一次单独的 LLM 调用。完整轨迹输入,结论输出。
用一个框架时还行。然后我们加入了更多框架。轨迹看起来完全不同,运行数百步,而压缩会吃掉你需要的部分。
证据只有一处,且被埋没
任务:提取 2,000 美元以下的房源。在第 34 步,智能体把过滤器设成了 20,000 美元。之后的一切都干净、自信,而且是错的。
你无法把这些塞进一个提示词里。而单次遍历只有一次发现它的机会。
于是评审变成了一个智能体。它获得轨迹和工作区,然后去搜寻,就像拥有读取权限的 Codex 或 Claude Code。它可以打开 CSV,回滚到第 34 步,对照该数字来源的页面进行核对。
评审能看到什么
智能体评审只能验证它能打开的东西。但这很容易被破坏。截图很占体积。页面文本很占体积。有些东西会被截断以适应预算。
如果剪掉了错误的内容,一个真实的主张就会变得无法验证,而在评审看来这与凭空捏造的毫无区别。它开始把正确答案称为幻觉。在你动提示词之前,先把证据契约定好。
我们为何不再要求通过/不通过
评审必须给出某种输出,通过或不通过是最显而易见的选择。但它也是错误的选择,因为大多数任务并非二元的。
真实提示是模糊的。查看其中一位顶级贡献者。 打开热门谜题。 没有人能验证哪一个才是正确的,包括评审本身。而且智能体的失败是部分性的:要求 JSON,得到的却是包含所有正确数据的 CSV。在 400 步正确之后,这不该算零分。
我们数据集中的一个例子:
前往 spaces 并导航到其中一个推荐的 spaces 进行查看。查看该 space 中一位顶级贡献者的个人资料,并返回其拥有多少关注者。
智能体核实了 227 名关注者。但推荐 spaces 页面需要登录,所以它使用了一个公开可访问的 Space 代替。
我们的十一位评审中有五位判定通过,六位判定不通过。 截图相同,关注者数量相同。分歧在于替换的 Space 是否算数。
所以它不是 0 或 1。称之为 60 分。你可以主张 45 分,而这个主张正是重点:分数并没有消除判断,而是把它放在一个你能看到的地方。
所以我们改为要求一个数字:所请求的结果在多大程度上被交付,且正确并有证据支持。这是同一位评审在相同轨迹上运行四次的结果,唯一改变的是一个本不该影响答案的设置。
20 分与半分之差。 二元评审并非更错误,它只是放大了差异。每个边缘任务都是一次抛硬币,而每次抛硬币在最终分数中都变成了一个完整的任务。
集成
另一个杠杆:多次运行评审并合并答案。
它之所以有效,是因为评审的噪声是随机的。每次运行都是真实分数加上某个误差,而这些误差彼此不一致,所以把多次结果放在一起就能抵消掉大部分误差。对于 个独立评审,每个方差为 :
三位评审将波动范围缩小 ,五位缩小 。
在实践中你会得到略低于此的收益。在重复运行中测量,我们整个运行的数字移动约一分。
如何合并它们很重要
取平均看似正确,实则不然。发现一个隐藏的缺陷是一次搜索,所以有时一位评审挖到了正确的文件并带回 10 分,而另外两位停留在 96 分。这个单一的离群值将平均分拉低 30 分。
中位数能经受住这种情况。但它也会丢弃那位孤军奋战的评审正确的情况,而且它无法区分这两种情况。
我们尝试修复这个问题。当三个分数相差甚远时,将所有三份审计发送给第四个模型,让它决定谁是对的。
死胡同。 仲裁者是另一个 LLM,所以它在不同运行中给出不同答案。我们用一个不稳定的裁决取代了稳定的中位数,最终数字比之前波动更大。
所以我们放弃了孤例的情况。我们会漏掉几个真实的 bug,但数字不再波动。
支线任务:大学是怎么做的
批改一摞试卷是同样的问题。没人希望两个助教给同一份试卷打出天差地别的分数,所以他们不会让每个助教从头开始自行决定。他们有一份评分标准:完整证明得 50 分,而真正困难的那一步值 40 分,即使你只完成了十分之一。
我们对失败模式做同样的事情。在不同模型上运行任务二十次,收集它出错的每一种方式,并把这份清单交给评审。我们有 5,692 个这样的条目。
不过,它只覆盖你已经见过的情况。当某个智能体第一次完全跳过浏览器、直接逆向工程网站的 API 时,没有对应的行可记录,评判者又只能靠猜了。
模型对比
每个任务你都有一个分数。把分数转化为“A 胜过 B”有三种方法,按顺序越来越好。
阈值与计数
选一个切分点,把高于它的都算作通过,然后加总。几乎所有基准测试报告的都是这个。
它把分数刚刚告诉你的所有信息都扔掉了。从任何实际用途来看,52 分和 48 分是同一次运行,但它们最终落在了切分点的两侧。你又回到了之前的放大问题。
逐任务比较
把两个模型放在同一个任务上对齐,判定谁赢了那一个任务,然后计数。对于分数,你在中间留出一个 5 分宽的平局带,这样小差距就不算结果。
每一行都是两个模型都尝试过的同一个任务。这一对数据早于连续评判者,所以判定结果是通过/失败,平局意味着两者做了同样的事。
这比“84 对 78”更有用:两个模型基本一致,而 Opus 在十四个具体任务上领先,你可以去查看。
配对还能消除大部分噪声,因为两个模型面对的是同一个任务:
计数胜场也把分差扔掉了。那也是一种阈值,而我刚刚抨击过阈值。区别在于:在任务层面,幅度是信号,而在这里它通常是伪影。
它会改变答案。Opus 在 44 个任务上以 12.3 分之差击败 Grok,Grok 在 28 个任务上以 26.7 分之差击败 Opus。按 算,Grok 获胜。按胜场数算,Opus 以 56.6 对 43.4 取胜。我们相信 Opus:在一个任务上出现 90 分的差距,几乎总是评判者出了问题。
Elo
一次比较两个模型无法扩展到二十个,而且并非每个模型都运行过每个数据集。
所以把每个任务当作一局游戏。如果 A 比 B 得分高 5 分,就算 A 胜,差距在 5 分以内算平。5 分大致是同一个评判者在同一任务上的波动幅度,所以任何更小的差距都是噪声。六个配置下的 106 个任务产生 1,590 场对局。
前四名彼此相差在 56 分以内。这个差距足够小,我不会称之为排名。
真正重要的差距是:低努力度的 Opus 5 比高努力度的 Opus 5 低 88 分。调高推理强度对模型的提升,比更换供应商更大。
Elo 聚合的是你已有的判断。它无法修复这些判断。
这把我们带到了哪里
报告智能体的噪声。运行多次并展示 best-of-N。
评判者的噪声是可以真正消除的。把每一份证据都给评判者,要求给出分数而不是结论,运行三次,取中位数。这会让它变得一致,而不是正确,而一致正是你可以测量的部分。
并且把评判者和数据集一起发布。公开的网络智能体基准测试评分方式差异很大,从脚本到人类再到 LLM 评判者都有。
一旦它稳定下来,你就能得到这样的图表:
同样的 106 个任务,每个模型都以相同方式评判。Luna xhigh 以十六分之一的成本落后 Opus 5 两个任务。这个对比之所以有意义,是因为评判者在两者之间没有变化。
该图表上的每个模型都运行在 Browser Use Cloud 上,如果你想把它们指向你自己的任务。
TL;DR
只更换评判者,同样的运行就会得到 62.5% 或 83.7% 的分数。把整个工作区都给它,要求给出分数而不是结论,运行三次,取中位数。