本文翻译自 Thoughts on slowing the fuck down,版权归原作者所有。

乌龟的脸,就是我审视我们行业时的表情
AI 编码代理出现已经一年多了,这一代工具真的能帮你构建完整的项目了。虽然之前也有 Aider 和早期的 Cursor 这样的先驱,但它们更像是助手而不是代理。新一代的工具令人着迷,很多人把业余时间都用来构建那些一直想做却没时间做的项目。
我觉得这样挺好。在业余时间折腾项目很有趣,而且很多时候你确实不必太在意代码质量和可维护性。如果你想学习新的技术栈,这也是个不错的途径。
圣诞节假期期间,Anthropic 和 OpenAI 都给了一些免费额度,让人体验他们那种令人上瘾的老虎机。对很多人来说,这是第一次体验到 AI 代理编程的魔力。参与进来的人越来越多了。
现在编码代理也被引入到生产代码库中。经过 12 个月的发展,我们开始看到所有这些"进步"带来的影响。这是我目前的看法。
一切都很糟糕
虽然这些都是个案性的观察,但感觉上软件变得脆弱不堪,98% 的正常运行时间成了常态而非例外,即使是大型服务也是如此。用户界面出现了各种最他妈奇怪的缺陷,按说质量保证团队应该能够发现这些问题的。当然这在代理出现之前就存在了。但我们似乎正在加速这个问题。
我们看不到公司的内部情况,但偶尔会有一些消息流到记者耳朵里。比如最近有报道说 AWS 的 AI 导致了停机事件。AWS 立即予以纠正,随后又内部发布了一份 90 天重置计划。
微软 CEO Satya Nadella 一直在谈论 微软有多少代码是由 AI 生成的。虽然没有直接证据,但有种感觉是 Windows 正在变差。从 Microsoft 自己发布的这篇博文来看,似乎也认同这种观点 Windows 质量承诺。
声称产品 100% 代码都由 AI 编写的公司,一贯产出的都是你能想象到的最糟糕的垃圾。不点名,但内存泄漏几个 G、界面故障、损坏的功能、崩溃:这可不是他们认为的质量保证,也不是宣传让代理为你完成所有工作的最佳方式。
通过行业八卦网,我听到越来越多的人,从小型到大型的软件公司,都说他们用代理把自己困住了。没有代码审查,设计决策交给代理,一大堆没人要求的功能。这就够了。
我们应该如何与代理协作(以及为什么不该这样做)
我们基本上放弃了所有的纪律和自主性,陷入了一种上瘾状态,最高目标就是用最短的时间产出最大量的代码。后果?管他呢。
你在构建一个编排层来指挥一大群自主代理。你安装了 Beads,完全没意识到它基本上是没法卸载的恶意软件。互联网告诉你要这样做,否则你就没戏了。你是在盲目跟风。看,Anthropic 用代理群构建了一个 C 编译器。它有点问题,但也许下一代大语言模型能修复它。哦天哪,Cursor 用一群代理构建了一个浏览器。没错,当然它还不完全好用,每隔一段时间需要人来帮忙转转轮子。但也许下一代大语言模型会修复它。发誓!分发,分而治之,自主权,黑暗工厂,软件在 6 个月内就搞定了。SaaS 已死,我奶奶只是让 Claw 帮她建了一个自己的 Shopify!
当然,这对你的没什么人用的副项目还是可以的。嘿,也许有人真的能让这种方式为真正的软件产品工作,而不是产出一坨垃圾供真实用户使用。
如果是你,恭喜你。但至少在我和同行的圈子里,我还没找到证据证明这种方法有效。也许是我们都有能力问题。
不断累积的错误,零学习,无瓶颈,延迟的痛苦
代理的问题是它们会犯错。这没问题,人类也会犯错。也许只是正确性问题,容易识别和修复。加个回归测试,额外加分。或者可能是你的代码检查工具没捕捉到的代码异味。这里有个没用的方法,那里有个类型不合适,再那边有重复的代码。单独看,这些都是无害的。人类也会犯这样的错误。
但代理不是人类。一个人犯同样的错误几次后,最终会学会不再犯。要么是因为有人开始骂他,要么是他真的在学习。
代理没有这种学习能力。至少开箱即用是这样的。它会一遍又一遍地犯同样的错误。根据不同的训练数据,它也可能创造出不同错误的华丽混合体。
你可以尝试教你的代理。告诉它在 AGENTS.md 里不要再犯那个蠢错了。设计最复杂的记忆系统,让它查找之前的错误和最佳实践。这对于特定类别的错误可能是有效的。但这也需要你真的观察到代理犯了那个错误。
AI 代理和人类之间还有一个更重要的区别。人类是一个瓶颈。人类不可能几个小时就写出 2 万行代码。即使人类高频地犯同样的小错误,一天内能在代码库中引入的错误也是有限的。这些错误会以非常缓慢的速度累积。通常,如果痛苦太大了,讨厌痛苦的人类会花时间修复这些问题。或者人类被解雇,另一个人来修复。于是痛苦消失了。
对于一个由代理组成的军队,没有瓶颈,没有人类的痛苦。这些微小无害的小错误以不可持续的速度累积。你把自己从循环中移除了,所以你甚至不知道这些无意的错误已经形成了一个怪物级别的代码库。只有当为时已晚时才感受到痛苦。
有一天你转过头想添加一个新功能。但这个架构此时大部分是由错误构成的,不允许你的代理军队以正常的方式做出改变。或者你的用户在尖叫,因为最新更新破坏了某些东西并且删除了用户数据。
你意识到你不再信任代码库。更糟糕的是,你意识到你让 AI 代理写的数百万单元测试、快照测试和端到端测试也都不可信。唯一仍然可靠的衡量标准是手动测试产品。恭喜你,你把自己搞惨了(和你的公司)。
复杂性的商家
你对发生的事情一无所知,因为你把所有的自主性都交给了代理。你让它们自由发挥,它们是复杂性的商家。它们在训练数据和强化学习训练中看到了很多糟糕的架构决策。你让它们为你的应用设计架构。猜猜结果是什么?
大量的复杂性,一堆可怕的盲目崇拜"业界最佳实践"的大杂烩,你没有在它失控之前将其限制住。但这还更糟。
你的代理永远看不到彼此的运行结果,永远看不到你的整个代码库,永远看不到你在或别的代理在做改变之前做出的所有决定。因此,代理的决定总是局部的,这正好导致上面描述的错误。大量的代码重复,为了抽象而抽象。
这一切都累积成无法挽回的复杂性混乱。这正是你在人工编写的企业代码库中看到的混乱。之所以达到这种状态,是因为痛苦分布在大量的人身上。个人的痛苦达不到"我需要修复这个"的阈值。个人可能根本没有修复问题的能力。组织的疼痛阈值非常高。但人工编写的企业代码库需要数年才能达到这个状态。组织随着复杂性慢慢演变,以一种病态的协同方式学习如何应对。
用代理和一个两人的团队,你可以在几周内达到这种复杂性。
代理搜索的召回率很低
所以现在你希望你的代理能修复这个烂摊子,重构它,使其焕然一新。但你的代理也无法处理这种情况。因为代码库和复杂性太大了,而它们对这个烂摊子只有局部视角。
我不是在谈论上下文窗口大小或长上下文注意力机制在看到百万行代码的怪物时会失效。那是明显的技术限制。但比那更狡猾。
在你的代理尝试帮助修复混乱之前,它需要找到所有需要更改的代码,以及所有现有的可以复用的代码。我们称之为代理搜索。代理如何做取决于它拥有的工具。你可以给它一个命令行工具,让它搜索代码库。你可以给它一些可查询的代码库索引,一个语言服务器,一个向量数据库。到最后差别不大。代码库越大,召回率越低。低召回率意味着你的代理实际上不会找到它做好工作需要的所有代码。
这也是为什么那些代码异味错误会发生的原因。代理错过了现有代码,重复了一些东西,引入了不一致。然后它们绽放成一朵美丽的复杂性屎花。
我们如何避免这一切?
我们现在应该如何使用代理(我认为)
编码代理是塞壬女妖,用它们的代码生成速度和参差不齐的智能吸引你,经常以惊人的速度高质量地完成简单的任务。当你想:“噢,这个东西真棒。电脑,替我干活吧!“时,事情就开始出问题了。
当然,把任务委托给代理没有问题。好的代理任务有一些共同属性:它们可以被限定范围,这样代理不需要理解整个系统。循环可以闭合,即代理有办法评估自己的工作。输出不是关键的,只是一些临时工具或内部的软件,没有人的生活或收入依赖于它。或者你只需要一个橡皮鸭来碰撞想法,这基本上意味着把你的想法与互联网的压缩智慧和合成训练数据碰撞。如果任何这些都适用,你已经找到了代理的完美任务,前提是你作为人类是最终的质量把关。
Karpathy 的auto-research应用于加快应用的启动速度?很好!只要你要明白它吐出来的代码根本不是生产就绪的。Auto-research 有效是因为你给了它一个评估函数,让代理可以用某个指标衡量自己的工作,比如启动时间或损失值。但评估函数只捕捉非常狭窄的指标。如果你的评估函数是 foobar,代理会很乐意忽略任何没有被捕获的指标,比如代码质量、复杂性,甚至是正确性。
关键是:让代理做无聊的事情,不会教会你任何东西的新东西,或者尝试其他你否则没有时间做的事情。然后你评估它提出的东西,取那些真正合理和正确的想法,并完善实现。是的,你也可以用代理做最后一步。
我建议慢下来是对的。给自己时间去思考你真正要构建什么以及为什么。给自己机会说,去他的,我们不需要这个。为自己设定限制,每天允许 AI 代理生成多少代码,与你实际审查代码的能力一致。
定义你的系统整体观的任何内容,也就是架构、API 等等,用手写。也许用标签补全来找回一些怀旧感。或者和你的代理一起结对编程。在代码中。因为书写事物或看到它一步步建立起来的简单行为引入了摩擦,这让你更好地理解你想要构建什么以及系统"感觉"如何。这是你的经验和品味起作用的地方,这是当前最先进的模型还无法替代的。慢下来,忍受一些摩擦,这才是让你学习和成长的原因。
最终结果是系统和代码库继续保持可维护,至少和我们代理出现前的老系统一样可维护。是的,那些也不完美。你的用户会感谢你,因为你的产品现在带来的是愉悦而不是垃圾。你会构建更少的功能,但是是正确的。学会说不本身就是一个功能。
你可以安心睡觉,知道你还了解到底发生了什么,而且你还有自主权。你的理解让你能够解决代理搜索的召回率问题,带来更好的 AI 代理输出,需要更少的人工处理。如果出了问题,你能进去修复它。或者如果你的初始设计有缺陷,你知道为什么有缺陷,以及如何重构得更好。不管有没有代理,都不在乎了。
这一切都需要纪律和自主权。
这一切都需要人类。