慢下来——关于AI编程代理的反思

 

序言:AI 编程代理已经出现了大约一年,它们能帮你构建完整的项目,速度惊人。越来越多的公司开始在正式产品中使用代理生成的代码,但效果如何?这篇文章的作者——一位资深软件开发者——认为我们正在目睹一场灾难:软件质量急剧下滑,代码库被代理制造的复杂性淹没,而人类开发者正在失去对系统的理解和掌控。他的建议既简单又激进:慢下来。这篇文章言辞辛辣、观点鲜明,是当下 AI 编程热潮中一剂必要的清醒剂。

原文:Thoughts on slowing the fuck down,作者 Mario Zechner,发表于 2026 年 3 月 25 日。


这只乌龟的表情就是我看我们这个行业时的表情

慢下来——关于 AI 编程代理的反思

能真正帮你构建完整项目的编程代理出现大约一年了。此前也有 Aider 和早期 Cursor 这样的先驱,但它们更像是助手而非代理。新一代代理令人着迷,我们很多人花了大量业余时间,去构建那些一直想做但从未有时间做的项目。

我觉得这没什么问题。在业余时间做东西是非常享受的,而且大多数时候你不需要在意代码质量和可维护性。如果你想学一门新技术栈,这也是个不错的途径。

圣诞假期期间,Anthropic 和 OpenAI 都发放了一些免费额度,好让人们上瘾他们的老虎机。对很多人来说,那是他们第一次体验到代理编程的魔力。鱼饵越来越大了。

现在,编程代理也被引入了正式产品的代码库。十二个月过去了,我们开始看到所有这些”进步”带来的后果。以下是我目前的看法。

一切都坏了

虽然这些都只是个人观察,但我的感觉是软件已经变成了脆弱的烂摊子——98% 的正常运行时间成了常态而不是例外,就连大公司的服务也是如此。而且用户界面出现的那些鬼样子 Bug,你会以为 QA 团队应该能发现才对。我承认,这种现象在代理出现之前就存在了。但我们似乎正在加速。

我们无法看到公司内部的情况。但时不时会有消息漏出来被媒体报道。比如那个所谓的 AI 导致 AWS 宕机事件。AWS 马上进行了“澄清”。但随后又在内部推出了一个 90 天重置计划

微软 CEO 萨提亚·纳德拉一直在宣扬微软有多少代码是 AI 写的。虽然没有直接证据,但确实有一种感觉,就是 Windows 正在走下坡路。微软自己似乎也同意这一点,从这篇不错的博客文章可以看出。

那些声称产品代码 100% 由 AI 编写的公司,持续产出你能想象到的最糟糕的垃圾。我不是在指名道姓,但是——GB 级别的内存泄漏、UI 故障、完全坏掉的功能、崩溃——这绝不是他们以为的那种质量认证。对于”让代理替你干所有活”这种狂热的迷梦来说,这绝对算不上什么好广告。

江湖传言,越来越多的软件公司——不论大小——都在说他们被代理编程逼到了死角。没有代码审查、设计决策交给了代理、一堆没人要的功能。不出问题才怪。

我们不该怎样与代理协作,以及为什么

我们基本上放弃了所有的纪律和自主性,换取了一种成瘾——你的最高目标变成了在最短时间内产出最大量的代码。后果见鬼去吧。

你在构建一个编排层,指挥一支自主代理的军队。你安装了 Beads,完全不知道它基本上是无法卸载的恶意软件。网上的人让你装的。他们说这才是你应该的工作方式,否则你就完了。你在 ralphing the loop。你看,Anthropic 用代理集群构建了一个 C 编译器。虽然有点问题,但下一代的 LLM 肯定能修好。天哪,Cursor 用一个代理营构建了一个浏览器。是的当然,它并没有真正工作,而且时不时需要人来转一下方向盘。但下一代的 LLM 肯定能修好。拉钩上吊,一百年不许变!分布式、分而治之、自主运作、熄灯工厂,软件在未来六个月内就会被彻底解决。SaaS 已死,我奶奶刚刚用 Claw 给自己建了一个 Shopify!

说真的,对于你那几乎没人用的——包括你自己也不怎么用的——业余项目来说,这样做也许行得通。而且,说不定真的有人能让这种模式在一个不是一坨屎、有真实用户在愤怒中使用的软件产品上运转起来。

如果那个人是你,我祝你好运。但至少在我周围的人脉圈里,我还没有找到任何证据表明这种垃圾能行。也许我们都有技能问题。

零学习、无瓶颈、延迟痛苦——漏洞的复利增长

代理的问题是它们会犯错。这没什么,人类也犯错。可能只是正确性错误,很容易发现和修复。再补上一个回归测试还能加分。也可能是一些 Linter 检测不到的代码异味。这里一个没用的方法,那里一个不合理的类型,那边一段重复代码。单独来看,这些都无关紧要。人类也会犯这些小毛病。

但铁疙瘩(clanker)不是人类。人类同样的错误犯个几次,最终会学会不再犯。要么是因为有人开始对他们大喊大叫,要么是因为他们确实在一条真正的学习曲线上。

代理没有这种学习能力。至少开箱即用没有。它会一遍又一遍地犯同样的错误。根据训练数据的不同,它还可能会发明出不同错误的精彩新组合。

你可以试着教你的代理。在你的 AGENTS.md 里告诉它别再犯那个小毛病。搞一套最复杂的记忆系统,让它查询之前的错误和最佳实践。这对特定类型的错误可能是有效的。但这也要求你真的观察到代理在犯错。

铁疙瘩和人类之间还有一个重要得多的区别。人类是瓶颈。人类没法在几个小时内拉出两万行代码。即使人类以高频率制造这种小毛病,一天能引入代码库的小毛病也是有上限的。这些小毛病会以非常缓慢的速度累积。通常,当毛病的痛苦变得太大时,人类——他们讨厌痛苦——会花些时间修复这些毛病。或者人类被开除了,换个人来修复这些毛病。所以痛苦会消失。

而对于一支被编排的代理军队来说,没有瓶颈,也没有人类的痛苦感。这些微小的、无害的小毛病突然以不可持续的速度复利增长。你已经把自己从循环中移除了,所以你甚至不知道所有这些无辜的小毛病已经形成了一个代码巨兽。你等到痛苦降临的时候,已经太晚了。

然后有一天你回过头来想加一个新功能。但是架构——此时已经基本上是各种毛病的集合体——不允许你的代理军队以能正常工作的方式做出修改。或者你的用户在朝你尖叫,因为最新版本的什么东西崩了,还删掉了一些用户数据。

你意识到你再也无法信任这个代码库。更糟的是,你意识到你让铁疙瘩们写的那些海量单元测试、快照测试和端到端测试同样不可信。唯一还能用来衡量”这东西能不能用”的可靠手段是手动测试产品。恭喜你,你把你自己(和你的公司)搞得一团糟。

习得复杂性的贩卖者

你他妈的完全不知道发生了什么,因为你把你所有的自主权都交给了代理。你让它们自由驰骋,而它们是复杂性的贩卖者。它们在训练数据和 RL 训练过程中见过许多糟糕的架构决策。你让它们来架构你的应用。猜猜结果是什么?

巨量的复杂性,一个可怕的、赶时髦式的”行业最佳实践”大杂烩——你没能在为时已晚之前制止它。但事情比这更糟。

你的代理从未见过彼此运行的结果,从未见过你的全部代码库,从未见过你或其他代理在它们做出变更之前所做的所有决策。因此,代理的决策始终是局部的,这就导致了上面描述的毛病。大量的代码重复,为了抽象而抽象。

所有这些复利累积成一个无法恢复的复杂性烂摊子。和你在人类制造的企业代码库中看到的那种烂摊子一模一样。那些代码库之所以会变成那样,是因为痛苦被分散到了大量的人身上。个体的痛苦没有超过”我需要修复这个”的阈值。个体甚至可能没有修复问题的手段。而且组织的痛苦容忍度极高。但人类制造的企业代码库需要好几年才能走到那一步。组织以一种扭曲的协同方式,与复杂性一起慢慢演化,学会了如何处理它。

而有了代理和一个两人的团队,你可以在几周内达到那种复杂度。

代理搜索的召回率很低

现在你希望你的代理能修复这个烂摊子,重构它,让它变得干净整洁。但你的代理也已经无法应对了。因为代码库和复杂性太大了,而它们永远只能看到这个烂摊子的局部视图。

我不只是在说上下文窗口大小,或者长上下文注意力机制在面对一百万行代码怪物时的失败。那些是显而易见的技术限制。还有更狡诈的问题。

在你的代理能够尝试帮助修复烂摊子之前,它需要找到所有需要修改的代码和所有可以复用的现有代码。我们称之为代理搜索。代理如何做到这一点取决于它拥有的工具。你可以给它一个 Bash 工具,让它用 ripgrep 在代码库中搜索。你可以给它一些可查询的代码库索引、一个 LSP 服务器、一个向量数据库。到头来这些都差不多。代码库越大,召回率就越低。低召回率意味着你的代理实际上找不到完成好工作所需的所有代码。

这也是为什么那些代码异味小毛病会在第一时间发生。代理漏掉了已有代码,重复了东西,引入了不一致。然后它们绽放成一朵美丽的复杂性臭花。

我们如何避免这一切?

我们应该怎样与代理协作(目前的想法)

编程代理是塞壬的歌声,用代码生成速度和锯齿状的智能诱惑你,常常能以惊人的速度高质量地完成简单任务。当你想”天呐,这东西太棒了。计算机,替我干活!”的时候,一切就开始崩塌了。

显然,把任务委派给代理本身没有问题。好的代理任务共享几个属性:它们可以被划定范围,让代理不需要理解整个系统。循环可以闭合,也就是说,代理有办法评估自己的工作。产出不是关键任务,只是一些临时工具或没人依赖的内部软件。或者你只需要一只橡皮鸭来碰撞想法——这基本上就是把你的想法往互联网和合成训练数据的压缩智慧上碰一碰。如果以上任何一种情况适用,你就给代理找到了完美的任务——前提是你这个人类是最后的质量守门人。

Karpathyauto-research加速你的应用启动时间?很棒!只要你明白它吐出来的代码根本不是生产就绪的。Auto-research 之所以有效,是因为你给了它一个评估函数,让代理可以用某个指标——比如启动时间或损失函数——来衡量自己的工作。但这个评估函数只捕捉到了非常狭窄的指标。代理会很乐意忽略任何没有被评估函数捕捉到的指标,比如代码质量、复杂性,甚至正确性,如果你的评估函数本身就有问题的话。

关键是:让代理做那些无聊的东西,那些不会教你任何新东西的东西,或者尝试一些你本来没时间尝试的不同方案。然后你去评估它产生了什么,采纳其中真正合理和正确的想法,完成最终的实现。是的,当然,你也可以用一个代理来完成那最后一步。

我想建议的是:慢下来——这是他妈的出路。给自己时间去思考你到底在构建什么,以及为什么。给自己一个机会说,操,不,我们不需要这个。给自己设限,限制你让铁疙瘩一天生成多少代码,这个上限要与你实际审查代码的能力相匹配。

任何定义你系统形态的东西——架构、API 等等——用手写。也许用 Tab 补全来感受一下怀旧的味道。或者和你的代理做一些结对编程。待在代码里。因为简单地动手写东西,或者一步步看它被构建出来,会引入摩擦——这种摩擦能让你更好地理解你想构建什么,以及系统的”手感”如何。这才是你的经验和品味发挥作用的地方,目前的 SOTA 模型还无法替代。而慢下来、承受一些摩擦,才是让你学习和成长的途径。

最终的结果将是系统继续保持可维护性——至少和代理出现之前的老系统一样可维护。是的,那些系统也不完美。你的用户会感谢你,因为你的产品现在能带来快乐而不是垃圾体验。你构建的功能会变少,但都是对的。学会说”不”本身就是一种功能。

你可以安稳入睡,知道你还大概了解他妈的发生了什么,你还有自主权。你的理解让你能够解决代理搜索的召回率问题,从而获得更好的铁疙瘩输出,需要的人工修复也更少。如果出事了,你能进去搞定它。或者如果你最初的设计不够理想,你理解为什么不够理想,以及如何重构成更好的东西。用代理也好,不用也好,关我屁事。

所有这些都需要纪律和自主性。

所有这些都需要人。