论文开篇的判断在 2023 年 10 月相当超前:HumanEval 这类代码补全基准已经趋于饱和(saturation),无法再区分前沿模型的能力。作者认为,评测应该向「有挑战性、可持续产生新题、贴近真实价值」的方向走,而真实软件工程正是这样一个「rich, sustainable, and challenging testbed(丰富、可持续、有挑战的试验场)」:
最终交付物:2,294 个任务实例,来自 12 个流行 Python 开源仓库的真实 issue + 对应已合并 PR;外加训练集 SWE-bench-train(另外 37 个仓库、19,000 个实例)和两个微调基线模型 SWE-Llama 7b/13b。
每个任务实例的形式:
git apply 打到代码库上。若直接 apply 失败,评测器还会尝试宽松修复(去除多余上下文行、重算 diff header)后重试;FAIL_TO_PASS 测试:来自原 PR 新增/修改的测试,打金标补丁前失败、打完通过——它们验证「issue 描述的问题真的被解决了」。平均每实例 9.1 个(最多 1633 个),40% 的实例有 ≥2 个。
PASS_TO_PASS 测试:原本就通过的测试(中位数 51 个)——它们验证「原有功能没有被改坏」,即无回归(no regression)。
当且仅当两类测试全部通过,该实例才算 resolved(解决);任何缺失或非 pass 状态都判失败。总指标 = resolved 实例百分比(% Resolved)。
这套「新增测试转绿 + 原测试不回归」的双重验证,就是 SWE-bench 最重要的设计:它把「补丁对不对」这个主观问题,转化为一个完全自动、可复现的客观判定。这是执行式验证(execution-based evaluation)相对于文本相似度(BLEU/CodeBLEU)或 LLM 判卷(LLM-as-a-judge)的根本优势——不奖励「长得像正确答案」,只奖励「行为正确」。
落到数据层面,每个实例是一条 JSON 记录,核心字段值得记住(后续所有 SWE-bench 家族与自建同类评测都沿用这套 schema):repo 与 base_commit(定位代码库快照)、problem_statement(issue 正文,即给模型看的题面)、patch(金标解决方案 diff,评测时对模型隐藏)、test_patch(原 PR 附带的测试改动,评测时打上以引入判卷测试,同样对模型隐藏)、FAIL_TO_PASS 与 PASS_TO_PASS(两组判卷测试的名单)。评测流程即:还原 base_commit → 打模型补丁 → 打 test_patch → 跑两组测试 → 解析日志判定。注意测试改动对模型不可见这一点:模型不能「照着判卷标准写代码」,只能从 issue 文本理解需求——这正是它比「给定单测写实现」类基准更接近真实开发的地方。
这是全文机制上最值得复述的部分。三阶段流水线:
从 2023 年 8 月 PyPI 下载量前 5,000 的库中取最流行的前 100 个包,确认开源许可证允许使用后,锁定 12 个流行 Python 仓库,抓取它们的全部 PR,共约 93,139 个。选热门仓库的理由:维护规范、测试覆盖好、issue 质量高。
只保留同时满足两个条件的已合并(merged)PR:
过滤后剩 11,407 个候选。
对每个候选,在按仓库版本定制的 conda 虚拟环境中做「先打测试补丁跑一遍、再打解决方案补丁重跑一遍」的对照实验,要求:
最终得到 2,294 个任务实例。整个管线几乎无人工标注、全自动可复跑——这既是优点(可扩展、可持续更新),也埋下了后来 SWE-bench Verified 要修的坑(部分实例 issue 描述不清、测试过于苛刻,详见第八节)。
12 个仓库及实例数:django (850)、sympy (386)、scikit-learn (229)、sphinx (187)、matplotlib (184)、pytest (119)、xarray (110)、astropy (95)、pylint (57)、requests (44)、seaborn (22)、flask (11),合计 2,294。分布很不均匀,django 一家占 37%。
| 维度 | 均值 | 最大值 |
|---|---|---|
| Issue 文本长度 | 195.1 词 | 4,477 词 |
| 代码库非测试文件数 | 3,010 个 | 5,890 个 |
| 代码库非测试代码行数 | 43.8 万行 | 88.6 万行 |
| 金标补丁(gold patch)编辑行数 | 32.8 行 | 5,888 行 |
| 金标补丁涉及文件数 / 函数数 | 1.7 个 / 3 个 | 31 个 / 36 个 |
| fail-to-pass 测试数 / 总测试数 | 9.1 / 120.8 个 | 1,633 / 9,459 个 |
两个直观感受:第一,上下文是海量的——40 多万行代码不可能全塞进 prompt,「在哪改」本身就是任务的一半;第二,约 2% 的实例 issue 里嵌了图片(matplotlib 高达 32%、seaborn 10%),纯文本模型天然吃亏,这也是后来 SWE-bench Multimodal 的由头。
2023 年还没有「agent」这个玩法,基线是最朴素的检索增强一次生成(retrieve-then-generate):
Prompt 结构:任务指令 + <issue> 问题文本 + <code> 检索到的文件(含 README)+ 一个 diff 格式示例 + 生成补丁的指示。贪心解码,每实例只生成 1 个补丁(pass@1)。被测模型与上下文窗口:ChatGPT-3.5(16k,oracle 设置下只能装下 58.1% 的实例)、GPT-4(32k,84.1%)、Claude 2(100k,96.4%)、SWE-Llama 7b/13b(≥100k)。GPT-4 因预算只在 25% 随机子集上评测。
| 模型 | % Resolved(oracle 检索) | % Resolved(BM25 27k) |
|---|---|---|
| Claude 2 | 4.80 | 1.96 |
| SWE-Llama 13b | 4.00 | 0.70 |
| SWE-Llama 7b | 3.00 | 0.70 |
| GPT-4(25% 子集) | 1.74 | 0.00 |
| ChatGPT-3.5 | 0.52 | 0.20 |
2023 年最强模型 Claude 2,即使直接告诉它该改哪个文件,也只能解决 4.8%;真实检索条件下不到 2%。这个「惨案级」数字正是论文的核心论点:与已饱和的 HumanEval(当时 GPT-4 已 ~90%)相比,真实软件工程还有巨大空间。分析部分有三个现象比总分更有信息量:
把 BM25 预算从 13k 提到 50k,召回率上升,但 Claude 2 的 resolve 率反而从 1.96% 一路降到 1.22%(13k/27k/50k 分别为 1.96/1.87/1.22)。反向实验更说明问题:「oracle-collapsed」设置只保留金标编辑位置 ±15 行,GPT-4 从 1.3% 升到 3.4%,Claude 2 从 4.8% 升到 5.9%。结论:模型会被大量无关代码「淹没」,定位(localization)是与生成同等重要的瓶颈——这直接预言了后来 Agentless 的「先定位再修复」两段式设计和 agent 式按需浏览代码的价值。
成功 apply 的模型补丁平均只改 30.1 行,而全体金标补丁平均 74.5 行、3.0 个函数、1.7 个文件(Claude 2 平均 19.6 行/1.0 个文件,对应实例的金标是 44.1 行/1.2 个文件)。模型倾向「贪心地」打最小补丁、只写原始 Python、不复用代码库既有工具函数和第三方库;而人类的金标补丁常做结构性改进、顺带预防未来的问题。定性分析里的典型失败(sphinx-doc__sphinx-8713):模型找对了要改的函数 _parse_other_parameters_section,却不检查配置项 napoleon_use_param 直接假定为 True,立刻被测试抓住——「几乎对了」在执行式验证下等于零分。
按 issue 年份切分,2023 年前后成绩几乎无差(Claude 2:4.87 vs 4.23),说明模型不是靠「背出训练集里见过的新版代码」得分。另外,让模型重新生成整个文件而不是输出 diff,成绩明显更差(Claude 2:2.2% vs 4.8%;控制长度后 3.9% vs 7.8%)——让模型输出「编辑」而非「全文」更有效,这个结论影响了后来所有 coding agent 的编辑工具设计(如 str-replace 式编辑)。
为了给开源模型一个能吃 100k 上下文、会输出 patch 的基线,作者用另外 37 个仓库(与评测集完全不相交,防污染)的 19,000 个 issue-PR 对做微调:剔除超 30,000 token 的样本后有效训练集约 10,000 条;基座 CodeLlama-Python,LoRA(r=16、α=16、dropout 0.05,只调注意力 q/k/v/o 投影),lr 6e-4、batch 32、至多 4 epoch,7b 用 4×A100 训 20 小时、13b 用 8×A100 训 47 小时。有趣的副产品发现:SWE-Llama 用 oracle 上下文训练,换 BM25 检索后骤降到 0.7%——它学会的是「编辑上下文里给的所有文件」,检索一混入无关文件就照改不误。微调会把训练分布的假设焊死进模型。
随基准一并发布的还有两件常被忽略的基础设施:其一,SWE-bench-train——用同一套属性过滤(但不要求 PR 含测试改动、不做执行过滤)从另外 37 个仓库收集的 19,000 个 issue-PR 对,证明这条管线可以低成本量产训练数据,这是后来 SWE-smith、SWE-Gym 等「用真实仓库造训练数据」路线的起点;其二,所有任务仓库都被镜像(mirror)到独立组织下并锁定,保证若干年后上游仓库怎么变、评测都能逐字节复现——做长寿命基准,快照与环境锁定是必须一开始就做的工程决定。
论文自陈的局限:任务全是 Python;基线只是最简单的一次生成,鼓励未来探索 agent 式交互、程序分析工具结合;且「测试通过」不等于「代码质量好」——模型方案常不如人类的全面、高效、可读。社区后来补上的坑也值得知道:约束不足的实例(issue 描述太模糊、测试检查了 issue 没提的细节)导致分数被低估或误判,OpenAI 在 2024 年组织人工筛验推出 SWE-bench Verified(500 个高质量实例 + 难度标注),成为事实标准;另有 Lite(轻量 300 题)、Multimodal、多语言版等家族成员。搭配 agent 框架(SWE-agent、Agentless 等)后,resolve 率从本文的 4.8% 一路飙升——这条从 2% 到 70%+ 的曲线本身,就是 2023–2026 年 agent 技术进步最干净的度量衡。