编程智能体的能力边界正在扩大 · Chameth.com
又到了聊大语言模型(LLM)的时候了!我知道,我知道,现在大家张口闭口都是这个。不过这也说得通:很多软件工程师每天的工作就是围着它转。而且它的变化实在太快了。去年五月,我写过这样一段话:
但它真正写代码的水平怎么样呢?就像身边有个热情十足、却不太细致的初级工程师随叫随到。如果你给出一个定义清晰的任务,再告诉它该怎么实现(最好在它提改动建议的时候给点反馈),它完全做得来。可一旦指引不够,它就容易跑偏。我试过让它从零生成一个简单应用,技术细节基本没交代,中间也不检查它做了什么——结果它搞出来一团乱麻,我索性全部丢掉,自己重新手写,反而更快。
当时我描述的其实是这么个意思:编程智能体能负责一个函数,如果函数描述得足够清楚,也能负责一组函数。那篇文章发布的时候,Sonnet 和 Opus 4 刚推出不久,之后又出了好几个大版本。
从函数升级到功能特性
不过那些光鲜的新版本,我并没有一直跟着 Claude 用下去。Anthropic 基本上禁止了订阅用户搭配第三方调用工具(harness),而且做法让我很不爽。在我看来,我买的是「推理即服务」——我用 Claude Code、OpenCode 还是别的什么工具来调用,不该有区别。但他们不这么认为。于是我就转投了 Z.ai 的 GLM 编程套餐。我当时签约的时候,一年的订阅费差不多等于 Claude 一个月的费用,额度还更高。
GLM 系列确实比不上 Claude,现在也还是比不上,但大多数时候够用了。随着新模型陆续发布,能力也一点点往上走。我注意到,交给它的活儿从单个函数慢慢变成了小而完整的功能模块。我不再描述具体的实现步骤,而是直接说要什么功能。具体怎么做我照样会给提示,但越来越愿意把更大块的活儿丢给它,拿回来的结果也还算靠谱。
差不多同一时间,部分模型的价格降了不少。新出的 flash 模型、token 折扣、额度重置这些加在一起,我发现自己怎么用都碰不到套餐上限。于是我给它的活儿越来越多:同时跑两三个任务,只在最后看一眼结果、提点后续要求。
从功能到成品
GLM 还撑不起更大的工作单元。我试着回头用 Claude,看看它现在什么水平,结果很快就放弃了——它的输出读起来实在太痛苦。我想试试它下一档的 Fable,但不用那些贵得离谱的套餐或者直接按 API 付费,根本用不了。这两个选项我都提不起兴趣。与此同时,OpenAI 推出了 Astra,对标的就是 Fable。而且在便宜些的套餐里也能小量使用。
我在 Astra 上试着做了些小东西,但心里一直记着额度有限。再说,零碎的活儿 GLM-5.3-flash 基本都能干。我盘算着,下次遇到大点的项目再正经试试 Astra。巧的是,没过多久一次网络丢包就给了我这个机会。
我把所有音乐都放在一台远程服务器上,用 Navidrome 托管,体验非常好——直到网络开始抽风为止。我用的那个播放器似乎压根没把缓冲当回事:链路到服务器出现 20% 丢包后,音乐就一直在卡,停一下、播一秒、再停一下、再播一秒,如此反复。这大概是它能给出的最让人抓狂的处理方式了。自己写一个播放器的念头在我脑子里转了一阵子,而现在我突然既有动力,又刚好有了一件趁手的新工具。
我启动了 pi,切到 Astra 的低思考模式,输入了这样一段提示词:
这是一个新项目。要做成一个用 Go 写的原生音乐播放器,基于 Gio 库,后端接 Navidrome 服务器。可以理解成 foobar2000,但是 Linux 原生、Go 实现、面向 Navidrome。不需要一上来就什么都有,但 MVP 应该能做到:连接 Navidrome(保存凭据)、显示播放列表、按顺序播放某个播放列表、切换曲目、暂停/继续、调节音量等。它要能容忍网络问题——缓冲好几分钟的播放数据,或者干脆缓存一到两整首曲子。我还有两个用 Gio 做的 UI 项目可以参考,见 ../gtodo 和 ../glauncher。实际播放部分可以考虑用 mpv 这类成熟的后端,不过这不是硬性要求。在这个项目里,你是总负责人/协调者。你应该派出子代理来做调研、实现、调试等工作,子代理使用 zai/glm-5.3-flash 模型。有问题随时问我。
我之前看过一些人的评论,他们也在做类似的「编排」;也见过有人提到 prime agent 这类原生支持这套流程的工具。这跟我的情况似乎天然契合:Astra 负责编排、架构和审查,而那些便宜得多的 GLM 模型去干真正的重活。它问了我几个问题,一小时后,一个功能完整的音乐播放器就出炉了:

刚出炉的 gmusic,正在放歌。
正是我想要的东西。一段提示词就产出一个功能完整的软件,多少有点让我难以置信。而且这还是在 Astra 开启低思考模式、用每月 20 英镑的套餐、调度更便宜的智能体的情况下做到的。提示词里其实藏了不少判断,光“think foobar2000”这两个词就承载了大量信息,但跟我平时写的东西比起来,细节还是少得多。输入一段描述,输出一个可执行文件,就这样。
到现在我已经用了 gmusic 一周,只做了几处小补充,就把它从“最小可用版本”变成了“日常用起来顺手”:支持 scrobbling(把播放记录同步到 Last.fm)、媒体键控制,以及重启后记住播放位置和播放列表位置¹。
牛、宠物、提示词,以及学会说“不”
能从一段文字生成可执行文件,这件事改变了我看待软件的方式。运维人员常说要把服务器当“牛,而不是宠物”:一头牛出了问题,你直接把它宰掉,自动重建或重新部署就行。它没有什么特别的价值,所以你不必慢慢把它养回健康状态,也不用花大把时间重新搭建一遍。我觉得这种态度现在也适用于软件了。
如果 gmusic 后来暴露出什么严重的架构缺陷——这是有可能的,因为我压根没看过它的源码——那我就把整个东西扔掉,把原来的提示词再加上一段“这次该怎么避免同样的错误”,喂进去,再拿回一个差不多够用的版本。
当然这里也有局限:“从一段话到成品”的这条流水线是随机的,所以你未必真能拿回一个足够相似的版本。而且你得愿意把整个东西扔掉、等一个新的出来。对一个音乐 App 来说没什么大不了,但换成业务关键的应用程序,我可不想要这种态度。反方向也有个有意思的地方:模型能力进步得这么快,有时候你反而会想把它扔掉重新生成一遍。“用提示词重新生成 App”会不会变成新的“安装更新”?
从这种视角出发,自然能得出一个结论:有记录的意图才是最重要的。你的提示词,以及后续的修正和补充,比生成出来的代码更重要。我喜欢保留某种决策日志,以后可以让 agent 去参考,但还没找到好办法。让 agent 自己来写,会暴露一些明显问题:它们很难分清哪些是有意做出的决定,哪些只是实现过程中顺带的细节;也选不好该写到多细,而且似乎永远没法摆脱之前记录下来的行为。
由 agent 管理的文档,最后常常会变得像邪教。第一版大概还凑合。接着,下一个碰它的 agent 就会忍不住把自己正在做的东西塞进任何列表、时间线或历史记录里。时间一长,一句关于某样东西当初怎么做的多余注释,会慢慢完成一次认识论上的转变,直到被所有后续 agent 当成必须遵守的天条。一团糟。
我觉得这还是更大的问题的一部分:模型还是太会讨好人了。不管是面对用户还是文档,它们都很少反驳。如果我让某个 agent 给 gmusic 加一个功能,用摄像头拍我的烤面包机,等面包烤好了就提醒我,它也会照做。你要是不留神,软件里就会多出 7 个厨房水槽和 3 把瑞士军刀,而 agent 从头到尾都不会建议把它们拆出去,或者重构。不知不觉间,你养的牛就变异成了长着太多肢体的畸形宠物。
当前这一代模型几乎肯定有能力反驳离谱需求、阻止范围蔓延、通过提问来确定某个东西该做多稳、边界情况该怎么处理,等等。你甚至可能可以用提示词让它们这么做,但在默认状态下,RLHF2 似乎已经把这一套全推平了,只留下一个唯唯诺诺的应声虫。
从产物到系统?
我认为智能体目前的状态是,它们能够负责“产物”,已经从函数和特性层面毕业了。这是我特意选用的措辞:它们无法负责完整的应用或系统,因为它们不会独立地退后一步,做出必要的判断。
很容易想象一个完美的软件工厂:一个智能体负责产品管理,一个负责架构,一个管理文档,等等,每个都在提示词中带有自己的观点和优先级。如果不小心,你很快就会开始谈论polecats和deacons,并向前沿实验室开出巨额支票。
我确实认为这种编排有一定好处,但增加戴不同帽子的智能体带来的帮助也是有限的。而且我愿意花在推理上的钱也是有限的!我从一个专门的代码审查智能体中获得了不错的收益。它经常能抓住其他模型忽略的一两个问题,所以我得到了明显且直接的“投资回报”:花几便士运行deepseek-4.1-flash加上代码审查提示词,就能让我少几个bug。
我认为这基本上就是我目前的底线了。我几乎想要一个“文档审查”智能体来尝试处理我前面提到的一些问题,但我觉得不值得。也许随着本地模型变得更强,这会是个有趣的实验。
用确定性替代提示词
有一件事让我感兴趣:我们能在多大程度上摆脱这些有问题的行为,而不依赖模型去记住并遵循指令?我遇到过智能体因为子智能体的非快进合并而搞乱git历史的问题。“自然”的修复方法是提示智能体不要那样做,但这依赖于它遵循那一条特定指令。它并不总是照做。于是我写了一个简单的pi扩展,检查git历史,如果发现问题就告诉智能体去修复。到目前为止成功率是100%。
同理,在 gmusic 的提示词里,我也告诉过智能体该给子智能体用哪个模型。这么干了一阵子之后(后来我把这些指令提升成了一个技能,不用每次手打),我发现它偶尔还是会自作主张换个模型。所以现在我又写了一个 pi 扩展,用我指定的模型来定义子智能体的角色,这样它们就不能由着性子乱来了。
这让我开始琢磨:扩展智能体能力的下一步,未必是更强的模型,也未必是给智能体分派更多角色,而是软件工程上的严谨。假如我们能准确评估什么时候该重构、文档质量到底如何,那就可以直接定下硬性规则,让智能体照章办事。不过这个“假如”可是承重墙——请原谅我用了 Claude 式的说法。
不管怎么实现,那一天可能并不遥远:一句提示词就能变成一份完整、可维护、安全、有文档的软件。等普通用户随口一喊就能召唤出好用的软件来干任何事,那场面会非常有意思。我不太确定这对我的软件工程师职业生涯意味着什么:流程里还有很多环节需要知识、经验和判断力,但也许用不了多久就不需要了?不管怎样,前方都是有趣的时代。
-
这倒是帮我解决了一个困扰已久的小麻烦:我有个“Daily Mix”播放列表,每天自动生成。在老播放器里,它实际上会把整个列表排进队列,所以第二天打开时,我还在听旧的每日列表。结果就是我不能直接在键盘上按播放键,得先找到应用、点开新列表、再按播放。这问题本身不算严重,但每天都要被扎一下,能摆脱它我还是挺高兴的。↩︎
-
或者现在流行的其他什么后训练方法。↩︎
本内容也在以下外部站点发布/讨论:
- Bluesky
喜欢这个页面?只是想声明自己读到了最后?就是喜欢按按钮?
给我点个头,让我知道你来过。没有追踪,没有计数器,只是路过时点个头。
提交此表单时,个人数据将如何使用和保留,请参见 colophon。