编码 agent 为什么不会设计软件
0:00 Mario Zechner & Armin Ronacher:Pi 加入 Earendil
主持人:大家好。Pi 出了个新版本。还有,能请你们自我介绍一下吗?我是说 Armin,我还没跟你说过话。Mario 我已经请来过两次了。不过,你能做个介绍吗?
Armin:嗨,我叫 Armin。我是 Earendil 的 MCPO,也是驻场实习生。对,我也不知道。我们就……我们就是在这儿做 Pi。不过对。
主持人:嗯,你是什么时候加入的?就是开始做 Pi 这件事?
Armin:我和一个朋友一起创办了一家公司,然后我们在十一月……二月的时候把 Pi 吸纳了进来。
主持人:那么,你为什么决定做……对,那件事?
Armin:这个问题问得非常好。不,是这样的,我们之前就一直在试着把 Mario 拉上船,拉了很长一段时间。就是,在 OpenClaw 那阵疯狂之后,机会来了,Mario 真的对这个想法动了心。这大概是我这边的版本。不过对,因为我们想跟 Mario 一起工作,我们做的是那种有延展性的软件,而 Pi 是……是一个早期实验的绝佳版本。
1:25 维护 Pi 与开源的公车因子
Armin:就是这个,所以它就很顺理成章了。现在你……好了,请讲吧,Mario。
Mario:不,我只想说,我是 Mario,我做的 Pi,我真是个白痴才会去做 Pi,现在我只能一直种地了。
主持人:你是真的觉得自己被困在这个项目上了吗?那是你的一个担忧吗?它这么成功,停下来好像又说不过去?
Mario:嗯,我是说,像 Armin 一样,我有很长的开源历史,只是跟 Armin 在不同的领域。
Mario:但即便如此。一旦我做了个开源项目还吸引了用户,就像我说的,我就是个白痴,会一直替人维护这些破玩意儿。对,哪怕他们一分钱都不给我。而且时不时来的那些负面情绪真的会磨人,不过对,我觉得目标仍然是把 Pi……不是交出去,而是让更多人来做 Pi,这样我需要一直待在旁边的公车因子(bus factor)就会变小。而且我觉得到目前为止,这个目标我们完成得相当不错了。
Mario:所以,如果我明天死了,Pi 也会在可靠的人手里。
Armin:那是我……那是个不错的状态。对。我在波兰办了个 meetup。我刚搬来的时候一个朋友都没有,结果这个 meetup 就爆炸式地发展起来了。我觉得它现在是全国最大的 meetup 了,就在 meetup.com 那个应用上。现在它完全自己运转,我都不用组织,只要去就行。我是……你知道,我的徽章挂在那儿,所以大家都对我很客气。但一个项目能走到这一步,真的很美好。
2:43 AI 烂活、贡献者与修 issue 的 agent
主持人:怎、怎、怎……嗯,那挺好的。那……对,就是找贡献者这件事,有什么变化吗?现在越来越多人在用 AI。我知道你不是那种喜欢把东西随便糊出来的人。所以这段经历怎么样?很糟吗?
Armin:对极了。
主持人:Mario,这段经历怎么样?
Mario:让我这么说吧,Pi Durable 本可以早很多就做出来的,如果我不是从二月一直忙到大概七月,每天大部分时间都在维护 Pi——也就是翻 issue、修 issue。而问题在于,agent 还真的帮不上你修 issue 的忙。
4:10 为什么 coding agent 修 bug 总免不了加代码
Mario:至少在我看来是这样,至少对我的项目是这样。我没有那个信任度去把这事交给它们,也没法判断哪个被报上来的 issue 真的值得我们花时间、真的需要修,哪个不需要。所以最起码,我还是得把所有提交上来的 issue 都过一遍,做分流(triage),挑出真正值得我们花时间的。然后问题是,agent 能修 issue 吗?当然能。问题只是它修得好不好?我得说,对很多 issue 来说,那是行得通的。
Mario:我可以信任 agent 去修,尤其是那种很小很小的东西。任何涉及设计或架构的,你多少还是需要人,因为 agent 只会局部地往你的代码库里拉屎,把事情弄得更糟。对吧,Armin?
Armin:我觉得 agent 的问题也在于,它肯定会把问题解决掉,但几乎……它几乎不可能在不加代码的情况下修好一个问题。这很怪,因为我觉得,很多 issue 其实本来就不应该……
4:52 AI 烂活什么时候也能接受
Armin:……本来就该对代码库是净零的,但我知道,我肯定知道——说这话的人可是整天发那种改两百个文件的 PR,吓、吓死人了。而且我还、还两万行代码。我、我是我自己 clanker 使用的受害者,但这、这、这仍然不应该成为常态。而且特别是,如果你的代码库完全自动化了,我觉得它自然会随着每一次 bug 修复而增长。
Mario:所以我最近跟 DHH 聊过一次,他已经彻底投降于那整套……烂活……
Mario:你知道的,烂活操作。那、那就是我对我这份工作的叫法,因为我基本上什么事都用模型干。在某种程度上,我觉得自己肯定比以前笨多了。但在另一个层面上,它又非常高效——如果你的工作不是要造一个会被复制、被几百万人使用的东西,那我觉得随便糊一个脚本出来也没什么坏处。或者说,把它做出来就行。所以我最近在干的事,就是针对特定的硬件组合做 Docker 容器,让模型在某种随机的 VRAM、RAM 和 VME 配置上跑得最优。这招一直挺好使的,但那也就是做个 Docker 容器而已。所以,设计啊、架构啊其实没那么重要,只要那个东西……你知道,只要结果能用就行,能完成它该干的事就行。但你们没有这种特权,你们没这种特权。
Armin:对。
Armin:不,我同意。我们当然有那种特权,我们显然有。Pi 里很多很多东西其实就是纯粹的烂活。
Armin:这、这、这只取决于你在应用的哪一层把人类拉进来,在哪一层你信任 agent 去产出能用的东西,而且你不在乎它是怎么实现的。我给你举个例子,Pi 的 TUI 库。最初的设计,至少我挺喜欢的。对,但最初的设计是我手写的,对吧?在 2025 年初,为另一个项目写的。那带来一个相当健壮、极简的东西,我知道它大概能扛住真实世界的考验,哪怕不算理想,但也够好了,对吧?然后那之后,当我开始做 Pi 的时候,我并没有进去说,给我写个 markdown 组件,给我写个文本组件,给我写个编辑器组件。我只是……哦抱歉,我确实是这么干的。我就是告诉 agent:这是 API,照着这个该死的 API 给我把这些组件全写出来。我才不管它们长什么样。它们只要能跑,并且有一堆测试保证渲染正确就行。其他的我都不在乎。我到今天都没看过 markdown 组件或文本组件的哪怕一行代码。所以我才不在乎,无所谓。我唯一在乎的时候是性能下降的时候,而那时候,agent 通常很擅长找出一堆毛病,但它非常不擅长给出一个通用性的解决方案。它会进去,局部地修点东西,让性能提升……
7:40 模型在软件架构上变强了吗?
Armin:……就为那一个边缘用例,但它不会去从大局思考,去发现架构本身的问题——那些让整体变慢、最终导致这个慢的边缘用例的问题。所以我觉得,在某种程度上我还有点价值。
主持人:我记得你跟我说过,你喜欢那种过程——创建接口,玩弄 API,试着去感受你在构建什么。这个过程变了吗?因为对我来说,我现在看到的是,模型整体上做事情变得厉害多了,但在架构方面,我没看到太大改进。还是很乱。你有没有注意到什么不一样的地方?因为这些新模型很能干,但……
Armin:对。
Mario:我几乎觉得它们更差了。我不知道。我……不,它们对我们来说没在变好。不。我确实觉得它们在架构这块稍微更差了一点。因为现在,嗯,结果变差了,是因为你给了它们多得多的控制权。
Mario:我觉得基本就是这么回事。而且我……几乎每次模型发布,我都试着去构建点东西。然后我觉得,我对它们自己干出来的活越来越不满意了。而这主要是因为,我越来越信任它们了。所以,实际净结果是……它们大概还是更强了,但叠加了我对模型的期望和我使用它的方式。就像,我……我总是在写一个 C 语言游戏,就是一个用 C 写的游戏。因为,我也不知道,它就是这么个东西。我……我以前很喜欢写 C,所以,好吧,这就是我常干的一件事。而我觉得它们越来越差了。也许只是我没那么上心了,但我可以肯定地说,它们一点都没变好。我觉得它们产出的东西正在变复杂。它们说话的方式越来越复杂了。它们用……用的技术术语多得离谱。它们的回复会跑到各种古怪的小众技术话题里去。我不一定是在说它们构建的方式,而是它们跟我们交流的方式变得越来越奇怪了,我觉得。不过我、我、我确实觉得 Opus 变好了。对,就是那个,Fable 五点几还是什么的,还有上一版 Opus。老实说,我、我就因为它们的说话方式,直接不用它们了。实在让人受不了。我、我、我又不是什么银河大脑。
Armin:对。
Mario:我每个词都像是词典里的一个新词条,所以我、我就不行了,我放弃了,彻底换回 Sol。
10:11 AI 逆向工程:两个 Codex 账号就破解了
Mario:然后 Astra,我觉得,也开始搞那套烂活了。所以我又弃用了 Astra。Estra 也很糟。但我对 Sol 6.1 和 Opus 5.5 挺满意的。它们又把调调降下来了,现在又变回正常人……正常的机器了。所以挺好的。但我觉得,有一个我确实感受到的提升,是在安全(cyber)领域,一个不相关的项目上。去年我干了一堆事情,用 clanker 去加固一个桌面端的软件,结果它就是不……它根本没法理解当时是怎么回事。而今年,那个软件被一个中国哥们用两个 Codex 账号给破解了。然后我用了一个「逆向 clanker」去重放那次攻击,去搞清楚他们到底是怎么穿过我软件的防御的。那真是他妈太惊人了。真的,真的非常惊人。地球上没有任何逆向工程师会做到那一步,尤其不会在那么短的时间内。简直他妈疯了。给你点概念,这有点底层,但就是,那是个 JVM,然后 JVM 里有 Java 字节码,那些字节码最终通过一个 JIT 编译器编译成机器码。我把那一切都加固得很好,所以人们没法简单地提取字节码,或者注入他们自己的字节码。但是在原生侧有一个小小的逃逸补丁,是人类绝对没可能发现并利用的那种。然后那个 clanker 直接进去,逆向 JVM 内部的原生结构,直接开始读进程内存,把它映射回正确的 JVM 构建版本,识别出原生内存里的哪个结构部分对应 Java 表示里的哪个部分,然后就……那简直像科幻小说,太惊人了。
Armin:对,我的意思是,我有过同样的经历。所以我……我有这么个小玩意儿,我老拿出来给人看,就是我那个小小的……对,USB 芯片,那个中国产的 CarPlay 转接器。它自己就搞明白了怎么解密上面那个小东西——那个东西本来是保护新 root 镜像上传的。它还在 Web 界面上找到了一个 CGI 文件,可以绕过一些东西。然后就是,我啥都没干,就把它插上,让它跑起来。对,我不知道,大概五百美元之后,整个东西就归我了。这真的很惊人,真的非常惊人。
Mario:对。所以我家里一堆这玩意儿,我……我买的硬件越来越多,或者说现在好多都是别人送我的。然后我就在这些模型上跑,试着看看,从最小的那些,Qwen 27B,一直到 DeepSeek 和 GLM。
Mario:它们都变得很会做事了。比如我给它们一个 Nintendo DS 的 ROM hack,一个 ROM 游戏,然后我让它从头写一个 Nintendo DS 模拟器。它可以看 Dolphin 之类的东西,但它必须用一种完全不同的方式写出来,然后它真的把它跑起来了。这是 DeepSeek,它真的把它跑起来了。
Armin:对,我发现进步特别大的时候,是任务非常二元化的时候——要么完成,要么没完成。
13:26 测试预言机与用 LLM 做 fuzzing
Armin:它们最终总能搞定。这差不多就是结论了。对,如果你有一个预言机(Oracle),能告诉 LLM 它做得到底对不对,那你基本就赢了。比如 Bun,对吧?Bun 有一大堆测试。我敢肯定它不是百分之百覆盖了所有需要测的东西,但对 Jared 来说已经够了,他能告诉一群 agent,好,这样这样去移植,我会在关键节点给你们掌舵。但大部分时候就是试着让测试套件跑起来。在用 Rust 重写 Bun 这件事上,那真的很好用。我也做了跟你刚才说的模拟器类似的事——外面各种系统有海量的模拟器,而且这些也都在训练数据里,多到离谱,包括那些系统的规格。所以这也是一个非常容易被预言机测试的东西,而且训练数据里塞满了信息,对吧?同时它也挺适合 fuzz 的。
Mario:对,我觉得任何能 fuzz 的东西都是这样。我最近就干了这么一件事。我拿了一堆示例文件,YAML 文件、TOML 文件、CBOR 文件、MessagePack 文件、JSON 文件。然后就是,这是我的序列化库,你给它把所有格式都实现出来。所以最后它就做完了。然后我说,好,现在给我往死里 fuzz。
Armin:嗯。
Mario:然后它找出了很多问题。但因为我……我知道以前 fuzz 库本来也没那么难,但现在这就是想都不用想的事。就是,好,让它跑到……直到……你得花好几个小时才能再找出一个回归。
Armin:对,我觉得那是个绝佳的应用场景。而且特别是对 fuzzing 来说,你可能已经有一些自动化的 fuzz 生成,但上面再叠一个 LLM,对吧?它还能推理出你的 fuzzer……
15:35 为什么架构不在训练数据里
Armin:……你的 fuzzer 生成器没覆盖到的额外用例。这对所有类型的测试来说都像是火箭燃料。所以超级惊人、超级有用,真的非常棒。但接着我们就遇到你之前说的那种,比如架构。而且我不想……人类没那么特别,我觉得 DHH 说过类似的话——「你以为你很特别,因为你会架构、会设计什么的,再想想吧,因为模型同样会把这活抢走。」我觉得 DHH 归根结底没搞懂机器学习是干什么的。问题在于,我觉得模型,我觉得模型其实——如果你跟它们讨论一个问题的正确架构是什么,我觉得它们相当擅长。但问题是,解决一个问题最可能产生的结果的那个轨迹,在权重里却跑到了完全不同的方向去。所以……而且它都能……
Armin:对。
Armin:它基本上都能用训练数据来解释。我可以很轻松地为安全领域搭建训练数据。我可以很轻松地为构建一个已经存在的、有预言机的东西搭建训练数据。我可以很轻松地为构建网站、前端之类的、任何你想搞的东西搭建训练数据。但我没有训练数据的地方,是构建、设计和架构一个东西的「过程」。这才是重点,这是编程里唯一通常不以文本形式编码、所以 LLM 没法从中学到的部分——构建某个东西的架构的过程。
16:54 训练数据、agent 轨迹与分类器
Armin:所以这就是我们卡住的原因,嗯。
主持人:嗯,我觉得。
主持人:这就是为什么我们现在都要把会议录下来,然后每一个失败的创业公司都能把他们的会议……对。我们要把录音卖出去,把一切都发给那些模型应用。黑板上写着的,两百万美元卖给 OpenAI。
主持人:我……我在德国见过一个哥们,他有个机器人公司,他们主要……他们的主营业务其实就是卖训练数据。他们花钱雇人戴上那些帽子和手臂之类的设备,你知道,去做那些活,然后把数据卖给那些实验室。生意非常好。
主持人:但我敢肯定,一切都在那些轨迹(trace)里。所以如果你在跟模型聊架构,那些轨迹应该被加权得更重。问题是怎么分配,你怎么决定哪个该得到更高权重?对,这是非常非常有意思的问题。但是……我觉得问题还在于,这里头没有信号,因为……它就像处于中间序列一样。
Armin:对。
Mario:比如,Pi Durable 经历了……我不知道多少……
Armin:八轮迭代。
Mario:对,它经历了好几轮迭代。就像,训练怎么可能知道,那些对话里到底哪一个最终变成了我们发布的那一版?而且显然这在某种程度上是可能的,你可以训练它,你可以……你可以给它打标签,有办法可能做到,但这是个难得多的问题,而且这样的对话本来就少……
主持人:……那些真正……我、我、我就想把它看作一个分类问题。你拿到一大堆轨迹,不管你是什么「零数据保留」政策。零、零数据保留政策。所以作为 OpenAI 或 Anthropic 或 DeepSeek 或随便谁,你手里有一大堆轨迹,海量的,对吧?现在你想挑出那些真正高价值、高质量的。你怎么做?你没法靠人来做。
主持人:我的意思是,他们也确实会人工标注,但那没法扩展。所以下一个最好的选择,就是一个机器学习模型,能把轨迹分成高质量、低质量。我觉得他们是有机会的,你知道,就是他们现在做的——如果你用 Claude Code,它会在 GitHub 仓库和提交里标记自己。所以通过不仅构建对话轨迹,还构建仓库历史本身,这可能是条好路子,因为你只要映射一下,哪些仓库还在持续吸引用户,哪些 PR 被合进去了,并且代码还有多少比例仍然……我觉得我觉得那能行。
Mario:对,我一直在把我的数据分享给他们。我、我就点了分享。
主持人:对,但问题是这样的,他们拿到的数据量,你会以为他们能干出很厉害的事,对吧?但我从道听途说听到的是,他们还没在干任何厉害的事。而且我觉得,一旦他们……
Armin:对。一旦他们掌握了那个,那就会通过 RSI(递归自我改进)实现。模型会去做那些厉害的事,因为……
主持人:对。
Armin:突然之间一切都会变得容易。
主持人:好吧,我不得不……这其实是我觉得事情能变好的原因——现在我们还处于这种……对人类来说做这件事真的很烦,但如果模型认为值得花这个力气,而且那会推动它们前进,那也许通过自我改进就能把我们带过去。
Mario:用最新的 Opus,我有所有这些推理……我把推理任务交给它,它几乎是日复一日地在取得突破。就是……它在硬件到软件那一层,在那一层的穿梭上已经变得特别擅长了。GPT 在这方面完全不行。我不知道,它们的模型在数学和一些别的事情上更强,但对,我不知道。我、我、我觉得我在那边看到了一个突破,但那其实并不……
主持人:……
链接
原视频:https://www.youtube.com/watch?v=ja_7AF54OtE
频道:0xSero(Mario Zechner、Armin Ronacher)
本文是 Pi Durable 访谈译文三篇中的第 一 篇,全文共三篇。
#Agent工程 #持久化



