CodexQA

Industry & PracticeResearch & Benchmarks

规范没有说出的东西:测试在要求规范没写的名字

CodexQA 团队44 min read

Fei Ding 审计 SWE-Milestone:98 个被评分里程碑里有 25 个,测试依赖规范没写、也无法推断的名字或路径。带这种缺口的构建单元失败率 80.6%,可比单元是 48.4%。排行榜名次几乎不动,但 go-zero 的分数会移动。

In this piece

规范没有说出的东西:以测试评分的编码智能体基准中的规范–预言机缺口

Fei Ding

脚注:通信作者:dignfei@gmail.com。单位:Alibaba Group。

摘要 编码智能体基准常常用自然语言描述一项任务,却用取自上游项目的测试来打分。要通过这些测试,可能需要描述里从未说明的信息——某个常量的名字、一条模块路径、一句精确的消息。我们把这称为规范–预言机缺口:一旦存在这种缺口,基准也在衡量智能体是否复现了上游的实现细节。我们把这一缺口形式化,包括相互依赖的任务链所增加的不一致,并为一共五种语言建立静态审计,对每一项被计分测试的每一个名字级、路径级和字面量级依赖进行分类(留出集上的精度为 89.2%,召回率为 92.9%)。在 SWE-Milestone 上(98 个被评分的里程碑,35 次已发布运行),有 25 个里程碑包含这样一项测试:它依赖一个未被说明、也无法推断的名字或路径。带有这种依赖的构建单元在 80.6% 的运行中失败,而没有这种依赖的可比单元为 48.4%;从参照实现中扣掉一个隐藏名字,就会使该单元的测试在 128 例中的 126 例无法编译。排行榜的名次对去掉受影响测试是稳健的,但这些测试会改变仓库内部的分数,并偏向那些复现上游名字的智能体。再看另外四个基准,普遍程度似乎跟着构造方式走:规范是发布说明或大语言模型摘要时,三分之一或更多的任务受到影响;任务经过筛选、或是为测试而写时,几乎没有;一个缺口要付出多大代价,取决于评分工具如何打分。我们发布了该审计、修正后的过滤清单,以及规范附录。

1 引言

面向大语言模型编码智能体的基准,已经从孤立的议题(Jimenez et al., 2024)走向长程的软件演化:智能体带着同一份代码库,走过一串相互依赖的变更(Deng et al., 2026; Le et al., 2025; Chen et al., 2026)。这样的基准是现实的,而且可以自动挖掘:一条流水线把项目的提交分成里程碑,为每个里程碑写一份自然语言规范,并复用项目自己的测试作为预言机。

这种构造把两种不同的人工制品接在一起。规范描述行为;预言机是代码,它调用辅助函数、引用常量、在固定路径上导入模块,并比较精确的消息。凡是预言机所依赖、而规范没有说明的东西,智能体都可能正确地实现了被规定的行为,却仍然因为命名、放置或措辞不同而失败。我们把这种错配称为规范–预言机缺口。缺口存在时,基准不再只衡量智能体是否实现了被要求实现的东西;它也衡量智能体是否复现了上游的实现细节。

单任务基准已经知道这个问题的一个版本:SWE-bench Verified(OpenAI, 2024)去掉了那些测试在检查议题里并不存在的细节的任务。长程基准把这个问题提得更尖锐。一个缺失的名字通常会使整个构建单元失败——也就是被一起编译或一起加载的那一组测试,例如一个 Go 包、一个 Rust 测试目标、一个 Maven 模块——而不是单独一项测试;它会在后来每一个使用它的里程碑里再次出现;而且当一个里程碑的参照测试依赖另一个里程碑的代码时,里程碑链还会加上它自己的缺口。

我们要问的是:这些缺口在实践中有多大,它们是否真的改变智能体的结果,以及它们对从基准得出的结论做了什么。我们的贡献是:• 给里程碑基准中的规范–预言机缺口下一个定义,其分类把规格不足(未说明、不可推断)与链条不一致(没有任何智能体能够通过)分开,并给出它们爆炸半径的模型;• 面向 Go、Python、Rust、TypeScript 和 Java 的静态审计,对每一项必需测试的每一个名字级、路径级和字面量级依赖进行分类,在一份根据公开文件标注的留出样本上得到验证(精度 89.2%,召回率 92.9%),并且在数分钟内跑完,不调用模型;• 对 SWE-Milestone v1.0.2(Deng et al., 2026)及其覆盖 27 个模型的 35 次已发布运行的研究:缺口影响 98 个里程碑中的 25 个;有缺口的单元失败次数是可比单元的 1.67 倍,对参照实现所做的反事实确认了所预测的爆炸半径;去掉受影响的测试之后,排行榜名次仍落在同等规模随机删除所能产生的范围之内,但在受影响最重的仓库内部,分数发生移动;智能体对隐藏名字的复现是模型的稳定特征,与其训练截止日期无关;• 与另外四个以其他方式建造的基准(SWE-EVO、SWE-Chain、SWE-bench Verified、DeepSWE)的比较,只使用公开数据:普遍程度跟着任务文本如何写成走,而评分工具决定一个缺口要付出多少代价;• 该基准的修正过滤清单和规范附录,以及对建造以测试评分的基准的建议。我们的深入主张只涉及一个包含七个仓库的基准;与另外四个基准的比较表明,这一审计可以迁移,而且普遍程度取决于构造方式。

2 背景:SWE-Milestone

SWE-Milestone(Deng et al., 2026)把一段仓库发布历史重构成里程碑的有向无环图,里程碑是功能上连贯的上游提交组。版本 1.0.2 覆盖五种语言的七个仓库:go-zero(Go)、navidrome(Go 与 TypeScript)、nushell 与 ripgrep(Rust)、scikit-learn(Python)、element-web(TypeScript)以及 dubbo(Java)。在用于其排行榜的端到端模式中,智能体从一个试验基线出发——该范围内的第一个发布,加上一小块让环境能够构建的补丁——并在同一棵工作树里实现全部里程碑,在前置条件已经完成的里程碑之间自己选择顺序。对每个里程碑,它收到一份软件需求规范(SRS),由一条大语言模型流水线根据该里程碑的提交生成。

评分基于测试。对每个里程碑,评分工具取该里程碑结束时的上游(gold)状态,把它的测试代码复制到智能体的代码上,并运行测试套件。测试按其在里程碑前后的 gold 状态上、经重复运行后的结果来分类:fail-to-pass 与 none-to-pass 测试(之前失败或原本不存在,之后通过)是该里程碑必须交付的新行为;pass-to-pass 测试必须继续通过;之前通过但之后不再运行的测试(pass-to-none)不计分。按里程碑给出的过滤清单去掉维护者认定无效的测试。这些合在一起就是必需测试。对每个里程碑,召回率是通过的必需新测试所占份额,精度是 $(f+1)/(f+b+1)$,其中 $f$ 是通过的新测试数,$b$ 是被弄坏的 pass-to-pass 测试数,而分数是二者的 F1;当全部必需测试都通过时,一个里程碑被解决。排行榜先在每个仓库被评分的里程碑上对二者取平均,再在仓库之间取平均;已发布的最佳配置在 98 个被评分里程碑上达到 29.75% 的解决率。

3 动机示例

规范要求行为测试却要名字

图 1:行为被规定了,名字却被要求。断掉的桥代表一个未被说明的接口:go-zero 的 M019 要求 SSE 行为,但它的参照测试要求 valueSSE 和 headerAccept。缺任何一个名字,都会在测试执行之前堵住整个 rest/handler 包;这一依赖在另外五个里程碑中再次出现。测试方块和里程碑连线是示意。

图 1 说明一个隐藏名字如何堵住整个构建单元,并跨里程碑反复出现。go-zero 的里程碑 M019 增加 Server-Sent Events 支持。它的 SRS 精确陈述了行为:“通过检查 Accept: text/event-stream 头来检测 SSE 请求”,并绕过超时处理器。它没有陈述参照实现为这一行为引入的名字 headerAccept 和 valueSSE,但 rest/handler 包的参照测试两者都用。因为 Go 把一个包的测试放在一起编译,一个行为实现正确、但给常量起了不同名字的智能体,会失去该包的每一项必需测试:M019 中是 84 项,在继承这些测试的另外五个里程碑中,每个是 88 到 108 项。已发布的运行表明利害所在。这些运行在 M019 上的源码快照显示各自写了什么:34 次运行中有 32 次(脚注 1:计数基于 35 次运行中的 34 次。有一次运行的发布名称标明它接触过泄漏信息,此处以及第 6.6 节将其排除。)实现了规范所要求的绕过。其中还有九次把该值命名为 valueSSE,这九次里有四次通过了全部 84 项必需测试(另外五次还缺另一个名字)。其余 23 次用了不同的名字(17 次是 valueEventStream,2 次是 valueTextEventStream,1 次是 valueSse),或者把字符串直接写在行内,并且一项都没通过;其中 13 次的评测日志报告,该包里除了 valueSSE 和 headerAccept 之外没有未定义的名字。这类差异在汇总分数里看不见,却决定了单次运行之间的比较。

4 规范–预言机缺口

4.1 定义

一项以测试评分的编码任务 $t$ 给智能体一份自然语言规范 $S_{t}$ 和一份作为起点的代码库 $B_{t}$,并用一个预言机 $O_{t}$ 给结果打分,预言机是取自参照解的一组测试。每项测试 $o\in O_{t}$ 依赖一组人工制品 $D(o)$,解必须提供它们,$o$ 才能通过:它所引用的标识符(函数、类型、常量、方法、字段),它所导入或模拟的模块或文件路径,以及它用来和输出比较的字面量(消息、格式化文本)。若一件人工制品定义在 $B_{t}$ 中,或在 $S_{t}$ 中被点名,它就是被任务固定的;我们把这个集合写成 $F_{t}$,并加入 $B_{t}$ 里已经存在的约定所决定的人工制品(下面所说的可推断名字)。任何其他人工制品都是自由选择:换一种选择的实现同样正确。一项测试的规范–预言机缺口是 $G(o)=D(o)\setminus F_{t}.$ 若 $G(o)\neq\emptyset$,这项测试就可能使一个智能体失败:它正确地实现了被规定的行为,只是给一件人工制品起了不同的名字、放在不同的地方,或用了不同的措辞。这一定义并不专属于长程;它适用于任何把自然语言任务与参照测试配对的基准。规范留空的行为落在 $D(o)$ 和我们的审计之外。

里程碑链。在里程碑基准中,智能体在同一棵树里依次走过里程碑 $m_{1},m_{2},\dots$。对里程碑 $m$,它所能知道的是它出发时的试验基线——而不是 $m$ 的参照起始状态,那一状态已经包含其他里程碑的参照代码,而智能体是用自己的方式重新实现的——以及 $m$ 的规范,和依赖图中其祖先的规范。一份规范点名一件人工制品,是指它逐字写出,或按其词序写出(SetSSESlowThreshold $\sim$ “set SSE slow threshold”);模块路径只有在它点出文件时才算被点名。

爆炸半径。一个缺口很少只让一项测试付出代价。若 $G(o)$ 包含一个名字或一条路径,则 $o$ 所在构建单元里的每一项测试都随之失败:语言把该单元作为一个整体来编译或收集(附录 A)。若 $G(o)$ 只包含字面量,则只有 $o$ 失败。因此,面临缺口风险的测试,是它所堵住的那些单元里的测试;在第一个失败单元就会停下来的构建系统中,可能是整个里程碑。

4.2 缺口从哪里来

对 $D(o)$ 中试验基线之外的每一件人工制品,我们通过比对所有里程碑的参照状态,判定它从哪里来(表 1)。类别 A1 和 A2 是规格不足:智能体只能靠猜测或凭记忆来复现这一依赖。类别 B 是沿里程碑链的不一致。B3 是最鲜明的:参照测试引用了一个名字,而同一里程碑的 gold 结束状态并没有定义它,因此连参照实现也无法通过它;基准已经把这类测试作为 pass-to-none 从必需集合里悄悄去掉。还有一种进一步的、依赖于顺序的形式,称为顺序冲突,其产生是因为里程碑的 gold 以不兼容的方式改变共享 API(go-zero 的 M003 使 RollingWindow 成为泛型;M024 去掉 setupInterceptors):智能体先实现哪一个里程碑,就会弄坏它后来实现的那些里程碑的参照测试。

类别该依赖是
visible定义在试验基线中
specified由本里程碑或某个祖先引入,并在其 SRS 中被点名
A1由本里程碑的 gold 变更引入,其 SRS 没有点名
A2由某个祖先的 gold 变更引入,该祖先的 SRS 与本 SRS 都没有点名
B1由一个不是祖先的里程碑引入
B2由不属于任何里程碑的上游提交引入
B3该里程碑自身的 gold 结束状态没有定义

表 1:测试依赖的类别。

并非每个隐藏名字都是在黑暗中猜测。一项依赖若满足下列条件,就是可推断的,并且不计入硬缺口:(i)它把试验基线中的一个名字与代码库已经系统使用的词缀组合起来(Allow $\rightarrow$ AllowCtx,go-zero 中有 227 对这样的配对);(ii)它是规范给出了名字的新模块或新文件,并按前端代码库的约定放进已有目录,或放在已有文件旁边;(iii)它是一个方法,其签名匹配试验基线中的某个接口,或匹配规范所点名的接口。反过来,依赖也可以藏在测试的标识符里,而不是藏在它的代码里:若一项被计分测试的名字有一部分是从一个只有参照实现才定义的字符串计算出来的,那么每一个携带它的测试都依赖那个字符串。规则(ii)、(iii)以及标识符规则是在留出集抽出之前、于开发数据上固定的:(ii)编码了一种前端约定,其余规则来自对 DeepSWE 的复核。

4.3 实现

五语言静态审计流程

图 2:静态审计:五个语言提取器恢复测试依赖(TS:TypeScript),橙色月牙是 $G(o)=D(o)\setminus F_{t}$,即基线、规范和可推断约定都没有固定的那些依赖。硬的名字或路径缺口会标记被堵住的构建单元中的全部必需测试,而字面量只标记单项测试;输出是带理由的审计记录、过滤清单和规范附录。Gold 差异把规格不足(A1:当前里程碑的 gold 变更;A2:祖先的 gold 变更)与链条不一致(B1:非祖先的 gold 变更;B2:未被指派的上游提交;B3:在自身 gold 中不存在)区分开;B3 测试可能已经作为 pass-to-none 而不计分。

图 2 概括了这一静态审计。每种语言有一个提取器,报告每个状态所定义的名字、模块路径和字面量,以及每项测试所引用的那些;一个与语言无关的核心比对 gold 状态,对每项依赖分类,并把必需测试映射到构建单元(细节见附录 A)。审计在半小时以内跑完,不调用模型(RQ4)。

5 实验设置

我们研究五个问题。RQ1(普遍程度):有多少必需测试和里程碑依赖未被说明、不可推断的信息?RQ2(实际兑现):这些依赖是否造成失败?RQ3(影响):去掉受影响的测试后,分数和排名如何变化?RQ4(精度与成本):审计有多准确、有多贵?RQ5(其他基准):这一缺口是否出现在以不同方式建造的基准中?

对象与运行。SWE-Milestone v1.0.2 的全部七个仓库(98 个被评分里程碑,580,039 项必需测试),以及它的 35 次已发布端到端运行(Claude Code、Codex、Gemini CLI 和 OpenHands(Wang et al., 2025a),共 27 个模型),其逐测试结果是公开的;用评分工具自己的计分代码重放后,我们的分数与 28 次排行榜运行的差距在 0.20 分以内。有一次运行的发布名称标明它接触过泄漏信息,它保留在汇总结果中,但在我们追问各次运行复现了哪些名字时被排除。把它从所有地方都排除,不会改变任何结论(它不在那 28 次排行榜运行之中):RQ2 的倍数和优势比变成 1.66 和 4.75,全部运行上的 Kendall $\tau$(表 3)按分数为 0.979,按解决率为 0.960。

实际兑现。一个单元是一个(里程碑,构建单元)对;当它的某项必需测试失败或缺失时,它在一次运行中失败。因为带有隐藏依赖的单元,其测试是在检验新代码,我们把它们与这样的单元比较:同样带有 fail-to-pass 或 none-to-pass 测试、但没有新依赖,并且处在相同的里程碑之内;95% 区间来自对里程碑的自助法;我们还阅读每次失败的日志,看它报告缺了什么;对 Go,我们还把参照实现中的一个隐藏名字改名后重新构建,看预测的单元是否被弄坏。

重新计分去掉(a)被硬隐藏依赖堵住的单元中的测试,以及(b)参照实现缺少某个名字、且没有任何环境补丁提供该名字的测试(保守);在完整变体中还去掉(c)没有任何运行通过、且其原因已被解释的测试(附录 D);我们用评分工具重算指标,用 Kendall $\tau$ -b 比较排名,对里程碑做自助法,并与从规模匹配、随机选出的单元中去掉同样多测试的做法相比较。

其他基准。SWE-EVO(Le et al., 2025)和 SWE-Chain(Lam et al., 2026)(发布级任务)、SWE-bench Verified(OpenAI, 2024)以及 DeepSWE 1.1(Huang et al., 2026)。映射是直接的:$S$ 是智能体看到的任务文本,$B$ 是基线提交处的仓库,gold 变更是参照补丁,预言机是被计分的测试。对于实际兑现,我们只使用公开结果:SWE-Chain 九个系统的逐步结果、官方实验仓库中解决率至少为 60% 的 78 份 SWE-bench Verified 提交的逐实例结果,以及 DeepSWE 已发布的试验。

6 结果

6.1 RQ1:普遍程度

仓库M必需隐藏面临风险的测试 %硬 M
go-zero (Go)2343,2531327.115/23
navidrome (Go+TS)913,64220.32/9
element-web (TS)1894,11470.17/18
nushell (Rust)1367,50400.00/13
dubbo (Java)1282,86310.01/12
ripgrep (Rust)1111,96400.00/11
scikit-learn (Py)12266,69900.00/12
All98580,0391420.625/98

表 2:被评分里程碑(M)上的隐藏依赖,语言写在括号里。隐藏:硬隐藏名字(SRS 没有点名,试验基线中不存在,不可推断),按里程碑求和;面临风险的测试:它们所堵住的单元中的必需测试,或带有隐藏字面量或测试级名字的必需测试,所占份额;硬 M:至少有一项硬隐藏依赖的里程碑。

表 2 概括了审计。98 个被评分里程碑中有 25 个包含一项带硬隐藏依赖的必需测试;因为一个里程碑只有在它的全部必需测试都通过时才算被解决,一个碰巧没有复现这些隐藏项的智能体就无法解决它们。面临风险的测试总体上很少(必需测试的 0.6%),但很集中:在 go-zero 中,测试会触到包的内部,23 个里程碑里有 15 个受影响,必需测试的 7.1% 位于被堵住的单元中;接下来是 element-web(18 个中的 7 个)、navidrome(9 个中的 2 个)和 dubbo(12 个中的 1 个),而那些测试驱动的是公开接口的仓库(scikit-learn、ripgrep)以及 nushell 则一个也没有。大多数硬项是 A2:某个祖先里程碑引入了名字,其规范却没有说明,而后来里程碑的测试依赖它们。第 4 节中把按约定放置的路径视为可推断、并阅读全部祖先规范的那些规则,把计数从 34 个里程碑降到 25 个。

爆炸半径解释了为什么少数名字会有影响。在 go-zero 中,两个常量 headerAccept 和 valueSSE 在六个里程碑里堵住 rest/handler 包,每个里程碑有 84 到 108 项必需测试(第 3 节)。

链条不一致是第二个、独立的来源。没有任何已发布运行构建出 nushell 的里程碑 G05_be6e868:它的参照测试在初始化一个结构体时没有字段 custom_completion,而里程碑 G01_48bca0a 会加上这个字段,因此先实现了 G01_48bca0a 的 19 次运行无法编译它们,其余运行则停在同一批测试的其他构建错误上。go-zero 的 M017 的参照测试使用了 M017 自己的 gold 状态并未定义的名字(例如 maxFormParamCount),因此连参照实现也无法编译它们;基准把这类测试悄悄记成 pass-to-none,并从必需集合中去掉(附录 H)。

6.2 RQ2:实际兑现

隐藏依赖与失败相关联,尽管没有朴素比较所暗示的那么强。在 35 次运行中,被硬隐藏依赖堵住的单元在 80.6% 的(单元,运行)对里失败,所有其他单元为 15.1%,但大多数未被标记的单元只持有 pass-to-pass 测试,智能体只要什么都不弄坏就能通过。在相同的里程碑之内,带有新测试、却没有任何新依赖的单元有 48.4% 失败,其新名字被规范说明了的单元有 52.2% 失败;被堵住的单元失败次数是前者的 1.67 倍(95% 置信区间 1.32–2.04),而被说明的名字没有造成差别(1.08,置信区间 0.83–1.41)。这一对照在运行之间的依赖下仍然成立:以单元大小和仓库为协变量的逻辑回归给出优势比 4.64(95% 置信区间 2.92–7.37,误差按里程碑和模型家族聚类,附录 B;当将近一半的比较单元失败时,优势比会超过比率比),而被堵住的单元失败次数是同一仓库、同一规模的新测试单元的 1.55 倍(置信区间 1.40–1.72)。日志是一致的:在被堵住单元的失败中,有 27.1% 的情况下,隐藏项是该次运行日志所报告的唯一缺失名字,另有 13.6% 的情况下它们位列其中;其余大多数根本没有报告任何名字。

反事实把机制单独抽出来,而不使用智能体。在参照解的非测试代码里给一个隐藏标识符改名——这对应一个用另一个名字实现了该行为的智能体——在 128 个 Go 案例中的 126 个里,使该单元的测试无法编译,而随后失败的测试是审计所预测的那些的 99.5%。

6.3 RQ3:对分数和排名的影响

变体运行$\bar{\Delta}$ S$\bar{\Delta}$ R$\Delta$ R_max_$\tau_{S}$$\tau_{R}$移动最大
Full35+0.83+0.51+2.780.9800.960112
28+0.84+0.47+2.780.9840.94252
Cons.35+0.37+0.33+2.040.9870.97981
28+0.39+0.30+2.040.9950.97221

表 3:去掉隐藏依赖测试之后的重新计分。S:分数(宏 F1),R:解决率(%);相对于用 v1.0.2 清单给同一次运行计分的平均变化,以点数计,$\Delta$ R_max_ 是最大的变化;$\tau_{S}$、$\tau_{R}$:与原始排名的 Kendall $\tau_{b}$,分别按分数和按解决率;移动:分数名次发生变化的运行次数;最大:最大的名次变化。完整变体豁免(a)隐藏依赖单元、(b)参照实现缺少某个名字的测试(v1.0.2 中没有)以及(c)已解释的全部失败测试;保守变体只豁免(a)和(b)。

去掉受影响的测试,绝对数字只移动一点,排名几乎不动(表 3)。在完整变体中,28 次排行榜运行平均获得 +0.84 分(从 -0.26 到 +2.89),解决率 +0.47 点(最高到 +2.78)。与已发布排名的 Kendall $\tau$ -b,按分数为 0.984,按解决率为 0.942。在全部 35 次运行上(0.980 和 0.960),这些变化落在偶然所能产生的范围之内:从规模匹配、随机选出的单元中去掉同样多的测试,得到的中位 $\tau$ 按分数为 0.990,按解决率为 0.980;低到真实值那么低的 $\tau$,在随机抽取中按分数出现 24.9%,按解决率出现 9.5%。若随机单元还在仓库、里程碑、单元类型和基线失败率上匹配,则分别为 13.3% 和 52.8%。排行榜自己的分辨率才是更紧的限制:对里程碑做自助法,35 次运行中全部 34 对相邻运行的 95% 名次区间都重叠,因此无论有没有这一修正,该基准都分不开相邻者。

缺口在它集中的地方才重要。在 go-zero 上,35 次运行的平均分数从 38.33 升到 42.08,平均解决率从 4.35% 升到 5.71%,报告逐仓库结果、或在单个仓库上做消融的研究都会继承这一效应。这一效应也可能部分是模型的属性:同一模型在不同配置下的两次运行,对它们写出哪些隐藏名字的一致程度,中位 Cohen $\kappa$ 为 0.81(8 对),而不同模型的运行之间为 0.63(553 对)。相同模型的配对如此之少,差异并不显著,因此这是探索性的(附录 C)。

6.4 RQ4:精度与成本

我们在从公开数据中抽样的(里程碑,构建单元)案例上做验证,每个仓库分三层——审计标记的单元、在某次已发布运行中整体失败的未标记单元(遗漏会在这里显现),以及大多通过的未标记单元——并且只根据规范、参照变更和测试来标注。第一组 111 个案例暴露了实现错误(没有阅读祖先规范、字面量没有归一化);修正之后,我们抽出第二组不相交的 94 个案例,然后是全部剩余的 48 个被标记单元加上 55 个未标记单元(103 个案例),由一名受雇的软件专家在比对之前盲标。在这两轮留出中的 65 个被标记单元上,审计的精度为 58/65(89.2%;95% Wilson 区间 79.4–94.7%);在第二组上,召回率为 13/14(92.9%;68.5–98.7%)。作者之一独立标注了同样的案例(Cohen $\kappa$ 为 0.92 和 0.96;94 例中 92 例一致,103 例中 101 例一致);相对于作者的标签,精度为 56/65。它的七个假阳性是规范暗示了、却没有直接说出的依赖——按约定命名或放置的模块、它说被移动了的包、由它所点名的协议固定的方法——以及一个藏在 Markdown 转义后面的标识符;看到这些集合之后,我们没有为此再加规则。相对于智能体行为,精度按设计会更低:一个标记意味着规范扣下了一项依赖,而不是每个智能体都会失败(第 6.6 节)。从冷缓存对七个仓库做一次完整审计,在一台 16 核工作站上用 28.1 分钟,内存至多 1,333 MiB,且不调用模型;重复运行给出相同结果。

6.5 RQ5:其他基准

基准规范被标记精度倍数
SWE-MilestoneLLM25/9858/65 (89.2%)1.67
SWE-EVOnotes17/4824/40 (60.0%)–
SWE-ChainLLM64/15528/40 (70.0%)1.12
SWE-bench Verif.issue3/5003/43.4
DeepSWEwritten7/1131/23–

表 4:审计用在五个基准上。规范:任务文本如何写成(大语言模型摘要、发布说明、经过筛选的议题、为测试而写)。被标记:带有隐藏名字、路径或字面量的任务(SWE-Milestone:硬名字或路径,另有 31 个带字面量;SWE-Chain:仅 A1);精度:被复核的标记,SWE-Milestone 按留出单元(RQ4),其他按条目,各行之间不可比(Verified:4 个条目中的 3 个,位于 3 个实例中的 2 个);倍数:失败率之比——SWE-Milestone:被堵住的构建单元相对可比单元(RQ2);SWE-Chain:被标记步骤相对未标记步骤;Verified:名字被标记的实例相对未标记实例;SWE-EVO 没有倍数(没有逐任务结果),DeepSWE 也没有(只有一个被确认)。

表 4 把未经改动的审计用到另外四个基准上(除 DeepSWE 外只有 Python)。这一比较是探索性的:复核单元和规模不同(附录 I)。普遍程度跟着构造方式走。当规范是一份发布说明(SWE-EVO),或是被要求略去“精确消息”和“内部标识符”的大语言模型摘要(SWE-Chain)时,三分之一或更多的任务依赖它没有说出的东西——说明里从未提到的一次模块拆分、一条异常消息、一个只有参照实现才命名的警告类;SWE-Chain 的链条也出现 A2 依赖,即更早一步引入、而后来的规范都没有说明的名字。当议题经过标注者筛选(SWE-bench Verified),或指令是为测试而写的(DeepSWE)时,隐藏名字几乎不存在:DeepSWE 的标记里只有一个经得起复核;其余是它的指令已经用散文给出的名字,以及测试当作输入传入的字面量。

少见,但决定性。两个被确认的 Verified 实例导入了议题从未提到的名字(get_annotation 与 infer_node;IS_PYPY),各自在收集阶段使全部 10 项或 21 项 fail-to-pass 测试失败;78 份强的公开提交里没有一份解决其中任何一个。在 DeepSWE 中,那一个缺口藏在测试标识符里:一个测试辅助函数按规则的显示名给每个案例命名,“Auto Table of Contents”,而只有参照实现定义了它,指令给出的别名是 auto-toc。这项任务在全部 113 项里通过率最低(280 次公开试验中的 2.5%,28 个模型);在 248 次带有测试报告的试验中,有 174 次这些案例跑在另一个组名之下——163 次是 “Auto TOC”——而全部 41 个被计分的标识符都算作失败。Verified 中的持续失败大多另有原因:在至多 20% 的提交能够解决的 40 个未标记实例中,我们的复核把 28 个归因于议题留空的行为,4 个归因于测试缺陷,3 个归因于审计规则之外的项,5 个归因于系统本身。

评分工具决定一个缺口是否咬人。SWE-Chain 所标记的任务份额大于 SWE-Milestone,但被标记的步骤只比其他步骤略微更常失败(倍数 1.12,95% 置信区间 1.04–1.28);它的评分工具把失败的导入隔离开,并回报给智能体(附录 F)。

6.6 被复现出来的隐藏名字

一个标记意味着规范扣下了一项依赖,而不是每个智能体都会错过它。在评测给出证据的那些硬依赖中,运行复现了 45%,可推断的依赖则复现了 79%,而且我们没有发现迹象表明,复现取决于模型的训练截止日期是否晚于上游代码(附录 G)。

7 修正后的基准与建议

修正后的过滤清单。对每个被评分的里程碑,我们扩展 v1.0.2 的过滤清单,加入这些条目,用以豁免(a)被硬隐藏依赖堵住的单元中的必需测试,以及(b)参照实现缺少某个名字、且没有任何环境补丁提供该名字的测试;完整变体还豁免(c)没有任何已发布运行通过、且审计解释了其原因的测试。这些清单通过评分工具自己的校验,可以替换基准原有的清单;它们含有 3,321 条(保守)或 3,964 条(完整)条目,每条都带理由。

规范附录。豁免测试会丢掉证据。另一种做法是告诉智能体测试需要什么。对 25 个受影响的里程碑,我们各生成一份附录,陈述参照测试所依赖的接口约定——合计 153 条——而不描述它们的实现,例如“包 rest/handler 必须声明 valueSSE(84 项必需测试依赖它)”。附录保留测试,并去掉猜测;要评测它们,需要新的智能体运行。

生成器为什么漏掉名字。SWE-Milestone 已发布的生成提示告诉模型不要过度规定实现细节,而它那一轮与测试对齐的修订可能会略去智能体能够“从代码差异里……想出来”的细节——可智能体从来看不到那份差异(附录 E)。

建议。(1)在生成规范时运行依赖审计,要么说明测试所需要的名字、路径和消息,要么排除那些伸进内部的测试。(2)沿链条以若干拓扑顺序重放参照解,并修复在任何一种顺序下失败的测试。(3)与测试无关地,在评分时隔离构建单元,使一个单元的编译失败不能抹掉整个里程碑,并把未解析的名字回报给智能体,如同 SWE-Chain 的评分工具所做的那样。(4)像 SWE-Milestone 那样发布逐测试结果;没有它们,我们的兑现分析或重新计分都不可能。

8 相关工作

编码基准的效度。SWE-bench(Jimenez et al., 2024)确立了用测试给智能体补丁打分。SWE-bench Verified(OpenAI, 2024)让标注者排除议题规格不足或测试过于具体的任务;其作者后来的一次审计发现,困难实例的一个子集中,大多数仍然有会拒绝正确解的测试(OpenAI, 2026),而我们对持续失败实例的复核指向同一方向。SWE-Bench+(Aleithan et al., 2024)报告了解的泄漏和薄弱的测试;EvalPlus(Liu et al., 2023)、UTBoost(Yu et al., 2025)和 Wang et al.(2025b)表明,通过测试仍可能接受错误代码;PAIChecker(Wang et al., 2026)检测议题与其拉取请求之间的错位;SWE-Bench Pro Verified(Zheng et al., 2026)和 SciCode-Verified(Hu et al., 2026)重新标注了基准,并发现缺陷低估了模型能力;Zhu et al.(2025)为智能体基准提出检查清单。这些工作审计的是单任务,大多靠人工标注,而且大多是相反的失败:测试接受得太多。我们研究的是要求得太多的测试,在五种语言上静态地度量它,并顺着构建单元和里程碑链追踪它的效应。

告诉智能体测试需要什么。若干基准在任务里说明接口:SWE-Bench Pro(Deng et al., 2025)给每项任务加上需求和接口描述,FEA-Bench(Li et al., 2025)给出新组件的签名,Commit0(Zhao et al., 2025)提供一个库的规范文档。DeepSWE(Huang et al., 2026)为每项任务编写指令和验证器。我们的附录把这一做法带到被挖掘出来的长程基准上,而审计表明它在哪里是需要的。

长程与多语言基准。SWE-Milestone(Deng et al., 2026)、SWE-EVO(Le et al., 2025)和 SWE-CI(Chen et al., 2026)在一串变更上评测智能体;Multi-SWE-bench(Zan et al., 2025)和 SWE-PolyBench(Rashid et al., 2025)把议题解决扩展到 Python 之外;SWE-bench-Live(Zhang et al., 2025)持续加入新任务,以对抗污染。

衡量了错误对象的基准。在自然语言处理中,标注伪影让模型不用做推断就能通过自然语言推断(Gururangan et al., 2018),而基准设计本身也被称为一个效度问题(Bowman and Dahl, 2021);污染(Sainz et al., 2023)以及对 SWE-bench 的记忆(Liang et al., 2025)提出了回忆与技能之别的问题,我们的复现分析触及这一点。规范–预言机缺口是标注伪影在生成式设定下的对应物:评分者奖励输入里并不包含的信息。

9 结论

生成出来的规范和逐字照搬的测试,使基准建造起来便宜、跑起来现实,但它们让测试依赖任务没有说明的信息。在 SWE-Milestone 中,四分之一的被评分里程碑包含这样一项依赖;携带它的构建单元失败得明显比可比单元更频繁,而在参照实现里给一个隐藏标识符改名,就会像审计所预测的那样弄坏它的单元。排行榜的名次经得起这一修正——而且无论如何,它都比看上去更粗——但逐仓库的分数会移动。跨五个基准,缺口跟着任务文本如何写成走。依赖审计很便宜——数分钟,不调用模型——我们连同修正后的过滤清单和规范附录一起发布了我们的审计。

局限

隐藏依赖是一种风险,不是必然的失败:智能体确实会复现一些未被规定的名字,来自约定,或来自对上游项目的记忆,因此我们把实际兑现分开报告,并把可以从基线约定推导出来的名字标为可推断。实际兑现是观察性的:我们在相同的里程碑之内,把被堵住的单元与同样在测试新代码的单元相比较,但两组在难度上仍可能不同;参照实现上的反事实只覆盖 Go。我们的三条规则(按约定放置的路径、接口方法、标识符级依赖)以及 RQ4 的修正,是在开发数据上设定、并在留出集抽出之前冻结的;我们报告修正前后的计数(RQ1)。DeepSWE 促使了两条规则,因此它不是样本外检验。我们对 SRS 的匹配是词法的;一份规范可能用别的词描述一个名字(过度报告),或提到一个标识符却并不把它当作接口(报告不足)。提取器是名字级的,不做类型检查:它们会漏掉一个新方法,如果同一单元里另一个类型上已经存在这个名字;它们也可能把外部库所要求的接口方法标记出来。测试所要求、却没有新名字的行为(一条转义规则、一种加权方案)只由一条文本启发式覆盖,我们把它分开报告;在 SWE-bench Verified 上,这类行为缺口解释了我们所复核的大多数持续失败,因此审计的计数是测试要求了任务没有说出的东西的一个下界。规则之外的依赖——关键字参数、Python 和 TypeScript 中对对象的属性访问、通过辅助函数比较的字符串——只作为名字级上界被报告,而在运行时计算的测试标识符,只有在审计器读到构造它们的辅助函数时才能匹配。被标记的项和持续失败,是对照任务文本、测试和参照实现来复核的(由大语言模型起草的初判,再由作者核对);这类判断可能不同,我们连同引文一起发布每一项判定。我们深入研究一个基准,并比较另外四个;普遍程度会随语言、测试风格和构造方式而变化,正如它在我们的仓库和基准之间已经不同。记忆分析是相关的,不是因果的。去掉测试会改变基准所衡量的东西;因此我们也提供规范附录,其效应我们还没有用新的智能体运行来测量。

伦理声明

我们分析公开发布的基准数据和智能体运行;不涉及人类受试者研究,我们也不运行编码智能体。留出验证的标签来自一位作者,以及一名受雇的软件专家,后者有超过十年的全栈开发与开源维护经验,通过个人联系招募,报酬为每小时 80 美元,远高于典型的标注费率,并被告知这些标签将被发布;参与是自愿的。我们使用的全部人工制品都是公开的:SWE-Milestone、它的评分工具和运行日志(MIT),DeepSWE 的任务和已发布试验(Apache-2.0,每项任务的上游项目使用其自己的宽松许可),SWE-bench Verified(与采用 MIT 许可的 SWE-bench 一起分发),SWE-bench 实验仓库的逐实例解决记录——该仓库没有声明许可,我们从中只使用每个实例是否被解决——SWE-EVO(MIT;其数据集卡片也写了 Apache-2.0)以及 SWE-Chain(Apache-2.0)。我们把它们用于评测研究,也就是其预期用途,并且除标识符和短引文之外,不重新分发它们的内容。这一审计可能被用来把智能体裁剪到某个基准的隐藏名字上;我们发布它是为了改进基准,而修正后的过滤清单去掉了这种裁剪所能带来的优势。人工智能助手的使用。我们使用基于大语言模型的编码助手来帮助实现审计和分析脚本,为被标记案例和持续失败案例的复核起草初判,并编辑文本。定义和设计决定是作者的;每一项复核判定和每一个被报告的数字,都由作者对照已发布的数据和代码核对过。

参考文献

  • Aleithan et al. (2024) Reem Aleithan、Haoran Xue、Mohammad Mahdi Mohajer、Elijah Nnorom、Gias Uddin 与 Song Wang。2024。SWE-Bench+:面向大语言模型的增强编码基准 (https://doi.org/10.48550/arXiv.2410.06992)。arXiv 预印本 arXiv:2410.06992。这篇工作把 SWE-Bench 增强为面向大语言模型的编码基准。
  • Bowman and Dahl (2021) Samuel R. Bowman 与 George E. Dahl。2021。要怎样才能修好自然语言理解中的基准评测? (https://doi.org/10.18653/v1/2021.naacl-main.385) 载于《计算语言学协会北美分会 2021 年会议论文集:人类语言技术》。预印本编号 ArXiv:2104.02145。这篇工作追问要怎样才能修好自然语言理解里的基准评测。
  • Chen et al. (2026) Jialong Chen、Xander Xu、Hu Wei、Chuan Chen 与 Bing Zhao。2026。SWE-CI:通过持续集成评测智能体维护代码库的能力 (https://doi.org/10.48550/arXiv.2603.03823)。arXiv 预印本 arXiv:2603.03823。这篇工作通过持续集成评测智能体维护代码库的能力。
  • Deng et al. (2026) Gangda Deng、Zhaoling Chen、Zhongming Yu、Haoyang Fan、Yuhong Liu、Yuxin Yang、Dhruv Parikh、Rajgopal Kannan、Le Cong、Mengdi Wang、Qian Zhang、Viktor Prasanna、Xiangru Tang 与 Xingyao Wang。2026。SWE-Milestone:在持续软件演化上评测人工智能智能体。载于《第四十三届国际机器学习大会论文集》。预印本编号 ArXiv:2603.13428。这篇工作在持续的软件演化上评测人工智能智能体。
  • Deng et al. (2025) Xiang Deng、Jeff Da、Edwin Pan、Yannis Yiming He、Charles Ide、Kanak Garg、Niklas Lauffer、Andrew Park、Nitin Pasari、Chetan Rane、Karmini Sampath、Maya Krishnan、Srivatsa Kundurthy、Sean Hendryx、Zifan Wang、Vijay Bharadwaj、Jeff Holm、Raja Aluri、Chen Bo Calvin Zhang,以及另外三人。2025。SWE-Bench Pro:人工智能智能体能解决长程软件工程任务吗? (https://doi.org/10.48550/arXiv.2509.16941) arXiv 预印本 arXiv:2509.16941。这篇工作追问人工智能智能体能否解决长程软件工程任务。
  • Gururangan et al. (2018) Suchin Gururangan、Swabha Swayamdipta、Omer Levy、Roy Schwartz、Samuel R. Bowman 与 Noah A. Smith。2018。自然语言推断数据中的标注伪影 (https://doi.org/10.18653/v1/N18-2017)。载于《计算语言学协会北美分会 2018 年会议论文集:人类语言技术,第二卷(短文)》,第 107–112 页。预印本编号 ArXiv:1803.02324。这篇工作指出自然语言推断数据里存在标注伪影。
  • Hu et al. (2026) Sihan Hu、Lyuhan Huang、Youjin Deng 与 Kun Chen。2026。SciCode-Verified:基准缺陷如何低估了语言模型的科学编码能力 (https://doi.org/10.48550/arXiv.2608.04975)。arXiv 预印本 arXiv:2608.04975。这篇工作说明基准缺陷如何低估语言模型的科学编码能力。
  • Huang et al. (2026) Wenqi Huang、Charley Lee、Leonard Tng 与 Serena Ge。2026。DeepSWE:在原创的长程工程任务上度量前沿编码智能体 (https://doi.org/10.48550/arXiv.2607.07946)。arXiv 预印本 arXiv:2607.07946。这篇工作在原创的长程工程任务上度量前沿编码智能体。
  • Jimenez et al. (2024) Carlos E. Jimenez、John Yang、Alexander Wettig、Shunyu Yao、Kexin Pei、Ofir Press 与 Karthik Narasimhan。2024。SWE-bench:语言模型能解决真实世界的 GitHub 议题吗?载于《国际学习表征会议》。这篇工作追问语言模型能否解决真实世界的 GitHub 议题。
  • Lam et al. (2026) Man Ho Lam、Chaozheng Wang、Hange Liu、Jingyu Xiao、Haau-sing Li、Jen-tse Huang、Terry Yue Zhuo 与 Michael R. Lyu。2026。SWE-Chain:在链式的发布级软件包升级上给编码智能体做基准 (https://doi.org/10.48550/arXiv.2605.14415)。arXiv 预印本 arXiv:2605.14415。这篇工作在链式的发布级软件包升级上给编码智能体做基准。
  • Le et al. (2025) Tue Le、Minh V. T. Thai、Dung Nguyen Manh、Huy Phan Nhat 与 Nghi D. Q. Bui。2025。SWE-EVO:在长程软件演化场景中给编码智能体做基准 (https://doi.org/10.48550/arXiv.2512.18470)。arXiv 预印本 arXiv:2512.18470。这篇工作在长程软件演化场景中给编码智能体做基准。
  • Li et al. (2025) Wei Li、Xin Zhang、Zhongxin Guo、Shaoguang Mao、Wen Luo、Guangyue Peng、Yangyu Huang、Houfeng Wang 与 Scarlett Li。2025。FEA-Bench:评测面向功能实现的仓库级代码生成的基准 (https://doi.org/10.18653/v1/2025.acl-long.839)。载于《计算语言学协会第六十三届年会论文集(第一卷:长文)》,第 17160–17176 页。这篇工作评测面向功能实现的仓库级代码生成。
  • Liang et al. (2025) Shanchao Liang、Spandan Garg 与 Roshanak Zilouchian Moghaddam。2025。SWE-Bench 幻觉:当最先进的大语言模型是在回忆而不是在推理 (https://doi.org/10.48550/arXiv.2506.12286)。arXiv 预印本 arXiv:2506.12286。这篇工作指出最先进的大语言模型可能是在回忆而不是在推理。
  • Liu et al. (2023) Jiawei Liu、Chunqiu Steven Xia、Yuyao Wang 与 Lingming Zhang。2023。你由 ChatGPT 生成的代码真的正确吗?对大语言模型代码生成的严格评测。载于《神经信息处理系统进展》。预印本编号 ArXiv:2305.01210。这篇工作严格评测大语言模型所生成代码是否真的正确。
  • OpenAI (2024) OpenAI。2024。介绍 SWE-bench Verified。https://openai.com/index/introducing-swe-bench-verified/。这是 OpenAI 介绍 SWE-bench Verified 的官方页面。
  • OpenAI (2026) OpenAI。2026。为什么 SWE-bench Verified 不再衡量前沿编码能力。https://openai.com/index/why-we-no-longer-evaluate-swe-bench-verified/。这是 OpenAI 说明为何不再用 SWE-bench Verified 衡量前沿编码能力的页面。
  • Rashid et al. (2025) Muhammad Shihab Rashid、Christian Bock、Yuan Zhuang、Alexander Buchholz、Tim Esler、Simon Valentin、Luca Franceschi、Martin Wistuba、Prabhu Teja Sivaprasad、Woo Jung Kim、Anoop Deoras、Giovanni Zappella 与 Laurent Callot。2025。SWE-PolyBench:用于编码智能体仓库级评测的多语言基准 (https://doi.org/10.48550/arXiv.2504.08703)。arXiv 预印本 arXiv:2504.08703。这篇工作给出编码智能体仓库级评测的多语言基准。
  • Sainz et al. (2023) Oscar Sainz、Jon Ander Campos、Iker García-Ferrero、Julen Etxaniz、Oier Lopez de Lacalle 与 Eneko Agirre。2023。陷入麻烦的自然语言处理评测:论为每个基准度量大语言模型数据污染的必要 (https://doi.org/10.18653/v1/2023.findings-emnlp.722)。载于《计算语言学协会自然语言处理经验方法会议 2023 年发现集》,第 10776–10787 页。预印本编号 ArXiv:2310.18018。这篇工作主张为每一个基准分别度量大语言模型的数据污染。
  • Wang et al. (2026) Manyi Wang、Junjielong Xu 与 Pinjia He。2026。PAIChecker:发现并检查类 SWE-Bench 基准中拉取请求与议题的错位 (https://doi.org/10.48550/arXiv.2607.28587)。arXiv 预印本 arXiv:2607.28587。这篇工作发现并检查类 SWE-Bench 基准中拉取请求与议题的错位。
  • Wang et al. (2025a) Xingyao Wang、Boxuan Li、Yufan Song、Frank F. Xu、Xiangru Tang、Mingchen Zhuge、Jiayi Pan、Yueqi Song、Bowen Li、Jaskirat Singh、Hoang H. Tran、Fuqiang Li、Ren Ma、Mingzhang Zheng、Bill Qian、Yanjun Shao、Niklas Muennighoff、Yizhe Zhang、Binyuan Hui,以及另外五人。2025a。OpenHands:作为通用智能体的人工智能软件开发者开放平台。载于《国际学习表征会议》。预印本编号 ArXiv:2407.16741。这篇工作把 OpenHands 做成面向软件开发的通用智能体开放平台。
  • Wang et al. (2025b) You Wang、Michael Pradel 与 Zhongxin Liu。2025b。SWE-bench 里“已解决的议题”真的被正确解决了吗?一项实证研究 (https://doi.org/10.48550/arXiv.2503.15223)。arXiv 预印本 arXiv:2503.15223。这篇工作实证追问 SWE-bench 里已解决的议题是否真的被正确解决。
  • Yu et al. (2025) Boxi Yu、Yuxuan Zhu、Pinjia He 与 Daniel Kang。2025。UTBoost:在 SWE-Bench 上对编码智能体的严格评测 (https://doi.org/10.18653/v1/2025.acl-long.189)。载于《计算语言学协会第六十三届年会论文集》,第 3762–3774 页。这篇工作在 SWE-Bench 上对编码智能体做严格评测。
  • Zan et al. (2025) Daoguang Zan、Zhirong Huang、Wei Liu、Hanwu Chen、Linhao Zhang、Shulin Xin、Lu Chen、Qi Liu、Xiaojian Zhong、Aoyan Li、Siyao Liu、Yongsheng Xiao、Liangqiang Chen、Yuyu Zhang、Jing Su、Tianyu Liu、Rui Long、Kai Shen 与 Liang Xiang。2025。Multi-SWE-bench:用于议题解决的多语言基准。载于《神经信息处理系统进展,数据集与基准轨道》。这篇工作给出用于议题解决的多语言基准。
  • Zhang et al. (2025) Linghao Zhang、Shilin He、Chaoyun Zhang、Yu Kang、Bowen Li、Chengxing Xie、Junhao Wang、Maoquan Wang、Yufan Huang、Shengyu Fu、Elsie Nallipogu、Qingwei Lin、Yingnong Dang、Saravan Rajmohan 与 Dongmei Zhang。2025。SWE-bench 走向实时!载于《神经信息处理系统进展,数据集与基准轨道》。这篇工作让 SWE-bench 走向持续更新的实时设定。
  • Zhao et al. (2025) Wenting Zhao、Nan Jiang、Celine Lee、Justin T Chiu、Claire Cardie、Matthias Gallé 与 Alexander M Rush。2025。Commit0:从零开始生成库。载于《国际学习表征会议》。预印本编号 ArXiv:2412.01769。这篇工作研究从零开始生成程序库。
  • Zheng et al. (2026) Pujun Zheng、Zixin Shang、Shufan Jiang、Wenhui Tian、Dongsheng Zhu、Zerun Ma、Dingbo Yuan 与 Qi Zhang。2026。SWE-Bench Pro Verified:面向软件工程智能体的可靠基准 (https://doi.org/10.48550/arXiv.2609.08149)。arXiv 预印本 arXiv:2609.08149。这篇工作给出面向软件工程智能体的可靠基准。
  • Zhu et al. (2025) Yuxuan Zhu、Tengjun Jin、Yada Pruksachatkun、Andy Zhang、Shu Liu、Sasha Cui、Sayash Kapoor、Shayne Longpre、Kevin Meng、Rebecca Weiss、Fazl Barez、Rahul Gupta、Jwala Dhamala、Jacob Merizian、Mario Giulianelli、Harry Coppock、Cozmin Ududec、Jasjeet Sekhon、Jacob Steinhardt,以及另外六人。2025。建立构造严格智能体基准的最佳实践。载于《神经信息处理系统进展,数据集与基准轨道》。这篇工作讨论如何建立构造严格智能体基准的做法。

附录 A 各语言的单元与提取器

审计对每种语言有一个提取器:Go 的 go/ast,带对象解析和构建约束;Python 的 ast;TypeScript、Rust 和 Java 使用 tree-sitter(表 5)。提取器按状态报告每个包或模块所定义的名字,并按测试单元和测试报告它所引用的名字、模块路径和字面量。一个与语言无关的核心比对所有里程碑的 gold 状态,对每项依赖分类,应用 SRS 与可推断性规则,并把必需测试映射到单元。必需测试集用评分工具自己的归一化代码计算,并在所有里程碑上与官方计数一致。Gold 状态从基准的镜像中导出。

语言提取器单元说明
Gogo/astpackage test binary面向 linux/amd64 的构建约束;Ginkgo 套件算一个单元
Pythonasttest module模块级导入失败会使收集失败;C 扩展按模式读取
TypeScripttree-sittertest file导入,jest.mock/vi.mock 路径;只有 SRS 点出文件时路径才算被规定
Rusttree-sittercargo test target映射宏和 rstest 案例;工作区构建在第一个失败目标处停止
Javatree-sitterMaven module多模块构建在一个模块失败后跳过其后的模块

表 5:各语言的构建单元与提取器。

附录 B 回归细节

RQ2 的模型是一个逻辑回归:因变量是一个(单元,运行)对是否失败——某项必需测试失败或缺失——自变量是被硬堵住单元的指示变量、该单元必需测试数量的以 2 为底的对数,以及仓库固定效应。它拟合于那 25 个含有被硬堵住单元的里程碑,用它们的 72 个被堵住单元和 27 个比较单元(有新测试、没有新依赖)在 35 次运行上的 3,379 对;3,465 对中有 86 对没有可读结果,被去掉。每次运行是一次单独的观测;同一模型在其他配置下的运行并不合并,但共享一个模型家族。标准误是对里程碑和 11 个模型家族(厂商加档位,例如 Claude Opus 或 Gemini Flash)的双向聚类稳健标准误;独立重抽样里程碑和家族的双向聚类自助法(500 次抽取)给出 2.62–8.56。把堵住指示变量设为零,平均使被堵住配对的预测失败概率下降 31.9 个百分点(18.3–43.7)。去掉被标为泄漏的那次运行后,优势比为 4.75(2.99–7.54)。

附录 C 运行之间的一致性

对每一对运行,我们在每个硬隐藏名字是否被写出这一点上计算 Cohen $\kappa$,范围是两次运行的评测都给出证据的那些名字(附录 G);被标为泄漏的运行被排除。相同模型的配对,是同一模型标识在两种配置下的运行(8 对,其余运行都只有一种配置);跨模型配对是不同模型的运行(553 对)。中位数分别为 0.81(95% 区间 0.66–0.94)和 0.63(0.50–0.75),来自对硬名字的 500 次自助抽取;二者之差的区间为 -0.17 到 0.40,来自对模型的自助法。

附录 D 没有任何运行通过的测试

在没有任何已发布运行通过的 6,167 项必需测试中,5,338 项归因于没有任何运行能够构建的那个 nushell 里程碑(它剩余的测试计入隐藏字面量),646 项归因于因环境而没有任何运行执行的测试,50 项和 14 项归因于 A1 与 A2 依赖,5 项归因于隐藏字面量,17 项归因于没有任何规范描述的行为;还有 97 项未被解释。

附录 E 生成器为什么漏掉名字

这一缺口不是规范撰写者的疏忽,而是写进提示里的一种张力。SWE-Milestone 已发布的生成流水线(脚注 2:https://github.com/DeepCommit-ai/DeepCommit,commit 2343409d,harness/gen_srs(srs_gen_v1.tmpl、acceptance_test_align.tmpl、prepare_prompt.py)。)指示模型:“不要过度规定:不要实现方面的提示,不要文件路径,不要代码片段”,并且“避免强制规定特定的函数、方法或代码编辑”。第二轮与测试对齐的过程,本意是补回测试所需要的东西——“如果测试要求特定的命名或接口,就加上:……模块常量(当测试导入它们时)”——并且默认既分析新的(none-to-pass)测试,也分析 fail-to-pass 测试。然而它的两条规则正好对着我们所发现的缺口起作用:它告诉模型略去智能体能够“从代码差异里……想出来”的东西,而智能体从来看不到那份差异;对于共享同一个错误签名的一簇测试,它加上“一条”准则并跳过其余。两轮都没有拿到一个单元里已有的测试,而这些测试占被堵住单元中 3,191 项必需测试里的 2,333 项,它们失败只是因为同一单元里一项新测试无法被构建。一个被吩咐不要过度规定、并且每个错误簇只写一条准则的生成器,很可能会正好漏掉那些决定整个单元的名字。

附录 F 评分工具设计

SWE-Chain 的评分工具把智能体的树复制到参照镜像之上,因此缺失的模块会被补上;它把失败的导入变成占位符,于是只有使用该名字的测试会失败;并且它把失败的导入回报给智能体,供一轮修复使用。构建报告在 55.9% 的系统运行中点出了那个隐藏名字,而 80.9% 的运行最终把它写了出来。SWE-Milestone 的评分工具则是把参照测试嫁接到智能体的树上,并使整个构建单元失败,而且不给这样的反馈。

附录 G 被复现出来的隐藏名字的细节

证据。一次运行是否提供了某项硬依赖,是从它的评测中读出的(发布中的源码快照只在第 3 节的例子里被我们阅读,那会允许直接核对):若一个构建需要该依赖的单元有一项必需测试通过(Go、Rust 和 Java 构建整个单元;Python 在模块级导入失败;TypeScript 在未解析的模块路径上失败),就表明它存在;若有一行日志把它称为未定义、未找到或未导出,就表明它不存在;否则该(条目,运行)对是未定的。一项失败的测试并不能证明构建发生过,因为有些运行把一个没有编译成功的单元里的每一项测试都记成失败。

比率。去掉被标为泄漏的运行后,运行复现了 2,056 个已判定的(硬条目,运行)对中的 45.2%,以及 1,064 个可推断对中的 79.0%。比率因仓库而不同:在 go-zero 中是 34.4% 对 49.9%;在 TypeScript 前端中,大多数硬项是模块路径,为 90–100%。在第 4 节的路径规则之前,这一对照促使了那条规则:该规则现在视为可推断的路径,在已判定配对中被写出的比例是 99.7%(654 对中的 652 对),它仍然视为硬项的路径是 91.5%(398 对中的 364 对)。

暴露。对每次运行和每个仓库,我们把厂商所声明的模型训练(或知识)截止日期,与该仓库区间的发布日期相比较。在仓库内部,截止日期落在该区间之后的运行,在硬项上与其他运行相差 -11.9 个百分点(置换 $p$ = 0.24);在声明了截止日期的运行之间,一次运行的暴露份额与其复现率的偏相关,在给定其官方分数的条件下,为 -0.01($p$ = 0.98)。这一分析是相关的,效力很小,但它没有给出迹象表明,接触过上游代码能够解释哪些运行复现了隐藏依赖。

附录 H 代表性案例

基准悄悄丢掉的测试(go-zero,B3)。M017 的参照测试使用了诸如 maxFormParamCount 这样的名字,而 M017 自己的 gold 状态并没有定义它们,因此参照解无法编译它们。基准的分类把受影响的测试记为 pass-to-none,它们就从必需集合中消失了。这一缺陷不降低任何分数,但它去掉了该里程碑的需求所要求的覆盖。

没有任何运行能够构建的里程碑(nushell,顺序冲突)。里程碑 G05_be6e868 重构了语言服务器测试,其参照实现在初始化 PositionalArg 时没有字段 custom_completion,而里程碑 G01_48bca0a 会加上这个字段。智能体在同一棵树里实现两者;先实现了 G01_48bca0a 的 19 次运行,因为缺少该字段而无法编译被嫁接的测试,其余运行停在同一批测试的其他构建错误上,没有任何已发布运行为该里程碑的 5,339 项必需测试产出哪怕一条结果。

附录 I 对其他基准的复核

表 6 按基准给出审计了什么、标记了什么,以及标记如何被复核。每一次复核都应用第 4 节的定义:当一项被计分测试需要这个精确的名字、模块路径或文本,任务文本没有给出它,而且基线既没有定义它、也没有按约定决定它时,该条目被确认;否则它是假阳性。SWE-Milestone 由两名盲标注者按构建单元复核(RQ4)。其他基准按被标记条目,对照任务文本(对 SWE-EVO 还包括其智能体指令所附加的拉取请求和议题文本)、测试和参照变更来复核,初判由一个大语言模型起草,再由一位作者核对。若一个基准的标记多于我们所复核的数量,被复核的条目是按仓库(SWE-EVO)或按包(SWE-Chain)分层的随机样本,种子为 20261010。单元、复核者和样本量都不同,因此精度在各行之间不可比,而且在复核条目很少的地方区间很宽:表 4 是构造方式有影响的探索性证据,不是一次受控比较。每一项判定连同其引文,都与数据一起发布。

基准任务标记复核确认精度(95% 置信区间)
SWE-Milestone9889655889.2 (79.4–94.7)
SWE-EVO4879402460.0 (44.6–73.7)
SWE-Chain155357402870.0 (54.6–81.9)
SWE-bench Verif.50044375.0 (30.1–95.4)
DeepSWE113232314.3 (0.8–21.0)

表 6:各基准的复核协议。任务:被评分的里程碑、发布任务、步骤、实例、任务。标记:带隐藏依赖的被标记构建单元(SWE-Milestone),或被标记条目,即每次复核从中抽样的框架(SWE-EVO 把一个条目在每个测试单元计一次,共 62 个不同条目)。复核:被复核的数量;SWE-Milestone 是规则冻结后抽出的两轮盲标中的单元(RQ4);SWE-EVO 和 SWE-Chain 是分层随机样本;Verified 和 DeepSWE 是全部标记。确认:被确认的数量。精度:被复核者中被确认的百分比,Wilson 区间。

Found it useful? Pass it on

WeChat

Scan with WeChat to open it on your phone and forward it.

Subscribe via RSS

Submit a correction