跳到主要内容
pass@1 不写回合预算,那个排名顺序就是假的

pass@1 不写回合预算,那个排名顺序就是假的

P99
P99

· 阅读约 8 分钟

UserSWE(arXiv:2610.29822,v1 上个月 21 号 14:46 UTC 挂出来)里有张表,我看了两遍才确认自己没读错:

允许的交互回合解出任务最多的 agent
1Claude Fable 5.1
中间若干Claude Opus 5
8GPT-6-Astra

同一批题,同一批 agent,同一套测试,只改动“允许问几句”这一个变量,榜首就变了三次。这张表要是只截一行贴出来,三个 agent 的粉丝都能各自宣布胜利,而且都没说错——他们只是各自选了不同的横坐标。

测试范围先说清楚:这篇的跑测我复现不了。11 个 agent、72 道题、42 个仓库,每道题每个回合都要起一遍测试环境,这基建我手上没有。我能做的是拿它的结论回去量我自己那张表——表里有一列叫 pass@1,跑了 N 次、记了环境、标了模型版本和日期,一直自认为口径干净。

现在我认为这一列的名字是错的。

它测的不是“这个 agent 能不能解这道题”,是“这个 agent 能不能在一次性拿到全部信息的前提下解这道题”。单轮任务上这两个量完全重合,真实 issue 上不重合。真实 issue 的第一段大概率缺东西,缺的那部分不在题面里,在你追问之后用户回的第二句话里。所以 pass@1 天生有个天花板,而这个天花板不是模型能力定的,是题面信息量定的。我表里 60% 到 70% 那一段,多少是被题面卡住的、多少是模型真不会,我分不出来。这不是多跑几次能解决的——跑一万次还在同一个天花板底下,只会把那个天花板的估计精度做高一点。

论文里有句话我同意得不能再同意:单轮评测同时产生假阳性和假阴性,放过错的补丁,也拒掉对的补丁。假阳性那一半大家都在骂,假阴性那一半更阴——一个得问清楚才能改对的 agent,在单轮里被记成失败,其实它只缺一句信息。我用那列 pass@1 给人推荐过工具。现在回头看,可能拒掉过本来没毛病的东西。

这才是这篇让我不舒服的地方。它没反驳我的数字,它说的是我的数字在回答另一个问题。

题是怎么造的,值得单说。

管线把仓库历史和已有的单轮 benchmark 转成多轮任务。关键不在“转成多轮”,在那个 information pool:每个回合规定模拟用户只允许透露哪些信息。这条是整个 benchmark 成不成立的分界线。把它拿掉,模拟用户第一个回合就把 issue 全文贴出来,你就得到一个套着多轮外壳的单轮 benchmark——跑满八个回合,实际测的还是第一个回合。这种事我自己干过:早期脚本里所谓的多轮,就是把同一个 prompt 分两次发,中间塞一句“你继续”。那不叫多轮,那叫分段。分段的收益和追问的收益根本不是一个东西,前者是上下文切碎了重发,后者是新信息进来了。

另一个轴是 persona 链,采样自一个在 20,859 条真实开发会话上标定过的转移模型。这两个轴经常被混着说。池子管能说什么,persona 管怎么说。池子是设计出来的,persona 是标定的;前者决定难度上限,后者决定它像不像人。我看到有人转这篇的时候写“用真实用户模拟”——只对了一半,措辞分布是标定的,披露节奏是人为设的。把这两件事说成一件事,就等于把 benchmark 的难度曲线当成真实用户的难度曲线,而这两条线的斜率不会一样。

判决机制那段我停留了一会儿。每回合跑测试,一对来自不同模型家族的 agent 分别写判决和把关,测试结果作主证据,模型判断只用在测试判不了的地方。

这个主次顺序比它看起来重要。我见过不少 harness 是反过来的:先让模型看一眼 diff 说“这看着像修好了”,测试留到最后跑一次。单轮上这么干勉强能用,多轮上等于把每个中间回合的证据全丢了——而多轮任务的价值恰恰在中间回合。它在第 3 回合改错了一个文件,第 4 回合该不该回滚,这个决策没有 per-turn 的执行结果根本判不了。跨家族那部分:同家族自写自判有已知的自偏好,跨家族消不掉偏好,但能让两个方向的偏好互相顶着,至少不是系统性偏向一边。工程脏活,不值得单独夸,很多 benchmark 连这个都懒得做。真正决定分数的其实是“只用在测试判不了的地方”这半句的执行严格程度,比选哪个模型当判决员影响大。

下面这段是冷水。

72 道题,42 个仓库。72/42 ≈ 1.71,也就是有一批仓库贡献了两到三道题。同一个仓库出来的题共享代码结构、共享测试基建、共享命名习惯和那套历史遗留的怪癖——按仓库聚类之后,有效样本量夹在 42 和 72 之间,离 72 那头更远。

按 72 个独立样本估:50% 左右的通过率,标准误 sqrt(0.25/72) ≈ 5.9 个百分点;换成更接近实际的 30%,5.4 个百分点。两个 agent 之间差三道题,3/72 = 4.2 个百分点,还在一个标准差以内。按 42 个簇算,还得再宽一圈。这还没算每题的重跑波动。我在自己表上犯过同一类错:把同仓库的多个任务当独立样本算方差,算出来的区间比实际窄,窄得还挺好看。

所以“第八回合 GPT-6-Astra 反超”这句话,如果差距就是三五道题,我不认。我最想在那篇里看到的一栏是每个格子的重复次数,以及重跑之后名次翻盘的频率——这个数直接决定那张排名表能信几分。在附录里我没找到。要是我漏看了,算我的;如果确实没有,那张表只能当方向看。⚠️

不过这里我要推翻自己前半句。

名次互换一两位我确实不认,但“名次随回合预算变化”这个现象本身,我倾向于是真的。理由不是哪个检验,是三样东西凑在一起:它是单调的,预算加,需要多轮才收敛的 agent 往上走;它跨 11 个 agent 都成立,不是一对一的偶然;而且它有机制——有些 agent 第一回合拿到题就直接动手改文件,有些要等看到测试红了才动,这两种策略的收益曲线在不同预算下本来就不一样。机制、单调、跨对象凑齐的时候,比一对一的差值可信得多。

所以判断得切两半:现象信,具体名次不信。这两半差得很远,混着说就是耍流氓。

对我实际的影响是:那张表想加一列“允许追问次数”。

加不上。表里那些任务是单轮构造的,题面就是全部信息,追问没东西可问——你问“能再具体点吗”,对面没有东西能给你。要加这一列,得回去从 issue 历史里重造任务,把“第一次描述里缺什么、第几回合补上的”逐条标出来。这才是这类 benchmark 的真实成本:不是跑八个回合的算力,是造题的人工。造题的边际成本压不下来,回合数这个维度就永远只能靠别人替你做。

算力那笔我粗估过:11 个 agent × 72 道题 × 8 个回合 = 6,336 次 rollout,每次都要起一遍测试环境,还要双 agent 写判决和把关。按我这边容器冷启动 P50 十几秒算,光把环境拉起来就一天多。这笔我能算,而且这还只是拉起环境,不含推理。造题那笔我算不了,我没造过这个规模的东西。

还有一笔我没测:多轮到第八回合,context 累积,单价不是线性的。同一道题,第 1 回合的 token 账单和第 8 回合差几倍——这个数决定“多轮能力”在真实产品里值不值那个钱。这轮没测,先记在这,下次把账单按回合拆开记。

置信标签按条给:

单轮通过率不能代表交互能力——高置信。不需要更多样本,这是定义层面的问题:题面信息量封顶,跑多少次都封在那儿。

名次会随回合预算重排——方向大致对,样本还不够。机制清楚,跨 11 个 agent 成立,但具体谁在第八回合排第一,72 道题、42 个簇撑不起这个精度。

某个具体 agent 是不是“擅长多轮”——证据不够,先别信。这个标签要成立,得看它在多个预算下的整条曲线,不是在两个点上比大小。

回到标题那句:你的 pass@1,截在第几回合。

如果答案是“没想过”,那你贴出来的那个排名,看的人和你一样,不知道自己在看什么。我那张表这段时间先不动,等我想明白怎么给单轮题面标一个“信息完整度”再说。

谁在自己的表里加了回合预算这一维,或者拿这篇的任务集重跑过,数字对不上,告诉我。