作者:Mario Zechner,Pi-Mom 作者,libGDX 开源游戏框架创始人,独立开发者、技术教练,近年专注 AI 与 agentic 编程领域。

大约一年前,真正能帮你从头构建完整项目的 coding agents 出现了。Aider 和早期 Cursor 这样的前身更早就有了,但它们更像助手,而不是 agent。新一代工具非常诱人,我们很多人花了大量业余时间,去实现那些一直想做但没时间做的项目。
我觉得这没什么问题。用业余时间做东西本来就很快乐,而且大多数情况下你根本不需要在意代码质量和可维护性。这也是学习新技术栈的好方法。
圣诞假期,Anthropic 和 OpenAI 都发放了一些福利,把人们钓进他们那让人欲罢不能的老虎机。对很多人来说,这是第一次体验 agentic 编程的魔力,这个圈子也在迅速扩大。
现在,coding agents 也进入了生产代码库。十二个月过去,这些”进步”的后果开始浮现,以下是我目前的看法。
一切都坏了
这些都是道听途说,但软件确实越来越像一团烂泥——就连大型服务的正常运行时间也开始跌破 98%,成了家常便饭而非例外。用户界面出现的那些 bug 离谱到你会觉得 QA 团队是睁眼瞎。我承认,这种情况在代理出现之前就有了,但我们似乎在加速走向深渊。
我们看不到公司内部发生了什么,但总会有风声漏出来。比如据报道的这次疑似由 AI 引发的 AWS 故障。AWS 立刻出来「纠正」,然后又悄悄在内部跟进了一个九十天重置计划。
微软 CEO Satya Nadella 一直在鼓吹微软有多少代码现在是 AI 写的。虽然没有直接证据,但 Windows 越走越烂,微软自己似乎也心知肚明——看看这篇博客文章就知道了。
那些声称产品代码 100% 由 AI 生成的公司,持续交付出你能想象的最烂的东西。不点名了,但几 GB 的内存泄漏、UI 花屏、功能彻底失效、崩溃闪退——这可不是他们以为的质量勋章,也绝对不是”让 agent 包办一切”这个白日梦的好广告。
小道消息越来越多,来自大大小小的软件公司,说他们用 agentic 编程把自己逼进了死胡同:没有代码审查,设计决策外包给 agent,堆出数不清的没人需要的功能,就这样。
我们不应该怎么用 agent,以及为什么
我们基本上已经把所有纪律和主动权统统抛弃,换来了一种上瘾——你最高的目标是在最短时间内生成最多代码,后果管他的。
你在构建一套编排层,指挥一支自主 agent 大军。你装了 Beads(一款 AI 代理编排工具),完全没意识到它基本上是卸不掉的恶意软件。网上都这么说,这才是正确的工作方式,不然你就是 ngmi(not gonna make it,注定出局)。你在 ralphing the loop。你看,Anthropic 用 agent 群搭了一个 C 编译器。是有点问题,但下一代 LLM 肯定能修好。天哪,Cursor 用一个 agent 营搭了一个浏览器。当然,它运行得不太稳定,偶尔还需要人来拨一下轮子。但下一代 LLM 一定能修好的,拉钩保证!分布式、分而治之、自主化、黑灯工厂(完全自动化的无人工厂),软件问题六个月内就解决了。SaaS 死了,我奶奶刚让她的 Claw 给她做了个属于自己的 Shopify!
我再说一遍,这套对几乎没人用的副业项目或许管用,包括你自己。也许真有人能把这玩意儿用在一个不是一坨垃圾、还有真实用户在用的软件产品上。
如果你是那个人,那我向你脱帽致敬。但至少在我身边的圈子里,我还没找到任何证据证明这玩意儿真的好使,也许我们都有技术问题。
零学习、无瓶颈、延迟暴露——小失误不断累积
agent 的问题在于它们会犯错。这很正常,人也会犯错。有时只是功能性错误,容易发现和修复,顺手加个回归测试还能得分。有时是代码坏味道,linter 抓不到的那种:多了一个没用的方法,定义了一个莫名其妙的类型,那边有段重复代码。单独看,这些都无伤大雅,人写代码也会犯这样的小失误。
但 AI 仔(clankers)不是人。人犯了几次同样的错误,最终会改——要么被人骂到学乖,要么自己走在真正的学习路上。
agent 没有这种学习能力,至少开箱即用没有。它会一遍又一遍犯同样的错误。取决于训练数据,它甚至可能以各种小失误为素材,创造出全新的失误变体。
你可以试着”教” agent:在 AGENTS.md 里告诉它别再犯某个错误,或者搭建一套复杂的记忆系统,让它查历史错误和最佳实践。这对某些特定类别的错误确实有效——但前提是你得亲眼看到 agent 犯了那个错误。
人和 AI 仔之间有一个更重要的区别:人是瓶颈。人不可能几小时内吐出两万行代码。即使人以很高的频率制造小失误,每天能往代码库里塞进去的失误量也是有限的,复合速度非常慢。而且通常,一旦小失误造成的痛苦大到无法忍受,人就会花时间去修——毕竟人是讨厌痛苦的。或者这个人被炒了鱿鱼,换一个人来收摊,痛苦就消失了。
换成一支 agent 大军,瓶颈消失了,人类的痛苦也消失了。这些本来人畜无害的小失误,突然以根本无法持续的速度滚雪球。你把自己从循环里移除了,根本不知道那些无辜的小失误已经汇聚成一个代码怪兽,等你感受到痛苦,一切已经太晚了。
然后有一天,你想加一个新功能。但代码架构——此时已经基本上是小失误堆成的山——根本不允许你的 agent 大军以正常运转的方式完成修改。或者你的用户开始向你咆哮,因为最新版本出了问题,删掉了一些用户数据。
你发现代码库已经无法信任。更糟的是,你让 AI 仔写的那数不清的单元测试、快照测试、端到端测试,同样不可信。唯一还能可靠判断”这东西能不能用”的方式,是手动测试产品。恭喜,你把自己坑了(连公司也一起葬进去了)。
复杂度贩子
你他妈完全不知道发生了什么,因为你把所有主动权都交给了 agent。你放任它们自由运转——而它们,是复杂度贩子。它们在训练数据和强化学习过程中见过太多糟糕的架构决策。你让它们来设计你的应用架构,猜猜结果是什么?
铺天盖地的复杂度,一团糟糕的货物崇拜式”行业最佳实践”大杂烩,等你意识到要控制局面,早就太晚了,而且还不止如此。
你的 agent 永远看不到彼此的运行情况,看不到你整个代码库,也看不到在它们做出改动之前你或其他 agent 做过的所有决策。因此,agent 的每次决策都是局部的——这正是上面说的那些小失误的根源:大量代码重复,为了抽象而抽象。
所有这些最终叠加成无可挽回的复杂度泥潭。这和人类造出的企业级代码库里那种烂局面一模一样——那些代码库走到今天这步,是因为痛苦分摊在数量庞大的人群身上,每个人承受的痛苦都没有超过”我必须去修这个”的阈值,个人甚至根本没有能力去修。组织对痛苦的容忍度极高,但这样的代码库,人类需要数年才能烂到那个程度——组织以某种扭曲的协同方式,随着复杂度一起慢慢演化,慢慢学会与它共存。
有了 agent 和两个人的团队,几周之内你就能到达同等级别的复杂度。
agentic search 召回率低
现在你寄希望于 agent 能修复这一团乱麻,重构它,让它焕然一新。但你的 agent 也招架不住了,因为代码库太大、复杂度太高,它们能看到的始终只是局部视图。
我说的不只是上下文窗口大小的问题,或者长上下文注意力机制在面对百万行代码怪物时的崩溃。这些是显而易见的技术局限,问题比这更隐蔽。
在 agent 尝试修复乱局之前,它需要找到所有需要修改的代码,以及所有可以复用的现有代码。这叫做 agentic search。agent 怎么做,取决于它有哪些工具:可以给它 Bash 工具让它用 ripgrep 在代码库里翻找,或者给它代码库索引、LSP 服务器、向量数据库。最终结果都差不多:代码库越大,召回率越低,而低召回率意味着代理实际上找不到它需要的所有代码,做不出一份好差事。
这也是那些代码坏味道小失误一开始就出现的原因:agent 漏掉了现有代码,重复造轮子,引入不一致,然后这些失误绽放成一朵壮观的复杂度烂花。
那我们怎么避免这一切?
我们应该怎么用 agent(目前,我是这么想的)
coding agents 是塞壬(Sirens,希腊神话中用歌声引诱水手触礁的妖怪):它们用代码生成速度和参差不齐的智能(jagged intelligence)勾引你,在简单任务上确实能以极快速度交出高质量结果。等你开始觉得”哦天哪,这玩意儿太强了,电脑,帮我干活!“——事情就开始走歪了。
把任务交给 agent 当然没问题。好的 agent 任务有几个共同特征:任务范围可以明确界定,agent 不需要理解整个系统;循环可以闭合,也就是说 agent 有办法评估自己的工作;输出不是关键任务,只是某个临时工具或内部软件,没有人的生命或收入依赖于它;或者你只是需要一只橡皮鸭来碰碰想法——本质上就是把你的想法扔给互联网压缩智慧和合成训练数据去弹一下。满足其中任何一条,你就找到了代理的完美任务——前提是你作为人类,是最终的质量关卡。
Karpathy 的 auto-research 用来给你的应用加速启动时间?很好!只要你清楚它吐出来的代码根本没有生产就绪。auto-research 之所以有效,是因为你给了它一个评估函数,让 agent 可以用某个指标(比如启动时间或损失值)来衡量自己的工作。但这个评估函数只捕获了一个非常窄的指标,如果你的评估函数本身有问题,代理会非常乐意忽略它没有捕获的所有其他指标,比如代码质量、复杂度,甚至正确性。
关键在于:让 agent 做那些无聊的事、那些不会让你学到新东西的事,或者去尝试各种你否则没时间去试的方案。然后你来评估它给出的结果,采用那些真正合理且正确的想法,完成实现。当然,最后这一步你也可以用 agent 来做。
我想说:他妈的慢下来,这才是正道。 给自己时间想清楚你到底在构建什么、为什么要构建它。给自己一个机会说:操,我们根本不需要这个。给自己设一个限额,每天让 AI 仔生成的代码量,不超过你实际能审查的量。
任何定义系统整体形态的东西——架构、API 等等——都要亲手写。也许用 Tab 补全找点怀旧感,或者和 agent 一起结对编程。待在代码里。因为亲手写下代码、或者亲眼看着它一步步被搭起来这个简单行为,会引入摩擦——而这摩擦会让你更清楚地理解你想构建什么,以及系统”感觉”起来怎么样。这正是你的经验和品味能发挥作用的地方,是当前最先进的模型还替代不了的东西。他妈的慢下来、承受一些摩擦,才是让你学习和成长的东西。
最终结果,会是持续可维护的系统和代码库,至少和 agent 时代之前我们的老系统一样可维护。是的,那些也不完美。你的用户会感谢你,因为你的产品现在令人愉悦,而不是一坨糟粕。你会做更少的功能,但都是对的功能,学会说不本身就是一种功能。
你可以睡个好觉,因为你他妈还知道发生了什么,还掌握着主动权。正是这种理解让你能够弥补 agentic search 召回率低的问题,从而得到更好的 AI 仔输出,需要更少的人工打磨。如果事情真的搞砸了,你能进去修。如果你最初的设计不是最优的,你也能明白为什么,以及如何将它重构成更好的东西,有没有代理,他妈的无所谓。
这一切都需要纪律,需要主动权。
这一切都需要人类。