“Pi 能不能装几个插件,直接变成 Hermes 或 OpenClaw?”
这个问题很容易被功能表带偏。四个项目都能接模型、调工具,也都能扩展;如果只看这些方框,Pi 和它们像是少装了几块积木。
但顺着 Pi 的源码往下看,结论要更克制一些:Pi 是一个把 Agent 循环、会话与扩展接口做得很干净的 Harness;Hermes、OpenClaw 和 nanobot 则把消息入口、持续运行、记忆、调度与治理一起交付成了 Agent OS。
前者可以长成后者,但不是把 Extension 数量加到某个阈值就会自动发生。缺的不是一个天气工具,而是一组必须共同运行、共同审计的控制面。
#先说结论
Pi 适合作为可控的 Agent 执行底座;若目标是“开箱即用的个人助手”,还需要另行拥有或选择提供渠道、调度、身份、权限、记忆和运维的 Agent OS。本文据此区分源码已经提供的能力与必须由上层补齐的责任。
数据快照
- 最后核验:2026-08-06
- Pi 源码快照:
bde81c8(main分支当日提交)- 主要对象:Pi Agent Harness、Hermes Agent、OpenClaw、nanobot
- 讨论边界:本文比较它们的运行时职责,不比较模型能力、社区规模或某次任务的成功率
- 证据限制:Pi 部分以固定源码快照为准;其余三个项目的“开箱能力”来自当日官方 README / 文档,不能推出它们在每种部署配置下都有相同表现
#先把“Agent”拆成两层
用人话说,Harness 是发动机和驾驶控制:给它任务、模型、工具与状态,它能把一轮又一轮工作跑完。Agent OS 则还要负责让这台发动机长期待命:消息从哪里进来、该由哪个会话处理、什么时候唤醒、用谁的身份访问外部系统、出了问题如何停下与追溯。
表 1:四个项目的公开职责边界;状态以 2026-08-06 的官方资料为准
| 维度 | Pi | Hermes Agent | OpenClaw | nanobot |
|---|---|---|---|---|
| 核心定位 | 可嵌入的 Agent runtime 与 coding CLI | 自我改进的个人 Agent | 运行在设备上的个人助手 | 自托管个人 Agent runtime |
| 单轮 Agent loop / 工具调用 | 有 | 有 | 有 | 有 |
| 扩展入口 | TypeScript Extension、工具、事件与 TUI | 工具、Skills、插件与多种后端 | Tools、Skills、Plugins | Python SDK、MCP、工具与子 Agent |
| 消息与网关 | 主仓库不提供个人助手网关;另有 pi-chat 项目面向聊天自动化 | Gateway 连接多种聊天渠道 | Gateway 统一会话、事件与渠道 | WebUI、聊天应用与长期运行 gateway |
| 持续任务与长期记忆 | 可由扩展自行实现 | 内置 cron、跨会话记忆与 skill 演化 | Gateway、渠道、工具与设备节点构成持续服务 | goals、memory、cron 与 automation 已在运行时中提供 |
| 默认安全边界 | 不内置文件、进程、网络或凭据权限系统 | 提供命令审批、配对和隔离文档 | 有配对、sandbox 与暴露运行手册 | 需按其配置与部署文档审查 |
Pi 的项目 README 明确把自己拆为 pi-agent-core、pi-ai、pi-coding-agent 和 TUI:运行循环、模型适配、交互式编码界面各自独立。Pi README 对这个边界说得相当直白。相对地,Hermes、OpenClaw 和 nanobot 的公开入口都把聊天渠道、持续服务或自动化放进产品定义。
这不是“谁更高级”的排序。想在本地终端里精确控制一个 Coding Agent,较小的 Harness 往往更舒服;想让同一个 Agent 在 Telegram、定时任务和多天记忆之间持续工作,OS 的默认层反而省掉大量不显眼的工程。
#Pi 的最小闭环:Agent 只负责把一轮工作跑完
Pi 的 packages/agent/src/agent.ts 是理解边界最短的入口。Agent 保存当前 transcript、工具集和模型状态;收到 prompt 后,它把消息交给 runAgentLoop(),并在循环中收集模型消息、工具执行和生命周期事件。Agent.prompt() 与 runAgentLoop() 的关系大致可以浓缩成下面这样;为说明结构,省略了类型、流式更新与错误处理。
class Agent { async prompt(input: string) { const messages = this.normalizePromptInput(input); await runAgentLoop( messages, this.createContextSnapshot(), this.createLoopConfig(), (event) => this.processEvents(event), signal, this.streamFunction, ); }}这个对象的职责很明确:模型是否继续、工具何时执行、结果怎样进入下一轮上下文,都是 loop 的内部问题。源码还把 beforeToolCall、afterToolCall、shouldStopAfterTurn 和 prepareNextTurn 放进 loop 配置中。对应的配置装配代码 证明了它为外部策略留出了钩子;它不能证明 Pi 已经替你定义了“什么任务应该每天九点运行”或“陌生 Telegram 用户能否创建会话”。
图 1:Pi Agent 的单次执行闭环;依据 2026-08-06 的源码快照
flowchart TD
S([开始:输入 prompt]) --> A[Agent 生成消息与上下文快照]
A --> B[runAgentLoop 请求模型]
B --> C{模型请求工具?}
C -- 是 --> D[执行或拦截工具调用]
D --> E[工具结果写入 transcript]
E --> B
C -- 否 --> F[发出 turn_end / agent_end 事件]
F --> G([结束:本次 Agent run 空闲])
H[外部 hook] -. 可改工具、停止或下一轮 .-> D
H -. 可改工具、停止或下一轮 .-> B
读图时最值得注意的是终点:它是“这次 run 空闲”,不是“服务继续待命”。Pi 的 loop 已经是 Agent 最难替换的一部分,但长期运行的入口和调度不在这段 loop 里。
#AgentSession 补的是会话,不是控制平面
如果只看 Agent,Pi 像一个很干净的循环库;pi-coding-agent 再用 AgentSession 把它变成可交互的产品。这个类被 interactive、print、RPC 等运行模式共享,负责自动保存会话、模型与 thinking level、压缩、分支和 bash 执行。文件头的职责说明 与 它对 Agent、session manager、extension runner 的依赖 共同说明了这层的任务。
这给 Pi 带来两个很实际的能力:同一段对话可以恢复、压缩和分叉;不同交互界面可以复用同一会话运行时。它仍然没有替上层回答三个 OS 问题:
- 一条外部消息怎样路由到正确的
AgentSession; - 没有前台终端时,谁负责唤醒、超时、重试和投递结果;
- 这次会话的 shell、网络和凭据到底代表哪个用户、遵循哪套审批规则。
把 Session 当成 Memory 也会造成误判。Session 首先是可恢复的执行记录和当前上下文;长期偏好、跨任务知识、可检索事实、失效策略分别需要不同的写入条件、作用域和淘汰策略。Hermes 所说的跨会话记忆与 Skills 演化,或 nanobot 所说的长期记忆,讨论的是这个更上层的问题,而不仅是“把 JSONL 留在磁盘上”。
#Extension 给了积木,但没有替你画出城市规划
Pi 的 Extension API 比“插件能加一个工具”宽得多。扩展可以注册模型可调用的工具、订阅生命周期事件、拦截或修改工具调用、注入上下文、定制压缩、添加命令和 TUI,并用 appendEntry() 保存自定义状态。官方 Extension 文档 还明确说明,扩展拥有宿主进程的完整系统权限。
这意味着对话中的判断有一半是对的:可以在 Pi 上做出 memory tool、浏览器工具、定时任务入口,甚至做一个分层的审批界面。比如,下面这种拦截确实可以把危险 shell 命令从“模型想调用”变成“用户确认后才调用”。
pi.on("tool_call", async (event, ctx) => { if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) { const ok = await ctx.ui.confirm("危险命令", "是否允许执行?"); if (!ok) return { block: true, reason: "Blocked by user" }; }});但它也恰好解释了为什么“装插件就开箱即用”不成立。上例只是一个字符串规则:它没有识别软链接、间接执行、远程 shell、凭据外泄,也没有给后台任务提供可复核的身份。Pi README 对此的立场很明确:它不含限制文件系统、进程、网络或凭据访问的内置权限系统,默认使用启动进程的权限;更强边界需要容器化或 sandbox。权限与容器化说明 不是缺失的文档,而是项目有意保留给宿主的责任。
#从 Pi 长成 Agent OS,真正要补的是五条跨层链路
把工具、记忆、渠道这些名词列出来很容易;困难在于它们必须和同一份身份、状态和审计记录连起来。下面的图不是 Pi 当前架构,而是基于其公开扩展点作出的实现建议。
图 2:在 Pi 之上增加 Agent OS 控制面的建议分层;这是本文的工程推断,不是 Pi 官方路线图
flowchart TB A[渠道:TUI、Web、Telegram、飞书] --> B[Gateway:鉴权、限流、会话路由] C[Scheduler:cron、事件、重试] --> B B --> D[Control Plane:任务、身份、审批、审计] D --> E[Pi AgentSession] E --> F[Pi Agent loop] F --> G[工具与 MCP] G --> H[执行边界:沙箱、网络、凭据代理] I[Memory:短期、长期、知识、经验] <--> D I <--> E J[Eval:验收、失败分类、回归] --> D J --> E
其中最容易被低估的有五条:
- 渠道到会话。 收到消息不是
session.prompt(text)就结束了。还要确定发送者、租户、会话 key、并发策略和结果回投位置。 - 任务到调度。 cron 触发后需要去重、超时、重试、失败通知和停止开关,否则“每天总结”很快变成每天制造一条无人处理的失败日志。
- 记忆到权限。 一条长期记忆应属于用户、项目还是共享空间?能否被低权限渠道读到?何时撤回?这些都不能交给向量检索的相似度独自决定。
- 工具到执行边界。 模型提出一个 tool call,只是意图;真正的权限检查应在网络、文件、进程和凭据即将产生副作用的位置再次发生。
- 结果到评测。 Loop Engineering 不是“失败了再塞一句反思 prompt”。至少要能记录目标、成功信号、失败类别与重试预算,才知道循环是在变好还是只是在多花 token。
所以 Pi 很适合承担图中的 AgentSession + Agent loop:核心循环小、生命周期清楚、工具和 UI 可替换。Graph Engineering 也不是做不到,只是图中的 Planner、Coder、Reviewer、Judge 不能只靠一次 Agent.prompt() 自然长出来;你还要在 Control Plane 定义节点状态、边条件、并发、失败回收和最终验收。Pi 可以是图节点的执行器,却不会自动成为图调度器。
#怎样选择:不要先问“能不能”,先问哪一层该由谁拥有
如果目标是可改造的 Coding Agent、特殊工具链,或一套需要自己掌握调度语义的 local-first runtime,Pi 是很好的起点。你可以把最小闭环跑通,再逐层增加有明确需求的渠道、Memory、审批和评测。
如果目标是今天就要通过聊天渠道处理持续任务,优先评估 Hermes、OpenClaw 或 nanobot 是否已经覆盖你的部署、身份与安全要求。它们省下的不是几段 plugin 代码,而是网关、生命周期和默认操作路径;当然,也会把更多运行时行为带进你的系统。
最需要避免的路线是:先把 Pi 接到所有渠道和高权限工具,再补权限、持久化和观测。那会得到一个很会做事、但没人说得清它什么时候醒来、拿谁的权限、又留下了什么的 Agent。
#总结:Pi 缺的不是能力清单,而是 OS 的责任边界
Pi 已经提供了 Agent 的骨架:模型调用、工具循环、会话、压缩、扩展与交互界面。源码中的 Agent 和 AgentSession 也解释了它为什么特别适合做 Loop Engineering 的执行底座:每一轮的状态、生命周期和工具调用都有明确入口。
但 Hermes、OpenClaw、nanobot 所在的层次不只是“更多 tools”。它们把渠道、Gateway、定时任务、长时记忆、身份、安全和持续运维组合成一个长期服务。Pi 可以向上生长,前提是你愿意明确拥有这些控制面的设计与维护。
下一篇会继续沿着 Pi 的源码看 Extension:一个扩展究竟能在什么时机改变上下文、拦截工具和保存状态;以及为什么这既是 Pi 最强的可塑性,也是最需要先设计安全边界的地方。