OpenClaw 架构深度解析:多通道 AI 网关的工作原理
从 ReAct 理论到生产级 Agent 系统的实现之路
1. 引言:什么是 OpenClaw
OpenClaw 是一个个人 AI 助手网关,运行在你自己的设备上。它回答你在已有通讯工具(WhatsApp、Telegram、Slack、Discord、iMessage 等)上的消息,让 AI 助手感觉”本地、快速、始终在线”。
与轻量级的 nanobot 不同,OpenClaw 是一个生产级、全功能的 TypeScript/Node.js 实现,强调:
- 多通道消息集成(20+ 聊天平台)
- 本地优先的 Gateway 控制平面
- 可扩展的插件架构(Plugin SDK)
- 多平台原生应用(macOS/iOS/Android)
本文将深入剖析 OpenClaw 的核心工作原理,并与 nanobot 进行对比,揭示生产级 Agent 系统的设计哲学。
2. 核心架构:分层控制平面
OpenClaw 的架构可以用一个分层模型来理解:
┌─────────────────────────────────────────────────────────────────┐
│ 用户交互层 │
│ WhatsApp Telegram Slack Discord iMessage WebChat ... │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Gateway 控制平面 │
│ ws://127.0.0.1:18789 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Channel │ │ Session │ │ Cron │ │
│ │ Manager │ │ Manager │ │ Service │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Routing │ │ Presence │ │ Skills │ │
│ │ Engine │ │ Tracking │ │ Registry │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└──────────────────────────┬──────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Pi Agent │ │ CLI │ │ Web UI │
│ (RPC Mode) │ │ (openclaw) │ │ (Control) │
└─────────────┘ └─────────────┘ └─────────────┘
2.1 入站消息处理流程
用户消息 (Telegram/WhatsApp/...)
│
▼
Channel Adapter (extensions/<channel>/)
│ • 协议转换(各平台 API → 内部格式)
│ • 身份验证(DM pairing、allowlist)
│ • 媒体下载(图片/音频/视频)
│
▼
MessageBus (src/channels/bus.ts)
│ • 统一消息队列
│ • 入站/出站分离
│
▼
Routing Engine (src/routing/)
│ • 根据 channel/account/peer 路由到对应 Agent
│ • 多 Agent 隔离(工作区 + 会话隔离)
│
▼
Agent Loop (Pi Runtime via RPC)
│ • LLM 调用(工具定义注入)
│ • Tool Call 执行循环
│ • 流式响应
│
▼
Outbound Pipeline → 回传给用户
3. Agent 执行循环:ReAct 模式
OpenClaw 和 nanobot 都基于 ReAct(Reasoning + Acting) 模式,但实现方式有本质区别。
3.1 nanobot 的实现
# nanobot/agent/loop.py:195
while iteration < self.max_iterations:
response = await provider.chat(messages, tools=tool_defs)
if response.has_tool_calls:
result = await tools.execute(tool_call.name, tool_call.arguments)
messages = add_tool_result(messages, result) # 追加到上下文
else:
final_content = response.content
break特点:
- 完全自研,代码直接可见
- 显式操作
messages数组 - 简单的 callback 式流式处理
3.2 OpenClaw/Pi Agent 的实现
OpenClaw 不直接写 while 循环,而是通过 Pi Agent Runtime(@mariozechner/pi-agent-core)实现:
// 通过事件流订阅
session.subscribe({
onTextDelta: (delta) => { /* 流式文本 */ },
onToolUse: (tool) => { /* 工具调用 */ },
onToolResult: (result) => { /* 工具结果 */ },
onCompaction: (summary) => { /* 上下文压缩 */ }
});Pi Agent 的核心循环(简化版):
// 外层循环:处理 follow-up 消息
while (true) {
let hasMoreToolCalls = true;
// 内层循环:处理工具调用和 steering 消息
while (hasMoreToolCalls || pendingMessages.length > 0) {
// 1. 执行 steering 消息(用户中断/修改指令)
if (pendingMessages.length > 0) { ... }
// 2. 流式获取 LLM 响应
const message = await streamAssistantResponse(...);
// 3. 检查并执行工具调用(支持并行/串行)
if (hasMoreToolCalls) {
toolResults.push(...await executeToolCalls(...));
}
// 4. 再次检查 steering 消息
pendingMessages = await config.getSteeringMessages?.();
}
// 检查 follow-up 消息(任务完成后的延续)
const followUpMessages = await config.getFollowUpMessages?.();
if (followUpMessages.length > 0) continue;
break; // 真正结束
}关键创新:
- Steering(方向控制):运行中注入新指令
- Follow-up(任务延续):完成后的自动继续
- 并行工具执行:
toolExecution: "parallel"模式
4. Pi Agent 详解:底层的 ReAct 运行时
Pi Agent 是 OpenClaw 的底层 Agent 引擎,由 Mario Zechner 开发的一组 npm 包:
| 包名 | 职责 |
|---|---|
@mariozechner/pi-agent-core | 核心运行时 — Agent 循环、Session 管理、工具调用 |
@mariozechner/pi-ai | LLM 提供商抽象 — 统一接口调用各平台 API |
@mariozechner/pi-coding-agent | 编码 Agent 实现 — 代码编辑、项目理解 |
@mariozechner/pi-tui | 终端 UI — TUI 界面组件 |
4.1 事件驱动的架构
Pi Agent 将一切都抽象为事件流:
agent_start
├─ turn_start
│ ├─ message_start (user)
│ ├─ message_end
│ ├─ message_start (assistant)
│ ├─ message_update (text_delta/toolcall_delta) ← 流式
│ ├─ message_end
│ ├─ tool_execution_start
│ ├─ tool_execution_update (可选,工具流式)
│ ├─ tool_execution_end
│ ├─ message_start/end (toolResult)
│ └─ turn_end
├─ turn_start (如果有更多工具调用)
└─ agent_end
这种设计的优势:
- 解耦:Agent 逻辑与 UI 渲染完全分离
- 可观测:每个状态变化都有对应事件
- 可干预:通过 steering 机制可在运行中改变方向
4.2 消息模型的灵活性
Pi Agent 引入了 AgentMessage 抽象,支持声明式扩展:
// 基础消息
type AgentMessage =
| { role: "user"; content: ... }
| { role: "assistant"; content: ...; stopReason: ... }
| { role: "toolResult"; toolCallId: ... }
| CustomAgentMessages // ← 可扩展!
// OpenClaw 扩展示例
declare module "@mariozechner/pi-agent-core" {
interface CustomAgentMessages {
compactionSummary: {
role: "compactionSummary";
summary: string;
tokensBefore: number;
};
}
}上下文转换管道:
AgentMessage[] ──[transformContext]──► AgentMessage[] ──[convertToLlm]──► Message[]
↑ ↑ ↓
原始状态 应用级转换 LLM 兼容格式
(剪枝/压缩/注入)
4.3 工具执行模型
| 特性 | nanobot | Pi Agent |
|---|---|---|
| 执行模式 | 串行 | 串行 / 并行 |
| Hook 机制 | 无 | beforeToolCall / afterToolCall |
| 流式结果 | 不支持 | tool_execution_update |
| 工具阻断 | 不支持 | ✅ 可在 beforeHook 中阻断 |
Pi Agent 的 Hook 示例:
beforeToolCall: async ({ toolCall, args, context }) => {
if (toolCall.name === "bash") {
return { block: true, reason: "bash is disabled" };
}
},
afterToolCall: async ({ result, isError }) => {
return { details: { ...result.details, audited: true } };
}5. OpenClaw 与 nanobot 的深度对比
5.1 架构哲学
| 维度 | nanobot | OpenClaw |
|---|---|---|
| 代码规模 | ~3,000 行(极简) | ~200,000+ 行(生产级) |
| 循环实现 | 自己实现 (_run_agent_loop) | 委托给 Pi Agent (subscribeEmbeddedPiSession) |
| 状态管理 | 显式 messages 数组 | 封装 AgentContext |
| 流式处理 | 简单 callback | Block-level 复杂流式 |
| 上下文压缩 | Token 触发总结 → MEMORY.md | Compaction:智能保留/丢弃消息 |
| 错误恢复 | 简单 retry | Auth profile rotation + failover |
5.2 核心差异详解
差异 1:循环实现位置
nanobot:完全可见的 while 循环
async def _run_agent_loop(...):
while iteration < self.max_iterations:
# 直接可见的循环逻辑
...OpenClaw:封装在 Pi Agent 中
// 通过订阅事件流交互
subscribeEmbeddedPiSession(params, {
onBlockReply: (payload) => { ... },
onReasoningStream: (chunk) => { ... },
onCompaction: (summary) => { ... }
});差异 2:Token/上下文管理
nanobot:简单的 Token 超限检测
if total_tokens > context_window:
await self.memory_consolidator.consolidate() # 总结为 MEMORY.mdOpenClaw:多层次的上下文管理
- Warning threshold:提前预警
- Hard limit:硬性截断
- Compaction:智能选择保留的消息
- Overflow retry:上下文溢出时的重试机制
差异 3:Streaming 架构
nanobot:简单的 progress callback
if on_progress:
await on_progress(thought) # 只通知思考内容OpenClaw:复杂的 Block Streaming
// 支持多种块类型:
- text_delta / text
- tool_use
- thinking(推理内容分离)
- canvas(视觉渲染)
- 代码块感知(避免分割 fenced blocks)5.3 功能特性对比
| 能力 | nanobot | OpenClaw/Pi Agent |
|---|---|---|
| ReAct 基础循环 | ✅ | ✅ |
| Steering(运行中干预) | ❌ | ✅ |
| Follow-up(任务延续) | ❌ | ✅ |
| 并行工具执行 | ❌ | ✅ |
| 工具 Hook 机制 | ❌ | ✅ before/after |
| 自定义消息类型 | ❌ | ✅ 声明式扩展 |
| 流式工具结果 | ❌ | ✅ |
| 模型故障转移 | ❌ | ✅ auth profile rotation |
| 上下文压缩 | 简单总结 | 智能 compaction |
6. 三者关系总结
┌─────────────────────────────────────────────────────────────────┐
│ nanobot │
│ • 极简 Python 实现 │
│ • 教学/研究友好 │
│ • 完全自研 ReAct 循环 │
│ • ~3,000 行代码 │
└─────────────────────────────────────────────────────────────────┘
↓
简化版 ReAct 原理
↓
┌─────────────────────────────────────────────────────────────────┐
│ @mariozechner/pi-* │
│ • 生产级 TypeScript 运行时 │
│ • 事件驱动架构 │
│ • Steering / Follow-up / 并行工具 │
│ • 封装核心循环,通过 EventStream 交互 │
└─────────────────────────────────────────────────────────────────┘
↓
生产级 Agent 运行时
↓
┌─────────────────────────────────────────────────────────────────┐
│ OpenClaw │
│ • 多通道网关(20+ 平台) │
│ • Gateway 控制平面 │
│ • Plugin SDK 扩展系统 │
│ • 在 Pi Agent 上构建工程复杂性 │
└─────────────────────────────────────────────────────────────────┘
一句话总结
nanobot = 教学演示级的 ReAct 实现(简单、透明、易理解) Pi Agent = 生产级的 ReAct 运行时(事件驱动、可扩展、支持复杂交互) OpenClaw = 基于 Pi Agent 构建的多通道 AI 网关(工程化、多平台、企业级)
OpenClaw 选择 Pi Agent 而不是自研循环,是为了获得 steering/follow-up 等高级交互能力,以及并行工具执行和流式事件系统的生产级架构。这种分层设计让 OpenClaw 可以专注于”多通道网关”这一核心定位,而将 Agent 循环的复杂性交给专业的运行时处理。
7. 延伸阅读
本文基于 OpenClaw v2026.3.22、nanobot v0.1.4 和 @mariozechner/pi-agent-core v0.61.1 分析整理。