ARTICLE · 1113041
OpenClaw 2.0 | 01 引擎收回来了:OpenClaw 自己实现了运行时,Pi Agent 不再是外部依赖
「OpenClaw 2.0」系列第一篇。
先交代版本。官方把 v2026.8.1 叫作 OpenClaw 2.0,发布文档的标题就是"v2026.8.1 (AKA OpenClaw 2.0)"。这个系列拆的是它之后的 2026.9.4,比 2.0 又往前走了几个版本。

拆一个 agent 框架,绕不开的第一个问题是:那个反复"调模型、执行工具、再调模型"的循环,是谁写的,谁在维护。OpenClaw 的答案在 2026.5.22 这个版本里变了,CHANGELOG 里有一行:internalize the former Pi agent runtime into OpenClaw, remove legacy package dependencies。意思是把原来那套 Pi 运行时并进 OpenClaw 自己的仓库,旧的包依赖删掉。在这之前,OpenClaw 的 agent 循环建立在一个叫 Pi Agent 的开源框架(pi-mono,作者 Mario Zechner)上。这事发生在 2.0 发布之前,2.0 是在这个新底座上发出来的。
如果你读过我的拆解系列第 09 篇,里面有一句话:OpenClaw 的 Agent 引擎不是自己写的,是基于 Pi Agent。这句话现在不成立了。
Pi 没有消失 -- 它被收进了自己家
先别误会成"换了台新引擎"。拿车打个比方:Pi 是发动机,OpenClaw 是整辆车。以前发动机是外购的,现在图纸收进了自己厂里,自己造,自己保养。
证据在仓库里摆着。架构文档开头第一句是 "OpenClaw owns the built-in agent runtime",往下还有一句 "No external agent framework packages remain",外部的 agent 框架包一个不剩。package.json 里带 pi 字样的依赖只剩一个,@earendil-works/pi-tui,管终端界面渲染,文档说把它也收进来是另一件单独的搬运活。
我进代码里核对了一遍,全仓没有任何一处代码还在 import pi-ai、pi-agent-core、pi-coding-agent。
血脉没断,许可也还在。仓库根目录的 THIRD_PARTY_NOTICES 里写着 "Portions of OpenClaw were adapted from Pi / pi-mono",MIT 协议,版权归 Mario Zechner;docs/reference/credits.md 里也把他列为 Pi 的作者。但"改造过"到底改了多少,官方没说,我自己去量了一遍,下一节给结果。
Pi 原本是四层分包:pi-ai 管模型通信,pi-agent-core 是循环,pi-coding-agent 管会话持久化、压缩、扩展加载,pi-tui 管终端界面。按职责对一下现在落在哪:pi-ai 对应 packages/ai,pi-agent-core 对应 packages/agent-core,pi-coding-agent 管的会话和工具渲染,落在 src/agents/sessions,pi-tui 原样还是外部依赖。这是按职责对的,具体改了多少,下一节有逐行比对的数。
顺带一个小细节:运行时 id 里还留着一个旧别名 pi,配置里写 pi 会被自动规范成 openclaw。
到底改了多少 -- 我把两边的代码摆在一起对了一遍
方法很笨,但够直接。我拿上游 pi-mono 的 v0.75.1(2026-05-18 发布,是 CHANGELOG 里查得到的、OpenClaw 并入之前最后一次升级的 Pi 版本)和 OpenClaw 2026.9.4 的源码,一行一行比。只数非测试代码里、长度 30 个字符以上、去掉 import 的行,在对方那边一字不差才算相同。
先看底噪。gateway、extensions 这些肯定不是从 Pi 来的目录,相同行只有 0.3% 到 0.6%;pi-tui 是外部依赖、没拷过来,留在 OpenClaw 里的也只有 2.3%,同一个量级。
结果是这样。近的部分是会话:src/agents/sessions,也就是会话管理和工具渲染,有 45.7% 的行跟 Pi 一样。远的部分是循环和运行器:packages/agent-core/src/agent-loop.ts 只有 17.4% 的行跟 Pi 一样,文件从 Pi 的 718 行长到了 1,667 行;src/agents/embedded-agent-runner,也就是 OpenClaw 自己的运行器,相同行只有 0.6%,基本是自己写的。
所以回到开头那个问题。新版跑的不是 Pi 的运行时,跑的是 OpenClaw 自己的。只是地基里,会话这部分有近一半的行是从 Pi 改过来的;真正驱动一轮对话的循环和运行器,已经是另一个东西了。
三处局限:只数一字不差的行,改了格式或变量名的不算,所以真实的相似度只会更高;比的是 2026.9.4 的代码,不是并入那一刻的快照;上游 v0.75.1 也不一定恰好是并入的那个提交。
为什么要收回来 -- 几条修复说的是同一件事
CHANGELOG 里没有哪一段写"我们为什么要去掉 Pi"。下面是我从几条修复里读出来的,不是官方原话。
第一条,issue #73781。Pi 自带一套自动重试,OpenClaw 自己也有一套重试加模型切换,两层叠在一起,一次失败的工具调用会被里面那层 SDK 再重放一遍。修法是把 Pi 那层的自动重试关掉。
第二条,issue #73003。长会话压缩,Pi 有一套,OpenClaw 也有一套,两边互相抢。修法是只要 OpenClaw 自己管着压缩,就把 Pi 的自动压缩关掉。
第三条,issue #84059。飞书、Slack、Telegram 和定时任务里,跑得久一点的回合会报出假的"会话被接管"错误,原因是 OpenClaw 自己往转录里写东西,被当成了别人在动手。
三个 bug 长得不一样,病根是一个:重试、压缩、会话写入,这三样都是"谁说了算"的事,里外两层各有一套,就一定会打架。做过微服务的人都见过类似的场面,网关重试三次,下游服务自己再重试三次,一次失败能放大成九次请求。
现在的引擎 -- 四层,不是一层
文档把一次对话里容易混的东西拆成四层:provider、model、agent runtime、channel。真正跑循环的是 runtime 这一层,内置的 openclaw 只是它的选项之一。Claude Code、Gemini CLI 这些外部工具走 ACP,留到第 10 篇。

runtime 挂在 provider 或 model 条目的 agentRuntime.id 上,不设就是 auto。光凭 provider 或模型前缀,不会选中某个运行时。OpenAI 是个特例,只有走官方 HTTPS 的 Responses 路由、而且没有自定义请求覆盖的时候,才会隐式选到 codex。

我打开了 mbp 上跑着的 2026.9.4 Gateway 的控制台看了一眼,智能体页上主模型是 openai/gpt-5.6-sol,运行时是 codex,跑循环的根本没走内置那套。换模型和换运行时,是两个旋钮。
渠道在哪 -- 全在 extensions 里
新版架构文档的描述是这样:一个长驻的 Gateway 管着所有消息渠道,控制端(mac app、命令行、网页)和 Node(手机、无头设备)通过 WebSocket 连进来。渠道的实现在 extensions/ 下面,一个渠道一个插件目录,telegram、slack、discord、whatsapp、feishu、signal、imessage、matrix、line、msteams 都在。整个 extensions 目录一共 163 项,模型提供商、语音、搜索也都在里面。
状态也搬了家
会话和转录现在都进了 SQLite。老的 sessions.json 和 JSONL 只能靠 openclaw doctor --fix 导入,Gateway 启动时发现旧库,会直接拒绝报就绪。这部分第 02 篇细讲。
收尾
借来的引擎跑得再快,出了事方向盘也得在自己手里。并进来换来的,是重试、压缩、会话写入这几件事只剩一个人说了算。代价是 Pi 往后的改进要自己跟,这个代价官方没写,是我的判断。
你们团队里,有没有哪个依赖是用着用着,最后决定直接并进自己仓库的?当时是被什么逼的?评论区聊聊。
下一篇聊跨会话:会话重置之后,它为什么还能翻出重置前的那句话。