这篇是对论文 SWE-bench: Can Language Models Resolve Real-World GitHub Issues? 的学习笔记。
如果要理解代码模型评测从“写函数”走向“做软件工程”的转折,SWE-bench 是绕不开的一篇。
在它之前,很多代码评测集中在 HumanEval、MBPP 这类任务:给模型一段函数签名和描述,让它补全函数,然后跑单元测试。这类评测很有价值,但它测的是一种相对干净的能力:在隔离环境里写一小段代码。
真实软件工程不是这样。真实修 Bug 往往需要读 issue、理解项目结构、定位相关文件、跨函数修改、跑测试、处理依赖、避免破坏已有行为。SWE-bench 把评测对象从“能不能写代码”推进到“能不能在真实仓库里解决问题”。
1. 传统代码评测缺了什么
一个刷题式代码任务通常长这样:
给定函数签名
写出函数体
通过隐藏测试
这能测算法、语法、边界条件,但它故意省掉了很多真实软件工程里的困难:
- 你不知道该改哪个文件。
- 你需要理解已有抽象和调用关系。
- 问题描述可能模糊,issue 里不直接给答案。
- 需要同时改多个函数或类。
- 需要兼容已有测试。
- 需要跑项目测试,而不是只跑一个小函数。
- 需要避免引入回归。
所以一个模型在 HumanEval 上高分,不代表它能接一个 GitHub issue 并修好。
SWE-bench 的核心价值,就是把“代码生成”评测变成“代码维护”评测。
2. SWE-bench 怎么构造任务
SWE-bench 从真实 GitHub issue 和对应 pull request 中构造任务。论文里的数据集包含 2,294 个软件工程问题,来自 12 个流行 Python 仓库。
每个任务大致包含:
一个真实代码仓库
一个 issue 描述
模型需要生成 patch
评测系统把 patch 应用到仓库
然后运行测试判断问题是否解决
这和传统 benchmark 最大的差别,是答案不再是一段孤立文本,而是一个可执行补丁。
模型不能只“解释应该怎么改”,也不能只写一个看似合理的片段。它必须改对文件、改对逻辑、保持项目能跑,并通过测试。
论文早期实验里,表现最好的 Claude 2 只能解决 1.96% 的问题。这个数字今天看起来很低,但它的意义很大:它说明真实软件工程评测比刷题难得多,也说明原有评测可能高估了模型离实用编程助手的距离。
3. SWE-bench 的评测哲学:用执行结果说话
SWE-bench 最值得学的是它的评测哲学:
不问代码看起来像不像,不问解释漂不漂亮,只问 patch 能不能在真实项目里通过验证。
这和 LLM-as-a-Judge 是完全不同的路线。代码任务如果能运行测试,就应该优先运行测试。单元测试、回归测试、lint、类型检查、构建流程,都是比主观评分更硬的信号。
这种评测会逼模型面对真实边界:
- import 是否正确。
- 修改是否破坏旧 API。
- 是否漏掉边界 case。
- 是否只修了表面症状。
- 是否引入新的测试失败。
- 是否生成了不可应用的 patch。
也正因为这样,SWE-bench 很适合评估 Agent,而不只是基座模型。一个真正的代码 Agent 需要搜索文件、读上下文、编辑、运行测试、根据失败修复。这是一条交互式工作流,不是一次性生成。
4. 后续演化也很重要
SWE-bench 后来形成了一个 benchmark family。官方站点里可以看到 Full、Verified、Lite、Multilingual、Multimodal 等版本。
其中 SWE-bench Verified 是 500 个经过人工过滤的实例;Lite 适合成本更低的实验;Multilingual 扩展到更多编程语言;Multimodal 处理带视觉元素的问题。这些演化说明一个现实:真实代码评测不能只靠一次性数据集,它需要持续清洗、分层和扩展。
这也提醒我们看 SWE-bench 分数时要小心:
- Full、Lite、Verified 不是同一个难度。
- Agent scaffold 会极大影响结果。
- 成本预算、步数限制、上下文策略都会影响成绩。
- 数据污染和 benchmark 过拟合需要持续关注。
所以 SWE-bench 最好被看成一套评测范式,而不是一个永远固定的排行榜。
5. 工程团队怎么借鉴 SWE-bench
如果你要评测自己的代码 Agent,不一定要直接跑完整 SWE-bench。更实用的是借它的方法,做一个内部 mini-SWE-bench。
第一步,从历史 issue、bugfix PR、线上事故里抽样。
样本要来自真实问题,不要全靠人工编题。真实问题会自然包含模糊描述、项目上下文、边界条件和历史包袱。
第二步,把任务还原到修复前状态。
也就是给 Agent 一个旧版本仓库和 issue 描述,让它自己找问题。不要把相关文件直接喂给它,否则会低估定位难度。
第三步,准备验证脚本。
最理想是单元测试或集成测试。没有测试时,可以补一个最小 reproducer。评测标准一定要可执行,不能只靠“看起来改对了”。
第四步,记录完整轨迹。
对代码 Agent 来说,最终 patch 只是结果。你还要看它读了哪些文件、跑了哪些命令、测试失败后怎么修、是否浪费大量步骤、是否改了无关文件。
第五步,用多指标报告。
除了 resolved rate,还应该看:
patch apply 成功率
测试通过率
平均成本
平均步数
无关文件修改率
回归测试失败率
人工复核通过率
这样才能知道 Agent 是真的会修,还是靠大改、碰运气、过拟合测试。
6. SWE-bench 的局限
SWE-bench 很强,但也有边界。
第一,它主要来自开源 Python 项目。企业内部代码、前端项目、微服务系统、数据平台、移动端工程,问题形态可能不同。
第二,测试通过不等于完全正确。测试覆盖不足时,模型可能写出刚好过测试但设计很差的 patch。
第三,issue 到 PR 的映射会带来选择偏差。能被收集进数据集的问题,未必代表所有真实软件工程任务。
第四,随着 SWE-bench 影响力变大,数据污染和 leaderboard overfitting 会越来越重要。模型可能在训练中见过 issue、patch 或相关讨论。
第五,它评估的是“给定 issue 修复代码”,但真实工程还包括需求澄清、设计评审、迁移方案、性能权衡、安全审计、上线回滚等更长链条。
所以不要把 SWE-bench 当成软件工程能力的全部。它更像一个坚实起点:先证明模型能在真实仓库里改出可执行 patch。
7. 我的 takeaway
SWE-bench 的最大贡献,是把代码模型评测从“答案像不像”拉回到“改动能不能跑”。
这对所有 LLM 应用评测都有启发。只要任务最终会落到某个执行系统,就不要只评文本。能执行就执行,能测试就测试,能复现就复现。
对代码 Agent 来说,真正的评测对象不应该只是模型输出,而是整条工作流:
理解 issue
定位上下文
制定修改
编辑代码
运行测试
根据失败修复
输出最小 patch
避免回归
这条链路里任何一环弱,真实可用性都会下降。
所以我会把 SWE-bench 作为代码 Agent 评测的基本范式:真实任务、真实仓库、可执行验证、完整轨迹、多指标报告。做到这些,评测才从“演示模型会写代码”变成“证明模型能参与软件维护”。