SWE-bench 把"语言模型能不能做软件工程"变成一个可量化、可回归、可持续更新的 benchmark:从 12 个热门 Python 开源仓库里扒出 2,294 条 issue + PR + 测试三元组,让模型只看 issue 和整个代码库,输出一个 unified diff patch;应用后必须通过 PR 附带的 fail-to-pass 测试以及原有回归测试才算解决。发布时前沿模型一片惨淡——BM25 检索下 Claude 2 只能解 1.96%,Claude 3 Opus 也才 3.79%——揭穿了 HumanEval 时代"LLM 会写代码"的错觉,并为之后的 coding agent 竞赛定下了评测范式。
传统代码评测(HumanEval、MBPP、APPS)都有几个共性问题:
而真实的软件工程场景恰好相反:
作者希望找到一个既困难又好验证的任务。GitHub 恰好是理想的数据源:merged PR 自带"修复后的代码"作 gold,自带 regression test 作评测器,并且能无限产出新样本避免被训练数据污染。
经过三步,9 万 → 2,294 条。作者还额外发布 SWE-bench Lite(300 条更自包含、聚焦功能性 bug fix)和 SWE-bench-train(37 个不同仓库、1.9 万条,去掉 Stage II 的 test-file 限制,用作 SWE-Llama 训练集)。
patch(1) 应用 → 跑 issue 关联的 fail-to-pass 测试 + 一组回归测试 → 全过 = 解决。核心指标:% Resolved(解决率)。辅助指标:% Apply(patch 至少能干净应用的比例,反映模型生成格式正确性)。
代码库塞不进任何模型的 context,作者固定两种检索方案作为公平的对比基线:
关键观察:27K token 下 BM25 的 recall 对 oracle 文件是 44.4% 平均、26.1% 全命中、51.3% 任意命中;50K 再提升也只到 51.1%。近一半实例下 BM25 连一个关键文件都没捞到。
作者基于 CodeLlama-Python 7B / 13B 做 LoRA 微调(只训练 attention 子层),训练集是上面提到的 19K SWE-bench-train。由于长度约束(>30K tokens 的样本扔掉),实际训练样本 10K。训练时用 oracle 检索格式:给 issue + 被 gold patch 修改的文件 → 让模型输出 gold patch。
这个选择埋了个坑:推理时如果换成 BM25 检索,上下文里会混进"不该改的文件",和训练分布不匹配 → 性能大幅下降。
| Model | SWE-bench % Resolved | SWE-bench % Apply | Lite % Resolved |
|---|---|---|---|
| Claude 3 Opus | 3.79 | 46.56 | 4.33 |
| Claude 2 | 1.97 | 43.07 | 3.00 |
| GPT-4-turbo | 1.31 | 26.90 | 2.67 |
| ChatGPT-3.5 | 0.17 | 26.33 | 0.33 |
| SWE-Llama 13B | 0.70 | 53.62 | 1.00 |
| SWE-Llama 7B | 0.70 | 51.74 | 1.33 |
Claude 2 从 1.97% 跳到 4.8%;进一步把 oracle 文件压到"只留真正改动的行 ±15 行"(oracle-collapsed),GPT-4 1.3 → 3.4%、Claude 2 4.8 → 5.9%。上下文里少塞无关内容是比多塞关键内容更重要的。
| Model | 13K | 27K | 50K |
|---|---|---|---|
| Claude 2 | 1.96 | 1.87 | 1.22 |
| SWE-Llama 7B | 0.70 | 0.31 | 0.00 |
| SWE-Llama 13B | 0.70 | 0.48 | 0.00 |
随着 max context 变大、BM25 召回率上升,解决率反而下降。模型在更多无关代码里迷路得更厉害。
| Model | Before 2023 | After 2023 |
|---|---|---|
| Claude 2 | 4.87 | 4.23 |
| GPT-4* | 1.96 | 0.00 |
| SWE-Llama | 3.98 / 2.95 | 3.85 / 3.46 |
除 GPT-4(且只测了 25% 子集)外,2023 前后差异不显著——即便训练数据包含了仓库旧版本,模型也没有"背答案"。
模型不会定位。 几乎所有错误都发生在"找不到该改的函数/文件"这一步,而不是"找到了写错了"。所以 oracle retrieval 和 oracle-collapsed 都能明显提升分数——这意味着后续工作最重要的方向不是 coding,而是 grounding / localization。
上下文越多越差。 和 Lost in the Middle 观察一致:注入 27K / 50K 的 BM25 上下文后,模型的注意力反而被稀释。这是"retrieval-augmented"的反面案例——信号/噪声比比检索召回率更关键。
diff 比整文件重写更可靠。 模型生成的 patch 通常比 gold 短一半(30.1 vs 74.5 行),rarely edit >1 file。让模型重写整文件反而降分(Claude 2 oracle 设置下 2.2% vs 4.8%)——尽管 patch 格式在 pretraining 里少见,但输出少 = 犯错面小。
微调模型对输入分布极敏感。 SWE-Llama 在 oracle 下能追平 Claude 2(13B 解出 91 个,Claude 2 解出 110 个),但 BM25 下只有 0.7%——因为它被训练成"你给我的每个文件都要改",一旦上下文含噪立刻失效。微调数据的检索格式必须和推理一致。
解对的题集不重合。 oracle 下 Claude 2 和 SWE-Llama 13B 数量接近,但 Claude 2 只覆盖了 SWE-Llama 解出实例的 42%。说明这些模型各有盲区,做 ensemble / 多候选 + 验证是有意义的。
模型写的代码"只解表症"。 定性分析中,SWE-Llama 在 sphinx-doc 的一个例子里定位到了正确函数,但只是把 if use_param: ... 改成"永远走 use_param 分支"——gold 则是正确地沿用 _parse_parameters_section 的 config 检查逻辑。模型倾向于 greedy 满足眼前的测试,不做结构性改造,不调用库内已有工具,不遵循代码风格。
图文混排是隐藏难度。 matplotlib 32%、seaborn 10% 的 issue 包含截图。纯文本模型在这些实例上近乎不可解——预示了多模态 coding agent 的必要性。
SWE-bench 发布后迅速成为 coding agent 领域的事实标准。18 个月内,基于前沿模型 + 工具使用的 agent 系统(SWE-agent、Aider、OpenDevin、Anthropic Claude Code、Cognition Devin 等)把 SWE-bench Verified 的解决率从 < 2% 推到 50%+、Lite 推到 70%+。作者后来发布的 SWE-bench Verified(OpenAI 联合清洗出 500 条人工审核过的可靠题目)、SWE-bench Multilingual 也是对本文局限性的直接回应。
这篇本身没有新模型、没有新架构,价值完全在 benchmark 的设计——尤其是"fail-to-pass 测试 + 执行判定"的判别器选择,让评测既严格又可自动化更新,这是把 LLM coding 从玩具题推向工程任务的关键一步。从方法论角度看,它也是"benchmark 即研究"的典范:好的评测比好的算法对社区推动更大。唯一遗憾是对多文件推理、长程工具使用等维度没有单独拆解——但这恰好留给了社区去填。