CC
云谦的博客
发布于 2025年12月29日

译:一个由 Agent 为 Agent 编写的代码库

原文: https://ampcode.com/by-an-agent-for-an-agent
作者: Tim Culverhouse
译者: Gemini 3 Pro High

2025年12月18日

当我写代码时,我必须做出许多决定,这些决定会影响我浏览代码库的能力:这个函数取什么名字好?我应该为这个类型新建一个文件,还是把它放在现有的文件中?文件名应该叫什么?我应该为此创建一个新目录吗?

Agent stealing feather

我不仅要决定这些事情,还得记住它们。每次打开 Neovim,我都要思考过去的 Tim 会怎么称呼这个。他会把它放在哪里?在做决定的前后,我都要承受认知负荷的冲击。

好消息是,现在我可以把几乎所有这些工作都卸载给 Agent。

是的,我知道,人不应该这样,但听我说完。在创建 Amp CLI 背后的 TUI 框架时,我正是这么做的。这个框架是我的 Zig TUI 库的 TypeScript 移植版,90% 的代码都是由 Amp 编写的。而且,正如 Thorsten 和团队中的许多其他人所说:Amp 在 CLI 上使用这个框架时表现炸裂。它几乎能搞定你扔给它的任何任务。以至于“为什么 Amp 如此擅长处理我们的 CLI?”这个问题已经被多次提起。我想我有答案了。我认为答案在于我把决定权交给了 Agent。

问题是——我确实在乎事物的命名以及代码库的结构。在编写框架的早期,我经常会因为 Agent 做的某个更改而感到恼火,叫停它,并告诉它重命名一个函数、把文件移到不同的目录,或者把某个类放到单独的文件中。我不喜欢做这些决定,但我仍然想做。让代码库看起来整洁会带来某种满足感——所以我过去常叫停 Agent 并告诉它“我更懂”。

但我并不更懂。事实证明,我并非绝对正确。

举个例子。Amp TUI 框架使用双缓冲方法来更新屏幕。我们保留一个前台屏幕和一个后台屏幕——一个代表上一帧,另一个代表下一帧。然后我们要对比它们,打印更新,并交换屏幕。当把代码从 Zig 移植到 TypeScript 时,Amp 把交换屏幕的函数命名为 present()。我不喜欢这个名字,而且我更懂,所以我把它重命名为 swapScreens()

但随着移植的进行,我看到 Amp 反复尝试寻找一个名为 present() 的函数,找不到后声明“让我试试别的”,最终才找到那个对来说有意义的名字的函数。

Amp 空转了,因为强加了对代码命名、结构和布局的看法。但显然,我的看法在统计上并不是最可能的。当 Agent 选择 present() 这个名字时,它的手是由训练数据和我提供的上下文引导的。但我把它推开了,可以说是违背了它的直觉,并在下一次让 Agent 的工作变得更难。Amp 再也不能问“过去的 Amp 会怎么称呼这个?”并在它的权重中找到答案——它必须知道过去的 Tim 会怎么称呼这个。

Orb writing code

我看到这种情况重复了几次,意识到了我的错误。我在干扰它使用自己的思维进行导航的能力。我让它违背本性。我让它慢了下来,因为它跑了更多的循环,消耗了更多的 token,最终,当我看到它记不住名字时,也给我自己带来了挫败感。

所以我改变了我的方法。不再告诉 Agent 如何命名事物或把它们放在哪里。由 Agent 来决定。

这奏效了。

一旦我放手,Agent 跑得更快、更久了。它选择了我不曾选择的名字,采用了我未曾想到的文件布局。它使用了比我们代码库中其他任何地方都多的 OOP 模式和类。与我们其余的代码相比,它对泛型和 TypeScript 原语的使用显得很奇怪

但是:它表现炸裂。

这是不可否认的。一旦它完成了框架,它在使用该框架时的表现让我们印象深刻——提醒一下,这是我们要自己的自定义框架,没有任何文档,也无法放入单个上下文窗口!利用它构建的框架,Amp 能比我们要大多数人更快、更正确地搞定事情。它知道如何向新的模态窗口添加滚动条(记得吗,我们这里谈论的是 TUI!),它知道动画子系统是如何工作的,它知道键盘快捷键和点击处理程序是如何工作的,如果框架中缺少什么,它会添加上去。“哦,我们没有监听这个事件。让我快速修复一下。”然后它真的很快就修复了。

最终,我不知道为什么它如此擅长使用它,当它写代码时我无法窥视它的权重内部,而且当我问它时我也不相信它的回答,但我有如下猜测。

这个框架及其 Zig 前身都受到了 Flutter 的启发。它们拥有类似 Flutter 的 API,包含 Widgets、StatefulWidgets、Intents 和 Bindings 等等。而且,我认为,Agent 认出了这一点。它的权重中有足够的 Flutter 知识。即使 Flutter 最初是用 Dart 编写的,我认为 Agent 在 Zig 版本中认出了 Flutter,现在也能在我们的代码库中认出 Flutter,并能透过语言和语法看到其中发挥作用的概念。

而且代码库允许它这样做

在我让它自由支配代码库之后——让它使用最可能的函数和类型名称,把文件放在它的“直觉”告诉它应该去的地方——它为自己构建了一个框架。在这个框架和代码库中,事物恰好处于一个了解 Flutter 且了解 TypeScript 的模型——以概率的方式了解它们——首先会去寻找的地方。在这个代码库中,语法和概念在统计上的可能性和实际编译通过之间取得了平衡。在这个代码库中,Agent 不必猜测某个东西叫什么,也不必想知道为什么某个东西是这样工作的。这是一个在我想让它做什么、概念需要什么以及 Agent 的权重判断实现它的最可能方式之间达到平衡的代码库。

一个由 Agent 为 Agent 编写的代码库。

Cathedral orb codebase

评论 (0)

请登录后发表评论

暂无评论,快来发表第一条评论吧!