Agent 工程: 初探 OpenClaw 的 pi-mono 设计
https://github.com/badlogic/pi-mono
Pi 给我们描绘了一幅与今天主流 AI Agent 截然不同的蓝图。它不追求成为一个无所不知的“万事通”,而是立志成为一个潜力无限、与你共同成长的“学徒”。
这何尝不是 Ilya 想象中的 AGI 之一呢?
今天聊聊背后那个更低调、更硬核的“发动机”——一个名为 Pi 的编码智能体。这玩意儿是我的朋友 Mario Zechner 写的,现在已经成了我主力使用的编码工具。和 OpenClaw 那种追求“带点疯狂的科幻感”不同,Pi 的哲学非常务实和接地气。
这两个项目虽然风格迥异,但都建立在一个共同的认知上:LLM 最擅长的事就是写代码和跑代码,那我们就应该把这点发挥到极致。
一、Pi 是啥?
市面上的编码智能体(Coding Agent)已经多如牛毛,大部分产品的思路都是“功能求全”,恨不得把十八般武艺都给你预装好,就像一把功能繁杂的瑞士军刀。
但 Pi 恰恰相反,它走的是一条“大道至简”的路。在我看来,Pi 最吸引人的地方有两个:
- 一个极小化的内核:它的系统提示词(System Prompt)短到惊人,并且内置的工具只有四个,没听错,只有 Read、Write、Edit、Bash 这四个。
- 一个为“自生长”而生的扩展系统:它把所有“非必要”的功能都交给了扩展,并且这个扩展系统非常强大,甚至允许扩展在会话(Session)中持久化自己的状态。
除此之外,Pi 本身的代码质量极高,稳定、轻快、不占资源。它的作者 Mario 是个对软件品质有洁癖的人,这点在 Pi 的每一个细节里都体现得淋漓尽致。
更重要的是,Pi 不仅仅是一个工具,它更像一个可以用来构建你自己的智能体的“元工具集”。OpenClaw 就是基于 Pi 构建的,我自己也用它搭了个 Telegram Bot。
二、设计理念
2.1 Read, Write, Edit, Bash
- Read (读取文件):这是智能体感知环境的基础。没有读取,就没有上下文,智能体就像一个睁眼瞎。无论是分析现有代码、理解项目结构,还是查看错误日志,一切都始于 Read。
- Write (写入文件):这是智能体创造新事物的核心。创建新模块、生成配置文件、编写文档,所有从无到有的工作都依赖 Write。
- Edit (编辑文件):这是对现有事物进行修改的工具。你可能会问,有了 Read 和 Write,我完全可以先把文件读到内存里,改完再整个写回去,为什么还需要一个单独的 Edit?
- Edit 的存在至关重要,它代表了一种更高效、更精确的操作方式。 对于大文件,Read-Modify-Write 的模式不仅消耗大量内存和网络带宽(如果模型在云端),还会占用宝贵的上下文窗口。而 Edit 工具通常基于 diff 或 patch 的思想实现,它只向模型描述“如何修改”,比如“在第 57 行后面插入这段代码”或“将第 100 到 105 行替换成这段代码”。这种原子化的操作,对于 LLM 来说指令更清晰、执行更可靠,也更节省资源。
- Bash (执行 Shell 命令):这是智能体与操作系统交互、执行动作的唯一通道。编译代码(gcc main.c)、安装依赖(pip install requests)、运行测试(pytest)、操作版本控制(git commit),甚至是调用其他 CLI 工具,所有需要“让事情发生”的步骤,都由 Bash 完成。
这四个工具构成了一个完美的闭环:通过 Read 感知世界,通过 Write 和 Edit 改造世界,再通过 Bash 验证改造的结果,并从结果(标准输出/错误)中获得新的信息,再次 Read,进入下一个循环。
Pi 给我感觉就像一个顶级的厨师。他不需要一百种奇特的厨具,只需要一把好刀(Write/Edit)、一块砧板(文件系统)、一口锅(Bash)和一个炉子(计算资源),就能烹饪出世间万物。而其他智能体里那些五花八门的预置工具,更像是方便快捷的“预制菜包”,虽然开袋即食,但限制了你的创造力和最终能达到的高度。
2.2 不内置“大一统”的工具协议
现在很多 AI Agent 框架,比如 LangChain,或者像 OpenAI 的 Function Calling,都致力于定义一套标准的工具调用协议,比如 MCP。开发者可以方便地引入社区写好的各种工具(Tool)或技能(Skill),比如网页浏览、数据库查询、API 调用等等。
Pi 却刻意地、哲学地避开了这条路。它的核心理念不是让你去“下载”一个别人写好的工具,而是让你去“命令”智能体为你“现场写一个”。
这背后是一种深刻的“授人以鱼不如授人以渔”的思想。
- 传统方式:你想让 Agent 浏览网页。你可能会去找一个 WebBrowser 工具,配置好,然后加载到 Agent 里。Agent 知道有这么个工具,以及它的输入输出是什么。
- Pi 的方式:你想让 Agent 浏览网页。你会对 Pi 说:“我需要你获取网页 https://example.com 的内容。你可以写一个 Python 脚本,使用 requests 库来实现。如果 requests 没装,就用 pip 装一下。”
你可能会觉得,这不麻烦吗?但从“养一个 Agent”的长期主义视角看,这种方式的优势是巨大的:
- 终极的灵活性:预制的工具总有其局限性。比如,一个通用的网页浏览工具可能不支持登录、处理动态加载内容或者自定义请求头。但在 Pi 的模式下,这些都不是问题。你可以随时让 Agent 修改它的脚本,比如换用 Playwright 或 CDP (Chrome DevTools Protocol) 来处理复杂的前端页面,或者在脚本里加上处理 Cookie 的逻辑。工具本身也成了代码,代码就是可以被修改的。
- 自我维护与迭代:Agent 写的工具脚本,它自己最清楚。当脚本因为网站改版或库更新而失效时,它可以通过读取错误日志,自行 Edit 脚本来修复问题。这个工具的生命周期是内化的,由 Agent 自己负责,而不是依赖某个外部社区的维护者。
- 避免依赖地狱和版本冲突:每引入一个外部工具,就意味着引入了一堆新的依赖。而 Pi 的模式下,所有“技能”都是按需生成的原生代码,依赖关系清晰可控,由 Agent 在当前项目环境中自行管理。
2.3 Agent Build Agent
2.3.1 Session as a Tree
传统的 Agent 会话就像一条单向的聊天记录,从上到下,一条道走到黑。如果你在做一个复杂任务的中间,发现某个依赖的工具坏了,或者想去探索一个旁支的可能性,你通常只有两个选择:
- 在当前会话里硬着头皮去修复或探索,这会严重污染主任务的上下文,让 Agent “分心”。
- 开一个新会话,但这样又丢失了主任务的所有背景信息。
Pi 的会话是“树状”的。你可以把它想象成在使用 git。
- 主干 (main branch):你正在让 Agent 开发一个新功能。
- 分叉 (branching):突然,你发现 Agent 用来格式化代码的脚本有个 bug。这时,你不用打断它,而是可以从当前会话点“分叉”出一个新的会话分支,就像 git checkout -b fix-formatter。
- 支线任务 (side-quest):在这个新分支里,你专注于让 Agent 修复那个脚本。你们来回测试、修改,直到脚本完美工作。这个过程中的所有上下文都隔离在这个分支里,不会干扰主干。
- 回归与总结 (rewind & summarize):修复工作完成后,你可以“倒带”回主干分叉前的那个点。最神奇的是,Pi 能够总结你在那个修复分支里都干了些什么,然后把关键信息(比如“我已经修复了代码格式化工具”)以摘要的形式带回到主干的上下文中。
这种树状会话结构,完美映射了真实世界中程序员解决复杂问题的非线性心智模型。 它使得 Agent 可以在不丢失主线任务焦点的情况下,从容地处理各种“插曲”和“探索”,极大地提升了处理复杂、长周期任务的能力。
2.3.2 状态持久化与热重载
当 Agent 决定为自己写一个新工具时,整个流程是这样的:
- 编写工具代码:Agent 使用 Write 或 Edit 工具,创建或修改一个 Python 脚本(或其他语言),这个脚本就是它的新“技能”。
- 状态持久化:Pi 的扩展系统允许将信息(比如这个新脚本可以作为一个名为 /new_skill 的命令来调用)存入会话文件中。
- 热重载 (Hot Reloading):Pi 的核心运行时会监控这些变化,并能动态地、无需重启整个 Agent 会话,就加载这个新写的工具。
- 测试与迭代:Agent 立即通过 Bash 工具调用新工具进行测试。如果失败,它能读到错误输出,然后回到第 1 步,继续修改自己的代码。
这个 “编写 -> 加载 -> 测试 -> 修正” 的闭环,完全由 Agent 自主驱动,是“软件构建软件”理念的具体体现。 因为有了热重载,这个循环可以进行得飞快,Agent 就像一个不知疲倦的开发者,在自己的代码上进行着快速的 TDD (测试驱动开发)。
2.3.3 模型无关的 Session Format
Pi 的会话文件(Session File)设计得非常巧妙。它不仅存储了和 LLM 的对话历史,还能存储扩展自定义的元数据信息。这意味着会话状态可以非常丰富,比如某个扩展可以在会话里记下“这个文件已经被我处理过了”,而这些信息不一定需要发送给 LLM,避免了上下文的浪费。
同时,它的核心 AI SDK 也有意地避免过度依赖某个特定模型提供商的专有功能,这使得会话在不同模型(比如从 GPT-4 切换到 Claude 3)之间有更好的可移植性。
三、个人看法
**从“用软件”到“养软件”:**传统上,我们程序员是工具的“使用者”。我们选择 IDE、配置 Linter、安装库,我们搭建的是一个相对静态的工具链。而与 Pi 一起工作的体验,更像是在“培养”一个数字助手。这个助手一开始可能懂得不多,只有最基本的读、写、执行能力。但通过不断的交流和“教导”(即让它为自己编写工具和技能),它会逐渐学习你的工作习惯、掌握你所在项目的领域知识、形成一套为你量身定制的能力。
**自我进化是趋势:**一个 Agent 的价值,最终不取决于它出厂时会什么,而取决于它能多快、多好地学会新东西。Pi 的“自生长”闭环(编写 -> 热重载 -> 测试 -> 修正)指明了通往真正 AGI-like 编码助手的道路。未来的顶尖 Agent,一定是那些具备最强“元学习”能力的 Agent。
0