一篇来自 SonarSource 的论文《Does Code Cleanliness Affect Coding Agents? A Controlled Minimal-Pair Study》问了一个很多 AI builder 已经在日常工作里遇到的问题:同一套逻辑,代码干净一点还是脏一点,agent 的表现会不会不一样?
这个问题有意思,不是因为它 7 月 5 日登上了 Hacker News 首页。HN 讨论只说明这件事戳中了很多工程师。真正重要的是,它把一个原本靠直觉做的日常选择,变成了一个可以测量的问题:我们要不要为了 agent 清理旧代码、拆函数、补注释、删死代码?
答案比许多人预想的更窄,也更有用。干净代码没有明显提高单次任务通过率。更准确地说,脏代码一侧的通过率还略高一点,但差距不到 1 个百分点。这个差异太小,不能解读成“脏代码更适合 agent”。论文真正测出来的变化在成本上:输入 token 减少 7.1%,输出 token 减少 8.5%,推理字符减少 11.1%,重新打开已编辑文件的次数减少约 34%。在多模块任务上,效果更明显:输入 token 减少 10.7%,文件重复访问减少 50.8%。
这篇论文没有证明代码越干净,agent 成功率越高。它证明了更窄的一点:在当前 agent 工作流里,代码整洁度首先改变的是 agent 找路和确认的成本。这个成本会变成 token、延迟、反复读文件、review 负担和长期代码侵蚀。
作者 Priyansh Trivedi 和 Olivier Schmitt 设计了六组 minimal pair。意思是两组代码仓库在架构、依赖、测试和外部行为上保持一致,只在实现的整洁程度上有差异。作者用 SonarQube rule violations、认知复杂度这类指标来代表整洁度。每组仓库跑 33 个任务,每边重复 10 次,共 660 次试验。Agent 是 Claude Code + Claude Sonnet 4.6。任务由作者构造,不是从真实开源项目的 issue 里拆出来的。
file revisitation 是论文里一个有用的指标。它指 agent 在单次任务中,反复打开和阅读同一个已经编辑过的文件。你可以把它理解为 agent 在同一个地方来回翻看,说明它不确定自己改对了没有。
论文最反直觉的结论在这里。如果干净代码不能提高通过率,那它的价值在哪里?答案在 agent 的交互带宽和 review 链路上。
脏代码侧通过率略高这件事不能直接抹掉。它至少提醒我们:整洁不是一个单调变量。有些所谓清理会把原本挤在一起的逻辑拆到更多 helper、更多文件和更多抽象层里。对人类长期维护来说,这可能更合理;对一个只需要完成当前短任务的 agent 来说,它未必更容易。论文里的差距太小,不能证明脏代码更好,但它足以反驳一个简单化判断:只要代码更符合 clean code 规则,agent 就一定更容易成功。
输入 token 下降,说明 agent 用更少的上下文窗口就能定位到需要修改的位置。在多模块场景中,这个差异尤其大。整洁侧的函数、文件和模块边界更明确,agent 不需要在大量无关代码中搜索。输出 token 和推理字符减少,说明 agent 在整洁侧生成更紧凑的 patch,而不是用冗长的补丁覆盖不确定性。
file revisitation 下降 34% 是另一个信号。当 agent 反复重读同一个文件,通常意味着它需要重新确认上下文、检查副作用、对照邻近代码。在整洁侧,这种来回确认的动作明显减少。对 code review 来说,agent 的每次重读都可能对应一次上下文漂移。
HN 社区的质疑集中在三个方向上。核心不是否定研究价值,而是界定它能回答什么、不能回答什么。
第一个问题是 AI 合成的 clean/messy pair 是否代表真实代码。论文用自动化工具构造整洁度差异。真实世界里的脏代码,往往来自业务退化、多人维护、框架迁移和历史事故。它不是单一维度的 rule violation 能完全捕捉的。
第二个问题是作者没有在每个任务完成后,跑原仓库的所有无关测试来检查回归。作者在 HN 讨论中承认了这一点,说这是一个 oversight,并补充:“But it could have gone either way. We don’t know.” 这意味着我们不清楚整洁侧和脏乱侧的非目标模块,是否受到了不同程度的连带破坏。
第三个问题是利益相关。SonarSource 的主营产品是静态分析工具。这层关系不等于研究有错,但它会影响问题定义。用 rule violation 数量来衡量整洁度,本身就带有静态分析工具的视角。
社区也贡献了独立于论文的工程经验。多位开发者提到,agent 不能把整个代码库塞进上下文,它仍然要像人一样搜索、读文件、追调用链。在这种限制下,命名方式、文件位置、模块边界和 locality 会直接影响搜索成本。另一些人指出,遗留代码和混合模式的代码库会污染 agent 行为。agent 容易模仿上下文中先看到的旧模式,而不是项目当前期望的写法。
把论文结论和工程实践放在一起看,有几个判断逐渐清晰。
不要为了 agent 搞表面的 clean code。把代码擦得整洁但逻辑不变,对通过率影响有限。但如果改动减少了间接引用、死代码和旧模式,agent 的导航成本确实会下降。关键不是看起来干净,而是减少歧义。
可执行验证比对 agent 喊话更有效。在 OpenAI Codex best practices 里,官方建议 AGENTS.md 包含仓库布局、build/test/lint 命令、工程惯例和完成定义。AGENTS.md 生态也强调 agent 需要明确的构建步骤、测试和约定。Claude Code best practices 的建议是写测试、跑 lint 和类型检查、review scope。这些建议的共同点是给 agent 一个机器能验证的反馈回路,而不是一段自然语言描述。
Aider 的 lint/test 文档 把自动 lint 和测试设计成 agent 的反馈 loop。agent 生成代码后立即跑检查,失败就修正。Martin Fowler 在 sensors for coding agents 中的观察也很实用:agent 倾向复制粘贴,不会自动重构,需要确定性的传感器发现这些问题。
投入产出比最高的几件事并不神秘:保持单一事实源,不要在多处维护同一逻辑的不同版本;清理死代码和已废弃的旧模式,因为 agent 会把它们当活代码对待;显式标注模块边界和编码约定,让文件级和函数级的上下文窗口天然包含正确的信号。
回到这篇论文。干净代码对 agent 的影响不是通过率魔法,而是上下文成本压缩。token 消耗、文件重复访问、patch 的紧凑程度,这些指标直接影响开发体验,但工程团队容易忽视它们,因为它们不在任务成功或失败的直观感受里。
问题不该问要不要为了 AI 写干净代码。更好的问法是:哪些工程纪律能同时帮助人和 agent 消除歧义,哪些只是把代码改得看起来干净。
在这个框架下,为 agent 写干净代码不是新宗教,也不是伪需求。它更接近把过去给人类维护者的工程纪律,改写成机器也能消费的上下文基础设施。