2026-03-25

能真正帮你搭出完整项目的 coding agent 出现在台面上,大概已经有一年了。更早也有 Aider 和早期 Cursor 这种前身,但它们更像助手,不太像 agent。新一代东西确实很诱人,我们很多人也确实花了大量业余时间,去做那些一直想做、但总没空做的项目。
我觉得这本身没什么问题。业余时间拿来做东西,本来就很爽;而且大多数时候,你也确实不用太在意代码质量和可维护性。它还能让你顺便学一门新技术栈,如果你愿意的话。
圣诞假期那会儿,Anthropic 和 OpenAI 都发了点免费额度,想把人勾进他们那个上瘾的老虎机里。对很多人来说,那是他们第一次体验到 agentic coding 的魔法。圈子越来越大了。
现在,coding agent 也开始进入生产代码库。12 个月过去,我们终于开始看到这一切“进步”带来的效果了。下面是我现在的看法。
一切都坏掉了
虽然这些都只是零散观察,但软件确实越来越像一堆脆皮垃圾了:98% 的可用性从“不能接受”慢慢变成了“差不多就这样”,连大服务都不例外。用户界面里还会冒出一些离谱得要命的 bug,按理说 QA 团队随手就该抓出来。我承认,这种事在 agent 出现之前就已经存在了。但现在我们显然在加速下坠。
我们拿不到公司内部的真实情况。但时不时总会有点东西漏到记者那儿。比如这个据说是 AI 导致 AWS 宕机 的说法。AWS 立刻出来“纠正”了。结果转头内部又搞了个 90 天重置。
微软 CEO Satya Nadella 这段时间也一直在说,微软现在有多少代码是 AI 写的。虽然我们没有直接证据,但 Windows 正在一路往沟里开的感觉,真的很强。微软自己似乎也认同这一点,看看这篇很有意思的博客文章。
那些宣称自己产品 100% 代码都已经由 AI 生成的公司,稳定输出着你能想象到的最烂垃圾。我就不点名了,但什么几 GB 的内存泄漏、UI 抽风、功能稀烂、各种崩溃——这可不是他们以为的“质量印章”。而且这对“让 agent 替你干完所有活”那个发烧梦,也绝对算不上什么好广告。
你顺着圈子里的风声越来越常听到:无论大公司还是小公司,都有人说他们已经被 agentic coding 逼进死角了。没有 code review,把设计决策外包给 agent,堆了一大坨根本没人要的功能。那不出事才怪。
我们不该怎么和 agent 一起工作,以及为什么
我们基本上已经把所有纪律和主导权都丢掉了,换来一种成瘾状态:你唯一的目标,就是在最短时间里吐出最多代码。至于后果,爱谁谁。
你正在搭一个 orchestration layer,想指挥一整支自治 agent 大军。你装了 Beads,完全没意识到那玩意儿基本就是个卸不掉的恶意软件。因为网上都这么说。你就该这么干,不然你就 ngmi。你在 ralphing the loop。看啊,Anthropic 用 agent 群编了个 C 编译器。虽然有点坏,但下一代 LLM 肯定能修好。哦我天,Cursor 用一大营 agent 搞了个浏览器。对,当然,它其实没怎么跑起来,中途还得人类偶尔上去扶一下方向盘。但下一代 LLM 肯定能修好。拉钩保证!分布式、分而治之、自主性、黑灯工厂,软件问题未来 6 个月内就会被解决。SaaS 已死,我奶奶刚让她的 Claw 给自己搭了个 Shopify!
再说一次,这套东西也许真能用在你那个几乎没人用、连你自己都不怎么用的 side project 上。也许世上真有某些人,能把这套东西整明白,拿来做一个不是热腾腾垃圾堆、而且真有真人在高强度使用的软件产品。
如果那个人就是你,那挺好,祝你成功。但至少在我身边这圈同行里,我还没见过这种玩法真的靠谱的证据。也可能只是我们都菜。
错误会不断复利,却没有学习、没有瓶颈、痛感还会延后
agent 的问题在于,它们会犯错。当然,人也会犯错。也许有些只是正确性错误,挺容易识别,也挺容易修。顺手再补一个回归测试,锦上添花。又或者是 linter 抓不出来的代码味道:这里一个没用的方法,那里一个说不通的类型,那边再来点重复代码。单独看,这些都不算什么。人类也会犯这种小蠢错。
但铁皮人不是人。人类犯同样的错,犯几次之后通常就会学会不再犯。要么是因为有人开始冲他吼了,要么是因为他自己真的在学习。
agent 没这种学习能力。至少开箱即用时没有。它会一遍又一遍地犯同样的错。取决于训练数据,它甚至还能把不同错误插值组合,整出崭新的花样来。
你当然可以试着教你的 agent。比如在你的 AGENTS.md 里告诉它,别再犯这个蠢错了。或者你调一套极其复杂的 memory system,让它去查以前的错误和最佳实践。对于某一类特定错误,这确实可能有用。但前提也是:你得先观察到它犯了这个错。
铁皮人和人类之间还有个更重要的区别:人类是瓶颈。人类不可能几个小时就拉出 20,000 行代码。即便这个人也会高频制造这种小蠢错,他一天之内能往代码库里塞进去的错终究是有限的。这些错会以非常慢的速度复利。通常来说,一旦这些蠢错带来的痛苦太大,这个讨厌痛苦的人类就会花点时间把它们修一修。又或者他被开了,换别人来修。总之,痛会消掉。
但如果你手里是一整支被编排起来的 agent 大军,就没有瓶颈,也没有人类痛感。这些原本微不足道的小蠢错,会突然以不可持续的速度疯狂复利。你自己已经退出了环路,所以你甚至不知道所有这些无辜的小蠢错已经聚合成了一个怪物级代码库。等你感觉到疼的时候,已经太晚了。
然后总有一天,你回过头想加个新功能。可这时候架构本身——到这个阶段,它大体上已经是由一堆小蠢错拼起来的了——根本不允许你的 agent 大军以一种还能正常工作的方式做出改动。又或者你的用户正在对你尖叫,因为最新版本里某个东西坏了,还把用户数据删了。
这时你会意识到,你已经没法再信任这个代码库了。更糟的是,你会发现那一大坨由铁皮人写出来的单测、snapshot 测试和 e2e 测试,同样不值得信任。最后唯一还可靠的“这玩意儿到底能不能工作”的度量方式,只剩下手动测试产品。恭喜,你把自己(还有你的公司)搞废了。
兜售“习得性复杂度”的商人
你根本他妈不知道发生了什么,因为你已经把所有主导权都外包给 agent 了。你放任它们自由驰骋,而它们就是复杂度商人。它们在训练数据和 RL 训练过程中见过太多糟糕的架构决策。你还让它们来给你的应用做架构。那结果会是什么?
就是一大坨复杂度:各种糟糕透顶的、货真价实的“行业最佳实践”邪教拼出来的缝合怪,而你在事态失控前根本没有及时收手。但事情甚至比这还糟。
你的 agent 看不到彼此的运行过程,看不到整个代码库,也看不到在它做改动之前你或其他 agent 曾经做过的所有决策。所以,agent 的决策永远都是局部的,而这正是前面那些小蠢错会出现的原因:大量重复代码、为了抽象而抽象的抽象。
所有这些东西会不断叠加,最后变成一坨无法挽回的复杂度烂摊子。和你在很多人类企业代码库里看到的那种烂摊子一模一样。那类系统之所以会走到那一步,是因为痛苦被分摊给了太多人。落到个人头上的痛感,通常还没高到“我必须得修这个”的程度。个人甚至可能根本没有能力去修。组织本身对痛苦的耐受度又高得离谱。但人类企业代码库要烂到那个状态,往往需要很多年。组织会和复杂度一起慢慢演化,形成一种精神错乱般的共生关系,并逐渐学会怎么和它共处。
而用 agent,只需要 2 个人、几周时间,你就能抵达同样的复杂度地狱。
Agent 式搜索的召回率很低
于是你开始希望 agent 能把这堆烂摊子修回来,重构它,让它重新变得干净漂亮。可这时候你的 agent 也已经搞不定了。因为代码库和复杂度都太大了,而它们永远只能看到这堆混乱里非常局部的一小块。
我说的还不只是上下文窗口大小、或者长上下文注意力机制一看到 100 万行代码怪兽就失灵这种显而易见的技术限制。事情比那更阴。
在 agent 真正开始帮你收拾这堆烂摊子之前,它得先找到所有需要改动的代码,以及所有现有可复用的实现。我们把这叫做 agentic search。agent 怎么做这件事,取决于你给了它什么工具。你可以给它 Bash,让它用 ripgrep 在代码库里狂搜;你也可以给它一个可查询的代码索引、一个 LSP server、一个向量数据库。到头来差别没那么大。代码库越大,召回率就越低。所谓低召回率,就是 agent 实际上就是找不全它需要的那些代码,因此也就不可能把事情做好。
这也是那些代码味道小蠢错一开始会发生的原因。agent 会漏掉已有代码,重复造轮子,引入不一致。然后这些东西再慢慢开花,长成一朵美丽的复杂度屎花。
那我们该怎么避免这一切?
我们该怎么和 agent 一起工作(至少目前我这么想)
coding agent 就像海妖,会用它生成代码的速度和那种锯齿状的聪明劲把你引过去。它常常能以极快的速度、高质量地完成一个简单任务。真正开始崩坏,是从你脑子里冒出这个念头开始的:"哦天哪,这东西真不错。电脑,替我上班吧!"
把任务委派给 agent,本身当然没什么问题。适合 agent 的任务通常有几个共同特征:它们可以被很好地限定范围,因此 agent 不需要理解整个系统;这个 loop 能被闭合,也就是说 agent 有办法评估自己的工作;输出结果不是关键任务,只是某个临时工具,或者某个没人会把命和营收押在上面的内部软件;又或者你只是想找个橡皮鸭来对着说说想法,本质上也就是把你的想法拿去和互联网上被压缩过的智慧,以及合成训练数据碰一碰。如果其中任意一条成立,那你就找到了非常适合交给 agent 的任务——前提是,你这个人类仍然是最后那道质量闸门。
比如 Karpathy 的 auto-research 被拿来加速你的应用启动时间?很好!前提是你得明白,它吐出来的代码根本就不是 production-ready。Auto-research 之所以能工作,是因为你给了它一个 evaluation function,让 agent 可以用某个指标来衡量自己的成果,比如启动时间或者 loss。但那个 evaluation function 只覆盖了一个非常窄的指标。任何没被它纳入评估函数的东西,比如代码质量、复杂度,甚至正确性,只要你的评估函数写得脑残,agent 都会很开心地直接无视。
重点是:让 agent 去做那些无聊的事、那些不会再教会你新东西的事,或者那些你本来没时间尝试的不同方案。然后由你来评估它整出来的结果,挑出其中真正合理、正确的部分,再把实现收尾。当然,最后这一步你也完全可以继续用 agent。
而我想建议的是:现在更好的路子,是他妈地把节奏放慢一点。给自己时间想清楚,你到底在做什么、为什么做。给自己一个机会说一句:去他妈的,我们根本不需要这个。给自己设一个上限:每天允许铁皮人生成多少代码,这个上限要和你自己真正能 review 的能力对齐。
任何定义你系统整体形态的东西——也就是架构、API 之类——都请你亲手写。真要怀旧的话,也可以用点 tab 补全。或者和 agent 做点 pair programming。要待在代码里。因为仅仅是“你必须亲手把它写出来”或者“你看着它一步一步被搭起来”这个动作,本身就会引入一种摩擦;而这种摩擦,会帮助你更好地理解你到底想构建什么,以及这个系统“手感”到底怎么样。这里真正起作用的是你的经验和品味,而这是当前最先进模型依然替代不了的东西。慢他妈一点,承受一点摩擦,正是你学习和成长的方式。
最终结果会是:你的系统和代码库依旧能被维护,至少能像 agent 出现之前我们那些老系统一样可维护。对,它们以前也不完美。但你的用户会感谢你,因为你的产品现在带来的是愉悦,而不是一坨工业泔水。你做出来的功能会更少,但会是对的那些。学会说“不”,本身也是一种能力。
你也能睡得更踏实,因为你至少还知道现在到底发生了什么,而且你仍然握有主导权。你的理解能力,能帮你补上 agentic search 的召回问题,于是铁皮人的输出会更好,也更不需要大量揉捏。如果真的出大事了,你也有能力进去亲手修。又或者如果你最初的设计确实不够好,你也知道它为什么不好,以及该怎么把它重构成更好的样子。有没有 agent,都无所谓。
这一切都需要纪律。
这一切都需要主导权。
这一切都需要人类。
本页面尊重你的隐私:不使用 cookie 或类似技术,也不收集任何可识别个人身份的信息。