OpenClaw 嵌入 Pi 架构深度解析
如果你用过 OpenClaw,可能会注意到它不仅能聊天,还能帮你写代码、调试程序——这个能力来自它与 Pi(pi-coding-agent)的深度集成。
今天这篇,带你完整了解 OpenClaw 是如何把 Pi 这把"编程神器"嵌入到自己的架构里的。
概述:为什么要嵌入 Pi?
OpenClaw 是一个消息网关,它需要支持各种渠道(微信、Telegram、Discord 等)的对话。但光聊天不够——用户还希望它能帮忙写代码。
传统做法是把 Pi 当作子进程启动,或者用 RPC 模式调用。但 OpenClaw 选择了更深入的方式:直接导入并实例化 Pi 的 AgentSession,通过 createAgentSession() 来运行。
这样做的好处是:
- 完全掌控会话生命周期和事件处理
- 自定义工具注入(消息、沙箱、渠道特定操作)
- 系统提示可按渠道/上下文动态定制
- 会话持久化,支持分支和压缩
- 多账号认证配置,支持故障转移
- provider 无感知模型切换
依赖的包
OpenClaw 嵌入了 Pi 的多个核心包:
| 包 | 作用 |
|---|---|
pi-ai | 核心 LLM 抽象:Model、streamSimple、消息类型、provider API |
pi-agent-core | Agent 循环、工具执行、AgentMessage 类型 |
pi-coding-agent | 高层 SDK:createAgentSession、SessionManager、AuthStorage、ModelRegistry、内置工具 |
pi-tui | 终端 UI 组件(用于 OpenClaw 本地 TUI 模式) |
核心集成流程
1. 运行嵌入的 Agent
入口是 runEmbeddedPiAgent(),位于 pi-embedded-runner/run.ts:
const result = await runEmbeddedPiAgent({
sessionId: "user-123",
message: "帮我写个快速排序",
// ...其他参数
});2. 会话创建
每个用户会话都有独立的工作目录:~/.openclaw/agents/<agentId>/sessions/。会话文件包括:
- 历史消息
- 工具调用记录
- 模型响应
3. 事件订阅
通过 subscribeEmbeddedPiSession() 订阅 Pi 的事件:
onBlockReply:流式响应块onToolCall:工具调用onError:错误处理onFinish:完成通知
4. 提示词构建
系统提示词是动态生成的,考虑了:
- 渠道类型(微信 vs Discord 格式不同)
- 用户偏好
- 当前上下文
- 可用工具列表
工具架构
工具管道
OpenClaw 的工具系统是一个管道:
- 工具定义适配:
AgentTool→ToolDefinition - 工具拆分:内置工具 vs 自定义工具
- 策略过滤:允许/拒绝列表
- 执行:通过
tools/下的各个实现
工具定义适配器
Pi 的工具格式和 OpenClaw 不同,pi-tool-definition-adapter.ts 负责转换:
- 参数类型映射
- 必填/可选字段处理
- 默认值注入
工具拆分策略
const { builtIn, custom } = splitTools(allTools);
// builtIn: Pi 自带的编码工具
// custom: OpenClaw 的消息、浏览器、cron 等会话管理
会话文件
每个会话存储在独立目录:
~/.openclaw/agents/<agentId>/sessions/<sessionId>/
├── messages.json
├── tools.json
└── metadata.json会话缓存
SessionManager 实例会被缓存,避免重复创建。缓存 key 基于 agentId + authProfile。
历史限制
根据渠道类型限制历史长度:
- 私聊:保留更多历史
- 群聊:减少历史以节省 token
压缩(Compaction)
当上下文接近模型限制时,自动压缩历史:
- 合并相似消息
- 删除冗余工具调用
- 重写为摘要
认证与模型解析
认证配置
支持多认证配置(Auth Profiles),每个配置包含:
- API Key
- Provider
- 模型偏好
配置支持冷却时间和故障转移。
模型解析
通过 ModelRegistry 根据配置和可用性自动选择模型。
故障转移
当主要模型失败时,自动切换到备用模型:
try {
return await callPrimaryModel();
} catch (e) {
if (isFailoverError(e)) {
return await callBackupModel();
}
throw e;
}Pi 扩展
OpenClaw 还实现了自定义扩展:
压缩保护
确保压缩操作不会丢失关键上下文。
上下文修剪
基于缓存 TTL 的自动上下文清理:
// 超过 TTL 的缓存消息会被清理
if (message.timestamp < Date.now() - cacheTTL) {
prune(message);
}流式响应与块处理
块分片
Pi 的响应是流式的,pi-embedded-block-chunker.ts 负责将流切分成合理的块:
const chunks = chunkStream(stream, {
maxSize: 500,
splitOn: [" ", "\n"]
});Thinking/Final 标签剥离
Pi 输出包含 <thinking> 和 <final> 标签:
const { text: cleanedText } = stripBlockTags(response, {
thinking: true,
final: true
});用户只会看到 <final> 里的内容。
回复指令
支持特殊指令:
[[media:url]]—— 插入媒体[[voice]]—— 语音回复[[reply:id]]—— 引用消息
错误处理
错误分类
pi-embedded-helpers.ts 提供了完整的错误分类:
isContextOverflowError() // 上下文溢出
isCompactionFailureError() // 压缩失败
isAuthAssistantError() // 认证失败
isRateLimitAssistantError()// 速率限制
isFailoverAssistantError() // 需要故障转移
classifyFailoverReason() // 分类原因Thinking Level 回退
如果请求的思考深度不被支持,自动降级:
const fallback = pickFallbackThinkingLevel({
message: errorText,
attempted: "high"
});
// 降级到 "medium" 或 "low"沙箱集成
开启沙箱模式时,工具和路径都会受限:
- 文件操作:限制在指定目录
- 执行命令:在容器中运行
- 浏览器:通过桥接 URL 访问
Provider 特定处理
Anthropic (Claude)
- 过滤拒绝回答的"魔字符串"
- 校验消息角色顺序
- Claude Code 参数兼容
Google Gemini
- 修复轮次顺序问题
- 工具 schema 清理
- 会话历史过滤
OpenAI (Codex)
- 使用
apply_patch工具 - 思考深度降级处理
TUI 集成
OpenClaw 还支持本地 TUI 模式,直接使用 @mariozechner/pi-tui 组件,提供类似 Pi 原生模式的交互体验。
与 Pi CLI 的关键区别
| 对比项 | Pi CLI | OpenClaw 嵌入版 |
|---|---|---|
| 调用方式 | pi 命令 / RPC | SDK createAgentSession() |
| 工具集 | 默认编程工具 | OpenClaw 自定义工具 |
| 系统提示 | AGENTS.md + 固定提示 | 动态按渠道/上下文生成 |
| 会话存储 | ~/.pi/agent/sessions/ | ~/.openclaw/agents/<agentId>/sessions/ |
| 认证 | 单凭证 | 多凭证自动轮换 |
| 扩展加载 | 从磁盘加载 | 程序化 + 磁盘路径 |
| 事件处理 | TUI 渲染 | 回调函数(onBlockReply 等) |
未来可优化方向
- 工具签名对齐:目前需要适配 pi-agent-core 和 pi-coding-agent 的签名差异
- Session 管理器封装:
guardSessionManager增加了复杂度 - 扩展加载:可以直接用 Pi 的
ResourceLoader - 流处理复杂度:
subscribeEmbeddedPiSession变得很大 - Provider 特性:很多特定模型的兼容代码可以交给 Pi 处理
测试覆盖
Pi 集成有完整的测试套件:
src/agents/pi-*.test.tssrc/agents/pi-embedded-*.test.tssrc/agents/pi-auth-json.test.tssrc/agents/pi-extensions/**/*.test.ts- 以及更多...
可选的实时测试需要设置 OPENCLAW_LIVE_TEST=1。
总结
OpenClaw 嵌入 Pi 的本质,是把一个强大的 AI 编程助手"装进"了一个全渠道通讯框架。
背后都是同一套 Pi 能力在支撑。这种深度集成的方式,让 OpenClaw 不仅仅是一个聊天工具,而是一个真正的 AI 工作助手。
如果你想了解更多技术细节,可以去看官方文档:https://docs.openclaw.ai/pi