





















本文永久链接 – https://tonybai.com/2026/07/12/does-code-cleanliness-affect-coding-agents
大家好,我是Tony Bai。
过去两年,关于“要不要写干净代码”的争论,在AI编程助手崛起之后似乎有了一个新的、看似合理的反驳:代码是给人看的,AI 又不嫌丑,能跑通不就行了?
这话听起来没毛病。毕竟绝大多数针对Coding Agent的评测——无论是SWE-bench还是它的各种变体——都只盯着一件事:任务做完了没有,Pass rate高不高。至于Agent在这个过程中翻了多少代码、读了多少遍文件、烧了多少token,几乎没人系统地问过,更没人问过一个更根本的问题:同一个任务,扔给同一个Agent,如果代码库本身“整洁度”不同,结果会不一样吗?
SonarSource的两位研究者决定把这个问题搞清楚。他们的研究背景数据本身就值得记一下:据他们引用的一项2026年的调研,在12.8万个GitHub项目中,已经有22%~29%能找到Coding Agent活动的痕迹——而距离第一批真正实用的编程Agent上线,还不到一年时间。AI 写代码,已经不是“会不会发生”的问题,而是“发生得有多快”的问题。而与此同时,在SWE-bench Verified这样的评测集上,一个任务平均要消耗大约400万个token,其中大部分是输入token。
换句话说:Agent 已经在大规模吃你的代码库,而且吃得很贵。这篇论文想搞清楚的是:你喂给它的代码库的“干净度”,会不会决定“这顿饭吃得贵不贵”。

这个问题不好回答,原因很朴素:你几乎找不到两个“除了整洁度之外完全一样”的代码库。同一个项目的两个版本,往往架构、依赖、测试覆盖都对不上,你根本没法把行为差异归因到“整洁度”这一个变量上。
研究者的解法是自己造出这样的对照组——他们称之为“最小对照对”(minimal pair):两份代码库,架构相同、依赖相同、外部行为(测试能否通过)相同,唯一的区别是代码整洁度不同。这个“整洁度”用SonarQube的规则违规数和认知复杂度来量化。
具体是怎么造出来的呢?两条流水线,方向相反:
Slopify(做旧管线):拿一份原本干净(经过静态分析把关)的代码库,模拟“如果这个团队从来没做过代码审查和lint检查,它现在会长成什么样”——分三步:先让代码能跑起来、测试能过;再探索每个目录写摘要;最后针对性地引入违规,比如把小函数内联回调用处、把逻辑复制到多个分支里、往文件里塞死代码。每一步改完都要重新跑测试,破坏行为的改动会被拒绝。
Vibeclean(翻新管线):反过来,拿一份天然生长出来的、违规一堆的代码库,像正经做代码审查一样把这些违规逐条修掉——去重字符串、删掉注释掉的死代码、替换过时的写法,遇到真正的“上帝方法”(比如200多行的switch分发器),就拆成命名清晰的小helper。
最终他们凑出了6组这样的对照代码库(3个Java为主,3个Python为主),其中一半是公开仓库(比如Apache Commons BCEL、Netflix Genie、CKAN),一半是SonarSource内部的私有代码库——后者是故意留的一手,用来排除“模型可能训练时见过这份公开代码”这种记忆效应的干扰。
在这6组代码库之上,他们又手工设计了33个任务,并且给自己定了三条硬规矩,保证测的是"整洁度"而不是别的东西:
每个任务在对照对的两侧各跑10次,用的Agent是Claude Code(Sonnet 4.6),总共660次试验。
先说一个可能让“整洁代码党”略感意外的结论:Agent的任务通过率几乎不受代码整洁度影响。干净代码上通过率91.3%,脏代码上92.1%,差了不到一个百分点。
也就是说,如果你只看“这个功能做出来了吗”这一个指标,代码整不整洁根本无所谓——Agent照样能在“屎山”里摸索出正确答案。这也解释了开头那种“AI又不嫌丑”论调为什么听起来站得住脚:如果你的评价标准只是“完成没完成”,那这个论调是对的。
但问题恰恰出在这里——完成任务的“过程”,两边天差地别。
在干净代码上跑任务,Agent的操作footprint全面收缩:
结合通过率没变这一点,一个直接的推论就是:Agent在干净代码上,是用更少的token做了同样的活。效率提升,不是靠少干活,而是靠少绕路。
如果说前面的token数字还只是"modest but consistent"(不算大但很稳定),真正炸裂的一个指标是文件重复访问率(file revisitation)——干净代码上,Agent回头重新读自己已经改过的文件的次数,减少了34%,而且这个方向在每一个代码库上都成立,跨度从-7%(CKAN)到-69%(Commons BCEL)。
研究者对这个现象的解读很值得玩味:“重复访问”更像是Agent对自己刚才那次修改“心里没底”的信号,而不是探索广度的体现。换句话说,在乱糟糟的代码里,Agent改完一处,心里犯嘀咕,又跑回去确认一遍;在干净的代码里,它改完就走,不带犹豫。
一个佐证是“读过的文件数”这个指标,在干净代码上反而略微上升(+3.2%),但per-repo的方向并不一致。一种合理的解读是:干净代码上Agent第一遍读得更广,但读完就下决心;脏代码上Agent一开始读的文件更少,但改完总要回去反复核实。
如果这篇论文只讲到这里,那结论会显得过于干净——“写干净代码就是省钱”,一个AI 时代版本的老生常谈而已。但作者们进一步把33个任务拆成了两条赛道,发现了一个真正有意思的细节。
为什么会这样?因为翻新管线处理“上帝方法”的方式,是把逻辑拆分重新分布到更多、更小的文件里,而不是把复杂度真正消灭掉。所以“干净版本”的热点代码,逻辑被拆得更细、分布更广,Agent省下了“理解一个巨大switch语句”的脑力,却得多跑几个文件去逐一定位和修改。
论文里给了两个对比案例特别能说明这个细节:
这个发现对开发者的启示其实很实在:“拆函数”这件事本身不是免费的。如果你把一个巨型函数拆成十个小函数,却没有解决真正的耦合和复杂度问题,只是把认知负担摊薄、挪了个地方,那么对Agent(以及对人)来说,导航成本未必会降低,甚至可能上升。真正有效的重构,是消灭复杂度,而不是把它切成更多份。
这里有个很容易被忽略但研究者非常严谨地处理了的细节:造对照代码库的过程中,注释和代码是一起被搬动的。比如某个内部代码库的“干净版”,比“脏版”多出了整整8000行注释——因为做旧管线在制造混乱的同时,顺手删掉了大量文档字符串和说明性注释块。
这就带来一个问题:如果不控制这个变量,前面所有关于“干净代码更省token”的结论,可能其实是在说“注释少的代码更省token”,而跟整洁度本身没什么关系——毕竟注释也是要被塞进上下文的。
研究者专门做了一次注释消融实验:人工把两侧代码库的注释量和抑制标记(比如# noqa、// NOSONAR、# TODO)拉齐,该删的冗余注释删掉,该补的缺失文档补回来,执行逻辑本身一字不改。结果是:
结论是:“干净代码更省token”这个效应,不是注释多少造成的假象,它是真的。
把上面这些拼起来,这篇论文给出的画面其实很清楚:
代码整洁度这件事,在Agent时代没有过时,只是换了一个记账方式。它不再决定“AI能不能帮你干活”(几乎不影响),但它实打实地决定了“AI帮你干这活要花多少钱、绕多少路”。7%~8%的token节省听起来可能不算惊艳,但要考虑到:这是在单个任务上的效应,而现实中的代码库要被Agent持续、反复地读取和修改。放大到一个团队一年内成千上万次Agent调用,这个数字会变成实打实的账单差异。而34%的文件重复访问下降,某种意义上更值得关注——它反映的不是“省钱”这么表面的东西,而是Agent对代码库“有没有把握”这件更本质的事情。
几个更具体的启示:
作为一篇技术解读,也需要提一下这项研究本身的边界,免得被过度解读:
研究者自己也很诚实地把这一点写进了论文:这不是一个“代码越干净AI越便宜”的简单等式,而是一个在足够大样本上才稳定显现的统计趋势,具体到某一次重构、某一个任务上,结果可能完全相反。
“写干净代码”这件事,曾经的理由都指向人:方便同事review、方便未来维护、方便新人上手。AI 编程助手的普及,给这个老话题加了一条新的、可以被量化的理由——代码的整洁度,现在也是AI在你的代码库里干活时要付出的一项计算成本。
它不会让不写测试的团队突然写测试,也不会让屎山项目突然被推翻重写。但至少,下次有人问“AI又看不出代码丑不丑,为什么还要写规范”,你可以把这篇论文甩给他:AI是真看不出“丑”,但它会为“丑”多绕路、多回头、多花token——而这笔账,最终是算在人类的信用卡上的。
资料链接:https://arxiv.org/html/2605.20049v1
还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 《从0 开始构建 Agent Harness》 将带你:
扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。

还在为“复制粘贴喂AI”而烦恼?我的新专栏 《AI原生开发工作流实战》 将带你:
扫描下方二维码,开启你的AI原生开发之旅。

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。