AI 编程AI Agent

模型越聪明,越容易在代码里的一行旧注释上内耗

用 Claude Code 或者 Cursor 改代码,我们可能都遇到过这种情况。比如我们只是想让 coding agent 去改一个按钮的样式,结果它自己去翻了很多毫不相关的老文件,甚至顺手改了几百行没人让它动的老代码。这时候我们往往会觉得这是因为现有的模型还不够聪明,等下一代推理能力更强的模型出来以后,这个问题自然就会得到解决。

结果在 2026 年 11 月 6 日,Google 的研发生产力团队发表了一项实测研究,用内部超过 91.3 万次真实编码会话的数据直接给了个相反的答案。他们比较同一个人在同一个代码模块里做同一类任务的表现,发现模型能力越强,反而越容易因源码里一行旧的 TODO 注释跑偏。

一旦智能体开始追踪一个它并不负责的历史注释,单次对话平均需要多执行 70% 的步骤,多消耗 77% 的 token。你在屏幕前等待的时间更是直接增加了 105%,相当于慢了一倍以上。

为什么模型越聪明,越容易对一行旧注释犯强迫症?

为什么你明明只让它改 A,越聪明的模型反而越爱自己加戏去查 B?这要从人类和大模型阅读源码的视角差异说起。

人类资深工程师脑子里自带一套注意力过滤器:知道对话框里刚敲的字是当前命令,源码文件里几年前留下的 TODO 只是前人没干完的历史背景。我们扫一眼旧注释就会直接跳过,不会停下来替前人还债。

但在大模型的上下文窗口里,所有文字地位相同。无论文字来自你的提问框,还是来自刚读进来的源码文件,模型都把它们看作同一平面上的上下文。更糟的是,TODO 注释在语法上天生就是一句未完成的祈使句,比如要求补上某项校验或支持某种格式。

以前的弱模型就像听话的木偶一样。你让它改第 50 行,它就改第 50 行,读完旁边的注释就忘了。现在的旗舰推理模型却有一种严重的优等生强迫症。它们在强化学习的训练过程中,因为两件事情反复拿到奖励:遇到阻碍时主动搜集线索,以及看到未闭环的任务时主动办完。

这位满脑子想立功的优等生走进了贴满陈年便签的老代码库,麻烦就来了。只要它在主任务上稍微遇到一点阻力,目光扫到旁边祈使句形态的 TODO,就会把这行旧便签当成破案线索或顺手能拿下的加分题。它立刻调起全局代码搜索、内部文档检索和工单查询工具,陷入跟历史遗留便签较真的算力内耗。Google 的统计显示,智能体接触到含这类注释的代码后,一旦擅自绕路去管闲事,有 40% 的情况会直接动手修改代码。

Google 博客披露的一个真实案例则把这个优等生强迫症展现得淋漓尽致。在那次会话的前半段,智能体自己刚刚查清楚一个事实:新版下载器已经在生产环境 100% 全量上线,旧版下载器 ModelDownloaderV1 早已废弃。

但在排查主任务的过程中,智能体恰好看到了这个废弃文件,发现里面有一条未关闭的 TODO,说需要在下载器里实现某个资格校验。由于新版的下载器为了模块解耦,采用了依赖注入设计,对具体的业务模型毫无感知,代码中自然没有这个业务相关的词。反而是已经死去的文件里,明码写着这个具体的指令。

智能体的强迫症立刻发作。它在代码库里搜出 4 个匹配文件,检索出 10 篇内部文档,然后直接动手修改了那份死代码。

直到人类工程师在对话里忍无可忍,当场质问它:你刚才自己都说新版已经全量上线了,为什么不改新版文件,反而去改 ModelDownloaderV1 这种旧文件?智能体这才认错,承认自己改了生产环境永远不会执行的死代码,还违背了新版架构解耦的设计初衷。

面对源码里三年前留下的待办注释,人类工程师一眼识别为历史遗迹直接跳过,而主动性更强的推理模型却把它当成当前指令,调起搜索与查单工具并动手修改废弃代码,导致等待时间翻倍。

既然旧便签害人,为什么不能写个脚本全撕了?

看到这里,你可能会有一个直接的想法。既然过期便签这么误事,那我们就写一个自动化脚本去工单系统里面查看状态,把所有已结案工单对应的 TODO 注释全部删掉不就好了吗?

根据 Google 的数据,在智能体自作主张绕路的情况下,确实有 41% 指向的工单已经关闭了。其中 32% 是前人修好了 bug 忘了把代码里的注释删掉,另外 9% 是早就决定废弃不修的死胡同工单。但哪怕面对这批已经结案的注释,我们真的不敢用脚本一键删光。这背后的原因是,程序员写注释有一个普遍习惯,往往在同一行 TODO 中同时记录未来要做什么和当前为什么不能动。

Google 博客里的另一个案例就踩中了这个坑。在那个例子里,Agent 读到 Android 兼容性测试的图形测试文件 SurfaceControlTest.java,看到一条要求补充测试 YUV420 图像格式的 TODO 注释,就放下手头的任务去查工单,结果发现工单早就关了,白跑一趟。

翻开 Android 开源项目的历史提交记录就能看清,这条注释是 2023 年 4 月一位工程师在修复量产手机测试崩溃时添加的,对应工单号 277348717。他把导致崩溃的 YUV420 图像格式从测试参数中删除,只保留 YV12 格式,同时关闭了这张工单。但在同一个代码提交中,他又复用了刚刚关闭的这个工单号,在函数上方添加了 TODO 注释。注释的前半部分提到将来至少需要把这个格式检查加回来,后半部分则提醒即使底层硬件缓冲区接口返回支持,某些设备上的图像读取器也不支持该格式。

这就造出了一个工程陷阱。虽然从代码入库的那一刻起,这个 TODO 所关联的工单就已经处于关闭状态,但它的后半句其实是整段代码中唯一的保命警告,用来提醒开发者下面那行测试代码为何只测试一种格式。如果自动化脚本发现工单已经关闭就把整行注释删去,这面承重墙也就塌了。下一个改代码的程序员或 AI 看不到硬件缺陷的警示,会以为测试覆盖不全,顺手把 YUV420 重新加入测试列表,量产手机上的测试崩溃就会再次重现。

Google 的大招只治了一半,我们今天该改哪两条规矩?

为了解决这个问题,Google 专门做了一个清理智能体。在提交删除任何一条过期注释的代码变更前,这个智能体会去交叉分析几年时间跨度内的工单讨论、文件改动和代码提交,确认没有隐藏的保命警告再动手。在 6 个月的运行中,它清除了几千条陈旧注释,人类评审员接受率超过 95%。

但这套大厂重型基建有一个明显的算术盲区。它最多只能帮我们清理掉那 41% 指向已关闭工单的假便签,却动不了还有 57% 指向真实未结案工单的真便签。

在那些让智能体擅自绕路的注释中,超过半数对应的是工单系统中真正未修复的遗留缺陷,因此没有任何自动化清理工具能删除这些注释。但只要这些真便签仍存在于源码文件中,满脑子想立功的强模型下次路过,依然会自作主张停下手头的工作,去替你查单甚至改代码。在这 57% 的真工单绕路中,同样有 39% 的情况智能体直接动手改了代码。

在未经请求的跑偏里,41% 指向已结案工单,靠拆开警告与待办即可清理;57% 指向真实未结案工单,静态工具无法删除,必须在规则文件里把行内待办锁死为只读背景。

控制这种行内注释的收益远比传统重构代码来得高。2026 年 5 月,SonarSource 进行过一项代码整洁度实验。他们发现,花大力气消除函数过长、认知复杂度过高等传统代码异味,大约能让编码智能体的输入 token 消耗减少 7.1% 到 10.7%。相比之下,放任一行 TODO 祈使句把智能体勾走,单次会话就要多烧 77% 的 token。

在看清优等生强迫症和承重墙混写这两个病根之后,我们不用搞 Google 那种翻陈年档案的系统。今天花 5 分钟在团队里立下两条规矩,就能同时堵住真假便签两边的坑。

第一条规矩写给模型,用来管住那 57% 的真便签。打开项目根目录的 AGENTS.md 或 CLAUDE.md,明确写入一条执行边界:源码文件里的所有 TODO 和 FIXME 注释都属于只读历史背景;只要用户没有在当前提问中点名要求处理,哪怕注释指向真实存在的缺陷,也严禁为了它去查工单、严禁跨文件搜索、严禁顺手修改相关代码。给优等生划清这道红线,它就能老老实实把背景放回背景。

第二条规矩写给人类自己,用来化解那 41% 的假便签。从今往后,代码里留注释要把保命警告和待办事项彻底分家。凡是解释某段代码为什么不能动的硬件限制或业务怪癖,一律用 WARNING: 或 NOTE: 单独成行;只有未来真要干的活才写 TODO:,这样工单一关就能放心删掉整行待办。遇到模块从旧版升级到新版、但暂时还不能删除旧文件的情况,直接在旧文件第一行醒目写上本文件已废弃且禁止修改。把承重墙和便签条拆开,再用几行规则管住过剩的好奇心,你的编码 Agent 才能少一点跟陈年旧账死磕的内耗,把算力花在真正该干的活上。

鸭哥每日手记

日更的深度AI新闻和分析