← 返回 AI Agent 课程

【中文精读】SWE-bench:语言模型能解决真实世界的 GitHub Issue 吗?

原文:https://arxiv.org/abs/2310.06770(Jimenez, Yang, Wettig, Yao, Pei, Press, Narasimhan;Princeton/UChicago,ICLR 2024 Oral)· 本文为中文精读版(忠实转述+关键段落翻译),非逐句全译 · 抓取自 ar5iv HTML 全文 · 生成于 2026-07-03 · 精读整理:
导读:如果你只打算精读一篇「编码 agent 评测」的论文,应该就是这篇。SWE-bench 是整个 coding agent 时代的奠基性基准——它第一次把评测对象从「写一个自包含的小函数」(HumanEval/MBPP)升级为「在一个几十万行的真实仓库里,根据一条真实 GitHub issue 修出能通过测试的补丁」。今天你听到的 SWE-agent、Devin、Claude Code 在 SWE-bench Verified 上刷分,全部源于此。读懂它,你就掌握了 agent 评测最核心的范式:执行式验证(execution-based evaluation)——不看代码长得像不像,只看跑起来测试绿不绿。它构造任务的「双重测试验证」管线,也是你日后为自己的 agent 搭评测集时最值得抄的作业。

一、动机:为什么要造 SWE-bench

论文开篇的判断在 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。

二、任务定义:输入、输出与双重测试验证

每个任务实例的形式:

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):repobase_commit(定位代码库快照)、problem_statement(issue 正文,即给模型看的题面)、patch(金标解决方案 diff,评测时对模型隐藏)、test_patch(原 PR 附带的测试改动,评测时打上以引入判卷测试,同样对模型隐藏)、FAIL_TO_PASSPASS_TO_PASS(两组判卷测试的名单)。评测流程即:还原 base_commit → 打模型补丁 → 打 test_patch → 跑两组测试 → 解析日志判定。注意测试改动对模型不可见这一点:模型不能「照着判卷标准写代码」,只能从 issue 文本理解需求——这正是它比「给定单测写实现」类基准更接近真实开发的地方。

三、构造管线:93,139 个 PR 如何被筛成 2,294 个任务

这是全文机制上最值得复述的部分。三阶段流水线:

Stage I:仓库选择与爬取(Scraping)

从 2023 年 8 月 PyPI 下载量前 5,000 的库中取最流行的前 100 个包,确认开源许可证允许使用后,锁定 12 个流行 Python 仓库,抓取它们的全部 PR,共约 93,139 个。选热门仓库的理由:维护规范、测试覆盖好、issue 质量高。

Stage II:属性过滤(Attribute Filtering)

只保留同时满足两个条件的已合并(merged)PR:

过滤后剩 11,407 个候选。

Stage III:执行过滤(Execution Filtering)

对每个候选,在按仓库版本定制的 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 24.801.96
SWE-Llama 13b4.000.70
SWE-Llama 7b3.000.70
GPT-4(25% 子集)1.740.00
ChatGPT-3.50.520.20

2023 年最强模型 Claude 2,即使直接告诉它该改哪个文件,也只能解决 4.8%;真实检索条件下不到 2%。这个「惨案级」数字正是论文的核心论点:与已饱和的 HumanEval(当时 GPT-4 已 ~90%)相比,真实软件工程还有巨大空间。分析部分有三个现象比总分更有信息量:

1. 上下文越长,表现越差

把 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 式按需浏览代码的价值。

2. 模型补丁比人类补丁短得多、简单得多

成功 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,立刻被测试抓住——「几乎对了」在执行式验证下等于零分。

3. 反数据污染的旁证 + 生成格式的影响

按 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 式编辑)。

七、SWE-Llama:微调基线

为了给开源模型一个能吃 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 与镜像仓库

随基准一并发布的还有两件常被忽略的基础设施:其一,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 技术进步最干净的度量衡。

对开发者的启示