过去一年多,我在项目开发里用了很多 Agent。
小项目里的体验很容易让人上瘾。把需求交出去,一会儿就有代码。跑一遍测试,再让它自己修两轮,事情好像就结束了。模型越换越强,Plan 也越写越细,我一度觉得,大型项目里的问题大概只是上下文还不够长、指令还不够清楚。只要提前规划得足够周全,Agent 就能沿着路线一直做下去。
最近半年,我越来越不相信这件事。
让我改变主意的,是一次很普通的评价代码问题。它没有崩溃,没有越界访问,没有类型错误,甚至很容易得到一套全绿的测试。隔了一段时间重新检查时,我才发现,我的 Agent 从第一天起就在代码中埋下了一个定时炸弹。
一、Agent 时代,软件工程的慢环节已经变了
1.1 由相似度计算偏差引发的思考
当时我要比较两条树结构路径的重合程度。我希望用 F1 Score。参考路径里的节点漏掉了要扣分,预测路径凭空多出节点也要扣分,Precision 和 Recall 两边都得顾到。
我的两页 A4 Plan 里,关于这个细节的指令是。
当两条路径相似度超过某个阈值以后执行后续操作。
Agent 最后把相似度计算方法写成了 Recall。
这个选择甚至说得通。只看那句 Plan,很难指着它说,你怎么能这样理解。麻烦也正在这里。程序运行正常,结果落在 0 到 1 之间,函数名和变量名都像那么回事。测试若由同一个 Agent 顺手补上,也很容易通过。但这就是错的。
用一个很小的例子就能看出差别。
reference = [A, B]
prediction = [A, B, C, D]
overlap = 2
precision = 2 / 4 = 0.50
recall = 2 / 2 = 1.00
F1 = 2 × 0.50 × 1.00 / (0.50 + 1.00) ≈ 0.667
阈值设为 0.8,Recall 会放行,F1 不会。
这个例子手算只需要半分钟。我当时没有把它明确写进 Plan。F1 在我脑子里太理所当然了,对于 GPT-5.6 Sol 级别的模型,这个细节甚至没有进入我的风险清单。整个项目完成以后,我做了一次全面重构和审查,才发现这个早期潜伏的小问题。这意味着我的几乎全部数据都要重算。
这次错误让我后怕的地方也在这里。明显的坏代码会报警。合理的误解却能通过类型检查,得到测试保护,还可能安静地改变全部研究结果。
后来我把近半年遇到的其他问题放到一起看,发现它们是共通的。
- 测试全通过,含义却错了。
- 项目越来越大以后,Agent 修好一个地方,又不小心弄坏另一个。后一处通常很难察觉,我们还会对已经审过的代码保留过高的信任。
- 多个 Agent 并行开发时,代码数量涨得太快,人根本审不完。
- 项目经验虽然被留在 Skill文档里(比如CLAUDE.md 和 AGENTS.md),但是文件越写越长以后,模型照样会漏。
- 每一次改动都能运行,系统的整体结构却一点点变形。
过去我会分别处理它们。测试有问题就补测试,Agent 绕圈就重开会话,规则漏了就再往文档里加一条。
任务推进得越来越快,我心里却越来越不安。我无法确认代码中还藏着多少同类错误。
暑假期间,我专门调研了这个问题。我读了 Addy Osmani、Robert C. Martin、Birgitta Böckeler、Peter Naur 和 OpenAI 团队的博客与访谈。Addy Osmani 曾任 Google Cloud AI 总监。Robert C. Martin 也就是大家常说的 Uncle Bob,是《代码整洁之道》的作者。Birgitta Böckeler 是 Thoughtworks 的 Distinguished Engineer。Peter Naur 获得过 2005 年图灵奖。
读完这些材料以后,我发现这些问题可以被统一地总结为:
Agent 生成代码的速度,已经超过了我们为代码建立可信证据的速度。
写代码曾经是软件流程里最慢的一步,许多工程制度都按这个速度长出来。Agent 先把代码供给大幅推快了。定义意图、验证行为、理解系统和承担后果的速度却几乎没变。原来的慢环节没有消失,它挪到了代码生成之后。
这个问题只是我个人碰巧踩中的坑吗?
1.2 2026 年的一些统计数据
Faros AI 分析了大约 22,000 名开发者和 4,000 个团队。AI 确实让工程师完成更多 PR,产生更多代码。团队从低 AI 使用率走向高使用率时,也出现了几组很扎眼的变化。
- code churn(代码反复修改) 增加 861%
- incidents / PR (单位代码改动带来的线上事故)增加 242.7%
- 每位开发者的 defect rate (代码中出现 bug / defect 的比例)从 9% 增至 54%
- median review duration(代码审查耗时的中位数) 增加 441.5%
- 未经 review 就合并的 PR 增加 31.3%
尤其是最后一个数字。公司并没有集体决定放弃 code review。代码产出的速度超过了 review 系统的吞吐量,队列越积越长,一部分改动最后只好在几乎没人认真阅读的情况下进入代码库。
CodeRabbit 比较了 470 个开源 PR,其中 320 个有 AI 参与,150 个完全由人编写。AI 参与的改动平均包含约 1.7 倍的问题。逻辑与正确性问题多约 75%,可读性问题超过三倍,安全问题也更常见。
Addy Osmani 在文章里还引用了 GitClear 的一组数据。高频 AI 用户的原始代码产出增加到未使用AI时的4倍,但同时真正交付的代码增幅却只有约 12%。这两个数字的口径并不一样,选择偏差也需要考虑。它们放在一起,至少提醒了我一件事。
4× code ≠ 4× value
生成出来的代码并不会自动变成交付价值。中间还要经过测试、理解、修改、验证和 review。代码越多,这几项工作的总量也会跟着涨。
Faros AI 和 CodeRabbit 都在销售相关工程产品,GitClear 的比较也有样本选择问题。这些统计适合看作风险信号,不能直接当成所有团队的因果结论。可它们和我自己的经历指向了同一处。代码生产已经提速,建立可信证据的办法还没有跟上。
二、从资深代码专家的博客和访谈中看到的
2.1 测试全通过,含义却错了
F1 被写成 Recall 以后,我最先想到的补救是多写测试。这个方向没有错,问题落在测试的答案从哪里来。
如果 Agent 先写出 Recall,再根据这段实现补单元测试,它会挑出一组适合 Recall 的输入,或者直接把实现结果抄成期望值。自动检查全部通过。覆盖率越高,这套测试还可能把错误含义守得越牢。
Addy Osmani 提到过一种相似的改动。Agent 先改变程序行为,自动化检查报错了以后,又把断言改到适应新行为。两百个测试最后全部通过,页面也很安静。此时最该先看的,往往是测试为什么跟着变了。
Birgitta Böckeler 对高自治流程里的行为验证也很谨慎。许多流程会让 AI 写测试,接着跑覆盖率和变异测试,最后再请人试一下。层数看起来不少,其中多层仍然压在 AI 自己写出的预期上。她还没有看到一种通用的行为 harness,足以让人在各种项目里放心撤掉监督。
这里坏掉的是 oracle,也就是测试用来判断对错的标准。出题人和答题人共享了同一次误解,绿灯只能证明二者相互一致。
Uncle Bob 的 gauntlet 给出了一种处理思路。Specification Agent 先把人的需求整理成 Gherkin 场景和 QA 流程。Coding Agent 再写单元测试与实现。Cleaner 检查复杂度并重构。Hardener 用变异测试攻击测试套件。最后的 QA Agent 从用户界面真正操作系统。
这条pipeline的价值来自证据差异。写代码的 Agent 想把功能做完,Hardener 巴不得测试露馅,QA 又站在用户视角看系统。Uncle Bob 自己仍会看 Gherkin 验收场景和 QA 步骤,有时细读,有时抽查。系统应该做什么,这一层没有完全交出去。
另一个 Agent 可以帮助找错,却未必形成独立证据。同系列模型、相近提示和同一份上下文,往往会共享盲点。更可靠的 oracle 可以来自人确认过的公式、手算结果、小型参考实现、带已知真值的模拟数据、人工标注或外部规范。
回到 F1 的例子,只要把那组两节点对四节点的数据提前写成验收测试,Recall 就无法继续冒充 F1。一个测试值不值得信,先看它能不能挡住眼前最合理的错误答案。
2.2 项目越大,Agent 越容易在修复里绕圈
Matt Pocock 在访谈里问过 Uncle Bob 一个很诱人的问题。AI 写得这么快,我们为什么还要在意烂代码,能不能一路顶着 bug 冲,直到没有 bug 为止。
Uncle Bob 试过。他让 Agent 一项接一项往下做,先不收拾前面留下的结构。很快,Agent 修好一个地方,又弄坏另一个。它转去补第二处,第三处跟着出问题。几处 bug 轮流冒头,Agent 开始绕圈,速度也越来越慢。最后仍然要有人进去,把前面留下的结解开。
这段经历把整洁代码从审美问题拉回了开发速度。
Martin Fowler 很早就用 cruft 描述代码里逐渐积累的杂质。内部质量不会直接出现在用户眼前,却会决定下一项功能有多难做。结构清楚时,开发者只需理解几个模块。结构混乱以后,一个小改动也可能要求读懂大片代码,还更容易带来意外破坏。
Agent 也要付这笔账。混乱的代码库会迫使它搜索更多文件,装入更多上下文,同时记住许多没有写下来的关系。它没有人的疲惫感,却会在这些关系里不断打补丁和回归。模型更强,账单可能来得晚一点,不会凭空消失。
Uncle Bob 在二十多年前就做过一件很适合 Agent 的事。他设计过一个叫 CRAP 的指标,把函数的圈复杂度和测试覆盖率放在一起算。函数越复杂,分支越多,测试又管不住它,分数就越难看。
他曾在一个大型项目上运行 CRAP。工具很成功,一口气揪出许多糟糕函数。随后才是麻烦。每个函数都要有人读懂、重构、补测试,再确认行为没有改变。清单完全正确,人工成本高得做不起,他只好把这个想法搁下。
变异测试也曾卡在同一笔成本上。工具会故意把减号改成加号,把小于改成大于,把相等改成不等,再跑一遍测试。代码已经被动坏,测试理应失败。若它仍然全绿,这个变异体便活了下来,说明测试没有管住那段行为。一次完整测试跑几分钟,几百个变异体足够跑一夜。第二天还有一张存活列表等着人逐个处理。
到了 2025 年底和 2026 年初,Uncle Bob 重新捡起这些工具。Agent 可以跑 CRAP,再逐个清理高分函数。变异测试找到存活项以后,也可以让 Agent 补上能杀死它们的测试。二十年前太贵的工程纪律,如今有了一批不会厌烦的执行者。
这类工作很少出现在 Agent Coding 的演示里。重构旧函数、消除重复、补边界测试和整理文档,没有一项看起来像新功能。它们会决定 Agent 下一周还能不能保持今天的速度。代码质量在这里是一项生产条件。
2.3 代码生成的数量涨得太快,人根本审不完
Addy Osmani 维护着几个受欢迎的开源项目。Agent 普及以后,他每天收到的 PR 多到没法一份份仔细看。队列就在那儿,人一天只有那么多小时。
传统 code review 有个不太起眼的前提。资深工程师读一段初级工程师写的代码,通常比对方写出来快。代码缓慢产生,review 还能追在后面。团队成员也会在看 diff 的过程中逐渐学会这套系统。
Agent 改变了这个速度关系。它生成上千行代码的时间,可能还不够人把变更说明读完。团队的代码产能增加了,对每项改动建立信心的能力却没有同步增加。第一章里的 review 时长和零审查合并数据,正是这个队列在许多团队里的样子。
Addy 没有继续假装自己能够公平地看完所有 PR。他会先让 Claude Code 或 Codex 过一遍,把一批 PR 分成大致可以合并、仍需修改和高风险几类。轮到他自己时,低风险项快速确认,高风险项认真看。
他没有把原来一小时的 review 压成四十分钟。他把这一小时重新切了一遍。过去十个 PR 也许各分到六分钟。现在,多数时间会留给那一两个一旦出错就很难收场的改动。
我读到这里时,attention allocation 这个词才有了分量。AI 先整理 PR,也替他整理了有限的注意力。机器把队列按风险摊开,合并决定仍在他手里。
风险取决于具体处境。一个周末 side project、刚开始有用户的产品、运行十年的关键系统,检查深度当然不同。实验室里的代码也一样。改一张内部示意图的配色,和改一段决定论文主结论的评价函数,不能分到同样多的人工注意力。
Addy 还提高了进入人工 review 的门槛。提交者要先说明改动目的,带上真实运行过的测试结果,控制 diff 的大小,并解释测试变化。AI reviewer 适合做第一轮 sensor,给出风险线索和可疑位置。最后点 merge 的人仍要知道自己为什么愿意承担这次风险。
这个办法承认了一个不太舒服的事实。人已经读不完全部 AI 代码。严谨不再等于每个 diff 平均用力。有限的时间要留给风险半径大、错误难发现、后果又难回滚的部分。
2.4 规则文件越写越长,模型照样会漏
Agent 漏掉一条规则以后,人很自然会把它补进 CLAUDE.md 或 AGENTS.md。再漏一条,再加一条。文件慢慢从一页变成十页,几乎每句话都标着重要。
长上下文里的信息不会得到同样多的注意。Lost in the Middle 研究发现,信息放在上下文开头和结尾时,模型往往更容易利用,落在中间时表现会下降。模型和窗口都在更新,这个具体曲线会变化。把全部项目经验一次倒进提示词,依然会遇到优先级不清、内容过时和检索困难。
OpenAI 的一个小团队在百万行 Agent-first 项目里碰到了同样的问题。他们用约五个月做出一个有真实用户的产品,代码库达到约一百万行,合并约一千五百个 PR。项目最初由三名工程师推动,应用逻辑、测试、自动化检查、文档、可观测性配置和内部工具都由 Codex 生成。团队估算,完成这些工作所需的时间约为手写代码的十分之一。
早期进展却没有数字看上去那么顺。Codex 能写代码,环境没有准备好。它看不到需要的工具,也摸不清内部结构。高层目标落进代码以后,缺少一条可观察、可验证的路。团队每次看到 Agent 失败,都会追问它缺了什么能力,以及这种能力能否变成项目里看得见、用得上的东西。
他们最初也想把知识集中塞进 AGENTS.md。文件越长,占用的上下文越多。内容很快过时,Agent 又分不清哪些规则仍然有效。后来 AGENTS.md 被缩到约一百行,只充当入口地图。
Agent 先从地图知道系统有哪些领域,架构说明、产品规范、执行计划和技术债务记录分别在哪里。任务走到哪一块,再去读对应文档。知识没有减少,进入当前上下文的内容变得更有针对性。
Uncle Bob 的多 Agent 做法也有相近作用。他倾向于把任务切得更小,让一个 Agent 出生、完成单一工作,然后结束。下一个 Agent 用干净的上下文接手已经留下的工件。启动和交接会花时间,却能减少一场长会话里逐渐堆积的无关信息。
这两种做法共同改变了一件事。AGENTS.md 不再承担百科全书的职责,长 Plan 也不必预言整个项目。入口文件负责指路,版本化文档保存事实,小任务控制当前上下文。真正不能违反的规则继续往测试、类型、lint 和依赖检查里下沉。
2.5 每一次改动都能运行,系统结构却一点点变形
Thoughtworks 的 Distinguished Engineer Birgitta Böckeler 做过一个很有意思的实验。她用 AI 重建一套内部社区分析仪表盘。技术栈包括 TypeScript、Next.js 和 React,后端还要连接几个外部 API。她没有先写一大本可维护性规范,而是一点点往项目里加 sensors,观察什么反馈能帮 Agent 保住结构。
第一个让她警惕的信号很朴素。一个小改动开始触碰越来越多文件。
她只想改变用户选择日期范围的方式,Agent 却改了四十多个文件。顺着 diff 往下看,核心请求参数在每一层反复传递。Agent 早就建过一个封装参数的对象,又没有坚持使用,项目里留下了半套抽象和半套复制。
三个后端 endpoint 的 route 文件也几乎一样。人写到第三份时,多半会觉得不太舒服,Agent 没有这层不适,它继续复制。前端第三个页面调用后端时,又绕开前两个页面已经使用的 hook,重新搭了一套。每一处都能跑,错误处理和今后的修改点却分开了。
这和 2.2 节的绕圈有联系,关注点稍有不同。CRAP 盯着函数复杂度和局部测试,Birgitta 看到的是系统级漂移。每个局部选择都说得通,放到全局以后,依赖方向、职责位置和复用方式已经慢慢散开。
她把 Agent 周围的工程条件分成 guides 和 sensors。Guide 在动手前指路,固定脚本、模板、代码生成器、架构说明和示例都属于这一类。Sensor 在动手后检查结果,类型、测试、lint、依赖规则、复杂度检查和 secret scan 都能提供反馈。
她和 Agent 一起给 dependency-cruiser 写了规则。Clients 层不能反向依赖 services 层。Agent 后来又越过边界几次,每次都立刻收到一个确定信号,然后自己改回来。Import 方向、目录层次和文件命名能够明确判断,交给工具比在 Markdown 里写一句“请遵守分层架构”可靠得多。
工具也有盲区。依赖分析知道谁 import 了谁,看不懂两段代码在语义上重复,也很难判断某项职责放错了位置。Birgitta 又运行了模型审查。第二次独立运行找出了第一次漏掉的新问题。模型能帮助闻出结构上的异味,输出会波动,重要结论需要复查。
OpenAI 团队也把架构边界写进项目的拒绝条件。业务领域有明确层次和依赖方向,自定义 linter 与结构测试会拦住越界。外部数据要在边界解析,日志必须结构化,schema 命名、文件大小和可靠性要求也有检查。Agent 对局部实现有很大自由,承重的边界不能随手挪动。
高吞吐还会迅速复制代码库里已有的模式,好的坏的都一样。OpenAI 团队起初每周五拿出约五分之一的时间清理 AI slop。后来连集中清理也跟不上,他们便把反复出现的质量判断整理成 golden principles,让后台 Agent 定期扫描偏差,更新质量评分,再提交一批很小的重构 PR。
架构无法只靠一份写得漂亮的说明保住。清楚的 guide 让正确路线容易找到,确定性的 sensor 拦住能形式化的越界,模型审查和人工抽查处理那些难以写成布尔条件的问题。项目还需要固定的小扫除,免得今天的一份复制在下个月长成二十份。
三、把这些经验装进一次真实改动
五种问题会在同一次任务里一起出现。含义可能被猜错,代码可能牵动太多文件,review 时间有限,规则又可能沉在上下文中间。我把资深编程专家们在应对上述问题时的策略总结成了一个pipeline。
3.1 动手前,先写一张短的修改约定
这份文档不需要写全实现。它只把容易被合理猜错、出错以后又代价很高的决定提前摆出来。
先写清哪项行为或结果要改变,再划掉本次明确不做的部分。公式、单位、方向和标签若不能让 Agent 猜,就单独列出。接着准备一个很小的输入,让最常见的错误算法暴露出来。无论怎样实现都应该成立的关系,也一起写下。
范围同样要明确。Agent 可以改哪些目录,哪些文件不能碰,验收时必须运行什么,最后要带回哪些证据,都在开始时约定。
把 F1 那次任务重新填一遍,大概会得到下面这张卡片。
目标和边界
计算预测路径与参考路径的节点重合 F1,再按阈值判断是否匹配。本次不改树遍历、路径生成、阈值来源和下游动作。
不能猜的定义
Precision 等于 overlap 除以预测路径长度,Recall 等于 overlap 除以参考路径长度,F1 取二者的调和平均。空路径如何处理要写明,根节点算不算、重复节点怎样处置也要定下来。
专门卡住 Recall 的例子
reference = [A, B]
prediction = [A, B, C, D]
threshold = 0.8
precision = 0.50
recall = 1.00
F1 ≈ 0.667
一直应该成立的关系
两条相同路径得分为 1。交换 prediction 和 reference 后,F1 保持不变。Overlap 不变时,只给 prediction 增加无关节点,F1 不能上升。得分始终落在 0 和 1 之间,空路径组合按照约定返回确定值。
风险和交付证据
这项改动会改变样本匹配和后续统计,应该按最高风险处理。验收测试先由人确认,再冻结,实现 Agent 不能悄悄修改。合并时要带回手算结果、属性测试、旧数据上的差异报告,并解释差异从哪里来。
这张卡片只有一页。它没有试图预先规定所有代码细节。它保住的是那些一旦猜错,程序仍可能顺利运行的分界。
3.2 实现过程中,小步推进,让约束及时说话
敏捷开发
Uncle Bob 用一美元改房子的故事反对过重的前期规划。假设打一遍地基只要一美元,建屋顶一美元,把厨房搬到另一边也只要一美元。人多半会先做一点,站远看看,不合适就改。
Agent 把文本编辑和试错做得很便宜,一份超长 Plan 没必要背负整个项目。一个任务可以只新增一种明确行为,迁移一个接口,或者消掉一种重复。做完以后先看证据,再看结构有没有变坏,随后才开下一项。
小步推进需要配上快速反馈。类型、单元测试、lint、依赖检查和关键不变量应该在每一小步后运行。允许改动的目录可以提前收紧。会话开始反复、遗忘和到处补丁时就停,让新的 Agent 从干净上下文和已经提交的工件接手。
AGENTS.md 在这里提供入口,详细知识留在对应文档。报错信息也值得多写半句。它既要告诉 Agent 哪条规则失败,也要给出允许的依赖方向或修复入口。一次确定性的失败,常常比再加一段 Prompt 更有用。
3.3 合并以前,先按风险决定需要多少证据
Birgitta 提过三个很实用的问题。改动影响有多大,出错机会有多高,出错以后是否容易发现。Addy 还会考虑代码要活多久,以及今后有多少人需要理解它。把这些条件放在一起,便能决定人该看多深,Agent 又该交多少证据。
我暂时把任务分成四级。
| 等级 | 常见改动 | 最低证据 | 人怎样介入 |
|---|---|---|---|
| T0 | 文案、注释、一次性格式整理 | lint、构建、快速抽查 | 确认范围,检查是否出现意外文件 |
| T1 | 局部界面、低影响工具函数 | 单元测试、结果截图或样例 | 看边界条件与测试变化 |
| T2 | 跨模块逻辑、数据管线、公共 API | 回归测试、依赖检查、端到端证据 | 审查接口、数据流和影响面 |
| T3 | 评价指标、标签映射、隐私、安全、论文主结论 | 独立 oracle、区分性反例、不变量、双重核验 | 人主导定义并拥有合并决定 |
风险应在任务开始时写下。T3 任务从一开始就准备独立 oracle,验收证据不能静默修改,允许触碰的范围也会收紧。T0 没必要背上整套重型流程。
任务完成以后,Agent 还要交一组证据。它先说明改了什么,哪些地方没有动,再列出真正运行过的命令和结果。关键样例的期望输出与实际输出摆在一起。测试里新增、删除、跳过或放宽的断言要单独解释。影响到的文件、依赖、性能和迁移也要能够看见。
这组证据会给 review 指路。人先判断证据够不够,再去读风险最高的 diff,不必在几千行代码里盲找重点。AI reviewer 可以补一轮风险扫描,不能替代独立 oracle,也不能替人按下最终的 merge。
3.4 合并以后,给代码库安排固定的小扫除
Agent 会照着项目里已有的样子继续写。一种坏模式若没有及时收住,很快会长出许多相似版本。季度末再发动大重构,成本和风险都很高。小规模清理可以每周进行。
重复实现、死代码、超大函数、依赖违规和过期文档都可以定期扫描。趋势也值得留意。同样大小的需求是否开始碰更多文件,PR 是否越来越大。关键测试可以周期性运行变异测试,不能只看覆盖度。反复出现的 review 意见,则可以逐渐整理成可检查的规则。
每个清理 PR 都应当小,原因说得清,也能很快回滚。同样大小的需求开始修改更多文件时,Agent 也许仍能把任务做完,项目已经变得更难改了。这个时候清理通常最便宜。
工程经验也可以按同一条路逐步升级。同一种错误第一次出现,先修好,并记下它为什么发生。第二次又来,补一个短 guide 或区分性样例。只要机器能够明确判断,就继续变成测试、lint、类型、依赖规则或脚本。只能在运行时看见的问题,交给日志、指标和抽样审计。始终无法稳定自动化,后果又很重,人工 Gate 便要留下明确负责人。
四、点 merge 的人要能回答一句话
AI review 很适合做 sensor。它可以给出风险线索,列出遗漏,也能把证据收拢。但它无法替人承担后果。
最后负责合并的人不必逐行背下所有实现。他至少要讲得出这项改动为什么做,最危险的含义由哪份独立证据守着,还有哪些部分没有验证。出错以后怎样发现,怎样退回,也应该有答案。
回到开头那次 F1 和 Recall 的错误。Plan 漏掉了一个我自己都没有意识到需要写的定义。测试若跟着实现生成,会共享同一份误解。代码量一大,review 的注意力又会被摊薄。长 Prompt 未必记得住那条规则,项目若很乱,一个局部修复还可能牵出别的问题。
办法若只剩下“下次把 Plan 写细一点”,走不了多远。一份自然语言规格永远有没写出来的地方,Agent 又很擅长给空白处填上一个合理答案。我们需要维护一条完整的信任链。意图怎样落地,证据从哪里来,架构怎样限制改动,最后由谁判断这次风险可以接受,每一处都要有人或工具接住。
Addy 把人的时间从平均 review 里拿出来,留给高风险 PR。Uncle Bob 用 Agent 去执行二十年前做不起的工程纪律。Birgitta 把能形式化的要求做成 sensors。OpenAI 团队把模型放进一个能够观察结果、会拒绝越界状态的工程环境。Naur 留下的提醒更老,也最难处理。代码之外,总得有人知道它为什么这样长。
毫无疑问 Agent Coding 时代一行代码都不看是大势所趋。这份乐观现在多了一些工程条件。写和试可以多交给 Agent,那些人不爱跑的检查也让它跑。人的时间需要留给含义、证据和风险。架构与最后的后果,仍然要有人接住。
Uncle Bob说,从二进制到汇编,到C、C++,到Python,到自然语言,每一次抽象层向上提升,处在更低层级的人都会抱怨。他们会说:“这会毁了一切。我们甚至都没工作可做了。编程变得这么简单,五岁小孩都能写代码了。” 不,不是的。同样的规则依然适用,所有这些编程基础之所以存在,都是出于同样的原因。你今天扔掉的那些规则,一年之后,很可能还是会从地上把它们捡起来,掸掉上面的灰尘,然后重新想起:为什么当初需要这些东西。
代码正在变便宜。理解、证据和责任还没有。
项目越大,模型有多会写只决定起跑速度。我们能不能一直知道它写对了什么,才决定这条路能走多远。
参考资料
- Addy Osmani 关于 Agentic Code Review 的文章
- Faros AI 的 2026 AI Engineering Report
- CodeRabbit 的 AI 与人类代码生成比较报告
- Matt Pocock 与 Robert C. Martin 关于软件基础和 AI 的访谈
- explainx.ai 对 Uncle Bob 代码 gauntlet 的整理
- Birgitta Böckeler 关于 coding agent harness 的文章
- Birgitta Böckeler 关于 maintainability sensors 的文章
- Birgitta Böckeler 关于代码责任的文章
- OpenAI 团队关于 Agent-first 工程的记录
- Peter Naur 的 Programming as Theory Building
- Lost in the Middle 论文
- Martin Fowler 关于内部质量与修改成本的文章
- Best Practices for Scientific Computing