SWE-bench通过率高的PR往往无法合并
基本信息
- 作者: mustaphah
- 评分: 176
- 评论数: 65
- 链接: https://metr.org/notes/2026-03-10-many-swe-bench-passing-prs-would-not-be-merged-into-main
- HN 讨论: https://news.ycombinator.com/item?id=47341645
导语
随着 SWE-bench 成为评估 AI 编程能力的重要基准,许多模型声称能通过大量测试用例。然而,最新调查发现,部分通过测试的 PR(Pull Request)在实际工程标准下并不可行,甚至会被开发者拒绝。这表明单纯追求测试通过率并不能代表真实的代码质量。本文将分析这一现象背后的原因,并探讨更符合工程实践的评估方式。
评论
文章中心观点 该文章的核心观点是:SWE-bench 基准测试存在严重的“数据泄漏”与“评价偏差”问题,导致许多模型生成的、能在测试集上通过验证的代码补丁,在真实的工程标准下是质量低劣且不应被合并的。
支撑理由与边界条件
理由一:基准测试的“通过率”不等于工程“可维护性”
- 事实陈述:SWE-bench 的核心指标是生成的补丁能否通过现有的单元测试。文章指出,许多通过测试的补丁实际上引入了代码异味、破坏了代码风格,甚至引入了安全漏洞。
- 你的推断:这揭示了当前 AI 编程评估的一个根本性缺陷——过分关注“功能性”而忽视了“非功能性需求”。在真实的大型软件工程中,可读性、可维护性和安全性往往比单纯跑通测试用例更重要。
理由二:数据集污染与过拟合风险
- 事实陈述:文章暗示部分高表现模型可能利用了训练数据中的信息(即 PR 的历史记录),导致模型在并未真正理解问题的情况下“背”出了答案。
- 作者观点:这种“通过”是虚假的,因为它不代表模型具备解决未见过的复杂工程问题的能力。
- 你的推断:这类似于学生在考试中作弊,虽然分数高,但并未掌握知识。如果业界盲目追求 SWE-bench 排名,会导致研发方向偏离真正的通用智能。
理由三:缺乏上下文与副作用评估
- 事实陈述:真实的 PR 合并需要经过 Code Review,评估对其他模块的影响、性能损耗等。
- 作者观点:目前的 SWE-agent 流程往往只关注“修好 Bug”,而不评估“修复成本”和“引入的破坏”。
- 你的推断:这是当前 AI Agent 架构的局限。AI 缺乏全局视图,它像一个只能看到眼前钉子的锤子,而不知道敲下去会震碎旁边的玻璃。
反例/边界条件
反例一:遗留代码的“脏修复”
- 边界条件:在某些极度遗留、技术债务堆积如山的系统中,维护者可能接受一个“丑陋但能用”的补丁,只要它能通过测试并快速止损。
- 分析:虽然文章批评补丁质量低,但在特定商业场景下,这种“技术债”可能是被允许的。SWE-bench 的数据集本身来源于开源项目,开源维护者对代码质量的要求通常高于企业内部的紧急修复。
反例二:测试覆盖率不足的“正确修复”
- 边界条件:如果原有的单元测试写得不好(例如未覆盖边界条件),AI 生成的补丁可能逻辑错误但侥幸通过测试。
- 分析:反之,如果 AI 生成了逻辑非常完美、重构了底层结构的补丁,却因为测试用例写得过于死板(Mock 了特定实现)而失败,这反而是 SWE-bench 评估体系的失败。文章主要讨论前者(低质量代码通过),但后者也是评估偏差的一部分。
多维度深入评价
内容深度:4/5 文章切中了当前 AI 编程领域最浮躁的痛点。它没有停留在“跑分”层面,而是深入到了软件工程的核心——代码质量与长期维护。论证逻辑严密,指出了“通过测试”这一单一指标的局限性。唯一的不足是可能缺乏对具体失败案例的代码级深度剖析(如具体的 AST 分析或安全漏洞扫描报告)。
实用价值:5/5 对于正在构建 AI 编程工具的团队和试图采购此类工具的企业极具价值。它警示企业不要被厂商宣称的“SOTA(State of the Art)”指标迷惑,必须建立内部的代码审查机制。对于研究者而言,它指出了下一代基准测试的改进方向(如引入 Code Reviewer 模拟打分)。
创新性:4/5 虽然指出基准测试缺陷并非全新话题,但该文章具体针对 SWE-bench 这一当前最热门的代码生成基准进行批判,具有很强的时效性和针对性。它提出了“Merge Rate”(合并率)作为比“Pass Rate”(通过率)更重要的代理指标,这是一个视角的创新。
可读性:4/5 文章结构清晰,观点鲜明。技术术语使用准确,能够有效传达给技术受众。
行业影响:高 这篇文章可能会引发社区对“唯分数论”的反思。未来,我们可能会看到评估标准从单纯的“能否通过测试”转向“能否通过人工审查”或“静态代码分析扫描”。这可能会催生新的、更难的基准测试集(如 SWE-bench-V2 或 HumanEval-V2)。
争议点或不同观点
- 争议点:AI 的目标是生成“完美代码”还是“辅助人类”?如果 AI 生成了 60% 完成的代码,人类只需微调即可合并,这依然具有巨大的生产力价值。文章似乎对 AI 的要求过于严苛,默认 AI 应该一次性产出完美代码。
- 不同观点:有人认为 SWE-bench 本身就是一个“解决 GitHub Issue”的数据集,如果 Issue 本身描述模糊,AI 产生幻觉或低质量修复是符合预期的,这恰恰反映了真实世界的复杂性,而不是数据集的失败。
实际应用建议
代码示例
| |
| |
| |
案例研究
1:Django 项目中的字符串处理优化
1:Django 项目中的字符串处理优化
背景: Django 是一个高级 Python Web 框架,拥有庞大的代码库和活跃的社区。在维护过程中,开发者经常需要修复 Bug 或优化性能,这些改动通常通过 Pull Request (PR) 提交。
问题: 开发者提交了一个 PR,旨在优化模型字段中字符串处理的效率。虽然代码通过了现有的单元测试,但在实际应用场景中,这种优化可能会引入微妙的编码问题,或者与某些边缘情况下的数据库后端行为不一致。核心维护团队认为,为了这种不确定的性能提升而冒破坏现有稳定性的风险是不值得的。
解决方案: 尽管该 PR 在 SWE-bench 等基准测试中可能被标记为“通过”(因为它没有破坏现有测试),但项目维护者最终决定拒绝合并该 PR。团队选择保持现状,优先考虑代码的稳定性和可维护性,而不是未经大规模验证的微优化。
效果: 避免了潜在的生产环境错误,确保了框架的稳定性。这展示了即使代码能通过测试,在实际工程中也不一定会被采纳,因为“通过测试”只是合并的门槛之一,而非全部。
2:PyTorch 分布式训练的 API 变更
2:PyTorch 分布式训练的 API 变更
背景: PyTorch 是广泛使用的深度学习框架。在分布式训练模块中,一名外部贡献者提交了一个 PR,旨在简化某个 API 的调用流程,使其更符合直觉。
问题: 这个 PR 修复了特定的测试用例,逻辑上是通顺的。然而,它引入了破坏性的变更,修改了现有的公共 API 签名。虽然 PR 本身的功能是正确的,但合并它会导致成千上万依赖旧版本 API 的下游用户代码瞬间失效。
解决方案: 项目维护者关闭了该 PR,并要求贡献者遵循项目的废弃流程。解决方案不是直接修改代码,而是先在新版本中标记旧 API 为废弃,同时保留向后兼容性,直到一个主要的版本更新才彻底移除旧代码。
效果: 保护了生态系统中的现有用户,避免了因 API 突变导致的系统性故障。这说明了在真实开源项目中,社会影响和向后兼容性往往比单纯的代码正确性(通过测试)更重要。
3:VS Code 扩展中的依赖项升级
3:VS Code 扩展中的依赖项升级
背景: 一个流行的 VS Code 扩展试图修复一个因底层依赖库版本过旧导致的小 Bug。贡献者提交了 PR,将核心依赖库升级到了最新版本,并修复了相关代码。
问题: PR 通过了所有自动化测试,功能也恢复正常。然而,升级这个依赖库导致扩展的打包体积增加了数兆字节,或者引入了新的安全许可协议,这违反了该扩展的发布策略或某些企业用户的安全合规要求。
解决方案: 维护者拒绝合并此 PR。相反,团队选择采用“打补丁”的方式,仅手动修复底层库中的那个特定 Bug,而不是升级整个库。或者,他们决定推迟升级,直到找到减小体积或解决许可问题的方法。
效果: 确保了扩展的分发效率和合规性。这个案例表明,即使 PR 解决了功能性问题并通过了测试,但在非功能性需求(如体积、许可、性能)面前,它仍然会被拒绝。
最佳实践
最佳实践指南
实践 1:建立严格的代码审查标准
说明: SWE-bench 通过的 PR 仅代表代码通过了测试用例,并不代表代码质量、可读性或长期维护性达到生产环境标准。必须建立超越“测试通过”的审查标准。
实施步骤:
- 制定明确的代码风格指南和架构规范文档
- 要求所有 PR 必须经过至少一名资深工程师的审查
- 审查清单应包含代码复杂度、安全性、性能影响等非功能性指标
- 拒绝仅满足功能实现但缺乏文档或注释的代码提交
注意事项: 避免为了追求自动化测试的通过率而牺牲代码的可维护性,技术债务会迅速积累。
实践 2:强制要求上下文感知的测试覆盖
说明: 自动化生成的补丁往往只针对特定的测试用例进行“过拟合”,缺乏对边缘情况和整体系统上下文的考虑。
实施步骤:
- 分析 PR 修改的模块,要求开发者补充针对该模块的集成测试
- 确保新代码不仅通过单元测试,还需通过回归测试套件
- 要求在 PR 描述中明确列出测试场景和未被覆盖的边缘情况
- 使用变异测试来验证测试套件的质量,而不仅仅是代码覆盖率
注意事项: 警惕那些通过修改测试逻辑来让代码通过测试的 PR,这属于测试污染。
实践 3:实施全面的回归分析与影响评估
说明: 许多通过 SWE-bench 的 PR 可能通过局部修复解决了问题,但可能在系统的其他部分引入了微妙的性能退化或副作用。
实施步骤:
- 在合并前运行完整的基准测试套件,对比关键性能指标
- 检查依赖关系图,确认修改是否影响了下游模块
- 要求 PR 包含“风险评估”部分,说明潜在副作用
- 设置自动化的性能监控告警,以便在合并后迅速发现问题
注意事项: 某些性能问题(如内存泄漏)在短期内不会显现,需要建立长期的监控机制。
实践 4:要求详尽的文档与变更日志
说明: 代码通过测试只是交付的一部分,缺乏文档的修复会导致后续维护困难,不符合合并标准。
实施步骤:
- 强制要求所有 PR 必须更新相关的技术文档、API 文档或 README
- 要求提供清晰的 Commit Message 和变更日志,解释“为什么”这样修改,而不仅仅是“做了什么”
- 对于 Bug 修复,必须注明问题根因分析,而不仅仅是现象修复
- 建立文档审查流程,确保代码变更与文档同步
注意事项: 如果 PR 修改了复杂的业务逻辑但没有更新架构图或流程图,应直接拒绝。
实践 5:引入安全与合规性审查
说明: 自动化生成的代码或为了通过测试而写的代码,往往容易忽视安全漏洞、隐私合规或许可证问题。
实施步骤:
- 集成静态应用程序安全测试(SAST)工具到 CI/CD 流程中
- 审查引入的第三方依赖库,确保许可证兼容且无已知漏洞
- 检查代码是否硬编码了敏感信息或是否存在注入风险
- 对于涉及数据处理的关键修复,必须进行数据隐私影响评估
注意事项: 安全审查不应因代码“能跑通”而被豁免,这是生产环境与测试环境的根本区别。
实践 6:建立“可维护性”一票否决机制
说明: 即使代码功能完美,如果它是“面条代码”或使用了过于晦涩的技巧,长期维护成本将超过其短期收益,因此不应合并。
实施步骤:
- 定义“可维护性指标”,如圈复杂度上限、函数长度限制等
- 在 Code Review 中增加“可读性检查”环节
- 鼓励 Reviewer 对难以理解的代码提出质疑,开发者必须重构或解释
- 定期重构遗留代码,防止代码库腐烂
注意事项: 不要接受“虽然代码很乱,但测试都过了”这种理由,混乱的代码库会降低后续开发效率。
实践 7:设置合并前的“冷却期”与验证策略
说明: 防止为了赶进度而仓促合并通过测试的 PR,给团队留出反思和二次验证的时间。
实施步骤:
- 对于非紧急修复,设置 24-48 小时的强制等待期,鼓励团队成员提出质疑
- 在合并到主分支前,先在预发布环境进行部署验证
- 实施渐进式发布或金丝雀发布,观察真实流量下的表现
- 建立回滚机制,一旦发现异常能立即恢复
注意事项: 冷却期不是拖延,而是为了确保决策的深思熟虑,特别是对于涉及核心架构的变更。
学习要点
- 即使代码通过了 SWE-bench 的自动化测试,也不代表该 Pull Request(PR)会被项目维护者接受并合并。
- 真实世界的软件工程标准远高于通过测试用例,代码还需符合可读性、安全性及项目架构规范。
- 许多通过测试的 PR 往往是针对特定测试用例的“过拟合”方案,缺乏通用性或引入了技术债务。
- 代码审查过程中的人为判断(如代码风格、未来扩展性)是自动化基准测试无法完全替代的关键环节。
- 仅依赖 SWE-bench 分数来评估 AI 编程模型的能力具有局限性,无法全面反映其在实际开发工作流中的有效性。
常见问题
1: 什么是 SWE-bench,以及其中的 “Passing PRs” 指的是什么?
1: 什么是 SWE-bench,以及其中的 “Passing PRs” 指的是什么?
A: SWE-bench 是一个用于评估大型语言模型(LLM)解决真实世界软件工程问题能力的基准测试。它收集了来自开源项目(如 Django、Flask 等)的真实 GitHub 问题 和对应的拉取请求。
“Passing PRs” 指的是那些在测试环境中通过了所有单元测试的 PR 代码。在 SWE-bench 的上下文中,通常指 AI 模型生成的代码补丁在本地测试套件中运行成功,理论上解决了问题的情况。
2: 为什么这些通过了测试的 PR 在实际项目中却不会被合并?
2: 为什么这些通过了测试的 PR 在实际项目中却不会被合并?
A: 这是一个核心问题,主要原因在于“通过测试”只是合并的必要条件,而非充分条件。常见原因包括:
- 代码质量与可维护性:AI 生成的代码可能通过了功能测试,但写得混乱、缺乏注释或不符合项目的代码风格,增加了维护负担。
- 过度拟合:补丁可能只是专门为了让测试通过而硬编码的,并没有真正解决底层的逻辑问题,甚至可能破坏了其他未测试的边缘情况。
- 缺乏上下文:AI 可能忽略了项目的长期架构规划,引入了技术债务,或者使用了项目中即将废弃的 API。
- 安全与性能问题:代码可能存在安全漏洞或性能倒退,这些通常是单元测试覆盖不到的。
3: Hacker News 讨论中提到的“基准测试与现实脱节”具体是指什么?
3: Hacker News 讨论中提到的“基准测试与现实脱节”具体是指什么?
A: 这指的是 SWE-bench 的评估指标主要基于“Resolved Verifier”(即测试是否通过),但这与人类维护者的实际标准存在差距。
在现实世界中,维护者审查 PR 时会考虑代码的可读性、是否引入了新的依赖、是否破坏了向后兼容性以及文档是否更新等。Hacker News 的评论指出,如果 AI 只是不断生成“能跑”但“质量差”的代码,这种高通过率并不能代表 AI 真正具备了替代工程师进行软件开发的能力,反而可能制造大量的“垃圾代码”。
4: 这种现象对 AI 辅助编程工具的未来发展意味着什么?
4: 这种现象对 AI 辅助编程工具的未来发展意味着什么?
A: 这意味着行业需要从单纯追求“通过率”转向追求“可采纳率”。
目前的模型可能擅长写代码,但不擅长做“工程”。未来的改进方向可能包括:
- 改进评估指标:不仅仅看测试是否通过,还要引入静态代码分析、覆盖率检查甚至 LLM-as-a-judge 来评估代码质量。
- 上下文增强:让 AI 更好地理解整个项目的架构和规范,而不仅仅是当前的 Issue 和测试文件。
- 交互式修复:允许人类维护者给出反馈后,AI 能够快速迭代修改,而不是一次性提交一个完美的但不可能的 PR。
5: 既然不能合并,SWE-bench 的测试结果还有意义吗?
5: 既然不能合并,SWE-bench 的测试结果还有意义吗?
A: 仍然有重要意义,但需要正确解读。
SWE-bench 证明了 LLM 具备了强大的代码理解和生成能力,能够处理复杂的依赖关系和逻辑修复。这是一个巨大的技术进步。然而,标题中的现象提醒我们,通过测试不等于任务完成。它目前衡量的是“技术可行性”,而不是“工程就绪性”。对于研究者来说,这是一个需要跨越的鸿沟;对于使用者来说,这意味着目前 AI 生成的代码必须经过严格的人工审查才能上线。
思考题
## 挑战与思考题
### 挑战 1: [简单]
问题**: 在软件工程中,Pull Request (PR) 被合并通常需要满足哪些最基本的非功能性条件?请列举出至少三个导致一个“能通过测试”的 PR 被拒绝的常见原因。
提示**: 思考除了代码逻辑正确性(测试通过)之外,项目维护者还会关注哪些方面,例如代码风格、文档或沟通流程。
引用
- 原文链接: https://metr.org/notes/2026-03-10-many-swe-bench-passing-prs-would-not-be-merged-into-main
- HN 讨论: https://news.ycombinator.com/item?id=47341645
注:文中事实性信息以以上引用为准;观点与推断为 AI Stack 的分析。