一个 SWE-bench 数字,是某套测试编排在一个被污染基准上的测量——就该这么读它。
"解决 SWE-bench 70%"是这个领域被引用最多、理解最少的数字之一。它把模型、脚手架、测试编排、pass@k vs 解决率,以及一个有记录在案污染的基准,全都搅在一起。本文涵盖 SWE-bench 系列、这些指标到底意味着什么、测试编排敏感性、污染问题,以及如何构建那个你唯一应当信任的私有评测集。
SWE-bench 系列测的是 issue 解决,而非代码质量。
SWE-bench 取真实 GitHub issue 连同其被合并的修复与测试 diff;若智能体的补丁让隐藏的 fail-to-pass 测试通过且不弄坏 pass-to-pass 测试,该实例就算"已解决"。SWE-bench Verified 是经人工筛选的 500 任务 Python 子集,成了头条;SWE-bench Pro 是更大、多语言、更难、抗污染的后继者,OpenAI 在审计 Verified 后转用了它。指标按任务二值:测试过或不过——它对补丁是不是好代码只字未提。
pass@k 在美化;k=1 的解决率才是诚实数字。
pass@k 把任务记为已解决,只要 k 次尝试中任意一次奏效——用来衡量上限有用,作为部署数字则不诚实,因为生产很少能默默试十次再挑赢家(没有可据以挑选的裁决者)。永远要读报告的是哪个:同一系统上光鲜的"pass@5"与冷静的"resolved@1"能差二十多个点。更糟的是那个不言明的——在被证明并非如此之前,假定那个被宣传的较大数字就是较宽松的指标。
# the same system, three legitimate, very different numbers resolve_at_1 = solved_in_one_attempt / N # the deployment number pass_at_5 = solved_in_any_of_5 / N # headroom, not capability pass_caret_5 = solved_in_all_of_5 / N # reliability under repetition # quote resolve@1; pass@k without k and the selector is marketing
排行榜的一行是模型 + 脚手架 + 测试编排 + 重试策略 + 哪个测试子集,在一个公开集上打分。比较任一处不同的两行,就是在比较虚无——智能体框架对数字的撬动常大于模型本身。
测试编排敏感性:脚手架是混杂因子,不是常量。
同一模型在 SWE-agent、OpenHands 与一套定制循环下产出实质不同的解决率——工具设计、重试预算、定位策略与 prompt 对它的撬动,常大于一次模型版本升级。这是 U1 那条经验作为测量风险的重述:一个基准数字把"主要是别人围着它搭的脚手架"的结果,归功给了"模型"。固定住脚手架,否则你是在 A/B 测两个不同产品,却管它叫模型比较。
污染不是假想——它有记录在案。
SWE-bench Verified 实例是截止日期前的公开 GitHub issue,配公开的已合并修复;审计发现前沿模型在部分任务上能近乎逐字复现 gold 补丁,而 SWE-bench Verified 的维护方自己也不再把它当作干净信号——正因如此,领域转向了 Pro 与持续刷新的集合(SWE-rebench 一脉)。把任何老旧公开基准上的分数当作被记忆污染的上界,而非泛化的测量。
你唯一应当信任的数字是你自己的私有集。
公开基准给系统排名;它们预测不了在你的代码库上的表现——那里有你的约定、你的测试惯用法、你的构建。用你自己已解决的 issue 建一个私有评测:每个都是 diff、fail-to-pass 测试、仓库状态,带日期且置于任何训练面之外。从新 issue 刷新它使其不会腐烂或泄漏,并在你固定的测试编排下报告 resolve@1。那个数字——在你的代码上、截止日期之后——才是唯一能预报生产的。
这个数字仍然告诉不了你的东西。
即便一个干净的私有 resolve@1,测的也是"让测试通过了",而非"写出了资深工程师会合并的代码",不是可维护性,不是它有没有为转绿削弱断言(U3)。它必要而不充分;要配上对样本的人工评审与轨迹检视。对任何你说不出其测试编排、k、选择器与污染状态的编码智能体数字,都别信;公开排行榜是在一个泄漏的测试上给脚手架排名,唯一诚实的分数是在你自己截止日期后的 issue 上的 resolve@1。