OpenClaw 架构解析
这篇是给想深入了解 OpenClaw 工作原理的同学看的。不懂代码也没关系,我会用人话解释。
先从整体说起:OpenClaw 是怎么工作的?
一句话解释
OpenClaw = 消息搬运工 + AI 大脑
它的工作流程很简单:
你发消息 → OpenClaw 收到 → 交给 AI 思考 → 把 AI 的回复发回给你
形象比喻:餐厅点餐
想象你去餐厅吃饭:
| 角色 | 对应 OpenClaw | 餐厅比喻 |
|---|---|---|
| Channel | 微信/Telegram | 服务员 |
| Gateway | 消息路由器 | 前台 |
| Pi Agent | AI 大脑 | 厨师 |
| Memory | 记忆系统 | 服务员的记事本 |
| Tool | 工具 | 厨房设备 |
点餐流程:
- 你跟服务员说”来份宫保鸡丁”
- 服务员记下来,送到前台
- 前台把单子传给厨师
- 厨师做好了,端出来
- 服务员把菜送到你桌上
OpenClaw 的流程:
- 你在 Telegram 发消息”帮我查下天气”
- Channel(适配器)把消息收进来
- Gateway(网关)统一处理,查询记忆
- Pi Agent(AI)处理请求,决定回复什么
- Tool Executor(工具)可能需要调用工具
- 格式化输出,原路返回给你
架构图解
分层架构
┌─────────────────────────────────────────────────────────┐
│ 渠道层 (Channel Layer) │
│ Discord 适配器 │ Telegram 适配器 │ 微信适配器 │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 网关层 (Gateway Layer) │
│ 消息路由 │ 会话管理 │ 记忆注入 │ 流量控制 │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 运行时层 (Runtime Layer) │
│ Pi Agent SDK │ 工具执行器 │ 记忆管理器 │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 模型层 (Model Layer) │
│ 多模型路由器 │ API 适配器 │
└─────────────────────────────────────────────────────────┘
数据流
用户发消息
│
▼
┌──────────────────────────────────────────┐
│ Channel Adapter(渠道适配器) │
│ 把各平台的"方言"翻译成统一格式 │
└─────────────────┬──────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Gateway(网关) │
│ 1. 鉴权(是不是合法用户) │
│ 2. 查询记忆(AI 认识这个人吗) │
│ 3. 路由到对应的 Agent │
└─────────────────┬──────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Pi Agent(AI 大脑) │
│ 1. 构建上下文(系统提示 + 记忆 + 消息)│
│ 2. 调用 LLM(GPT/Claude) │
│ 3. 决定是否需要调用工具 │
└─────────────────┬──────────────────────┘
│
▼
┌───────┴───────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 直接回复 │ │ 调用工具 │
│ (聊天) │ │ (查天气等)│
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 格式化输出 │ │ 执行工具 │
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬─────────┘
│
▼
┌──────────────────────────────────────────┐
│ 返回给用户 │
└──────────────────────────────────────────┘
核心组件详解
1. Channel(渠道适配器)
作用:把各平台的”方言”翻译成 OpenClaw 统一能理解的语言。
举个例子:
- Telegram 说”有个用户发了消息,内容是 xxx”
- Discord 说”频道 123 里有个叫 John 的发了 xxx”
- 微信说”有人@你了,消息内容是 xxx”
Channel 适配器把这些都转成:
{
"platform": "telegram",
"user_id": "123456",
"chat_id": "789012",
"content": "xxx"
}支持的平台适配器:
- TelegramAdapter - 电报
- DiscordAdapter - DC
- WhatsAppAdapter - WA
- SlackAdapter - Slack
- MatrixAdapter - Matrix
- 等等……
2. Gateway(网关)
作用:中央枢纽,所有消息都要经过这里。
核心职责:
| 职责 | 说明 |
|---|---|
| 协议转换 | 把各平台的消息格式统一 |
| 消息路由 | 决定消息去哪个 Agent |
| 会话管理 | 维护每个用户的对话状态 |
| 记忆注入 | 把相关记忆塞到上下文里 |
| 流量控制 | 限流、并发控制、防滥用 |
工作原理(伪代码):
async def handle_message(message):
# 1. 验证用户是否合法
if not is_allowed_user(message.user_id):
return "你没有权限使用这个 Bot"
# 2. 获取或创建会话
session = await get_or_create_session(message)
# 3. 检索相关记忆
memories = await memory_manager.retrieve(
query=message.content,
user_id=message.user_id
)
# 4. 构建上下文
context = {
"session": session,
"memories": memories,
"system_prompt": system_config.prompt
}
# 5. 扔给 AI 处理
response = await pi_agent.process(context)
# 6. 保存新记忆
await memory_manager.store(session, response)
# 7. 发回去
return response3. Pi Agent(AI 大脑)
作用:真正”思考”的地方。
Pi Agent 拿到上下文后,做这些事:
- 构建提示词:把系统提示 + 记忆 + 用户消息组合起来
- 调用 LLM:发送给 GPT/Claude
- 解析响应:看 AI 说啥,要不要调用工具
- 执行工具:如果需要,就调用相应工具
- 返回结果:把最终结果返回
为什么叫 Pi?
- π 是数学里的无限不循环小数
- 暗示这个框架简单到极致,但又功能无限
4. Tool Executor(工具执行器)
作用:执行各种工具,比如查天气、搜网页、读写文件。
安全设计:
- 危险操作(如删除文件)会警告
- 可以配置白名单/黑名单
- 敏感操作需要二次确认
工作流程:
AI 说:"我需要查下北京的天气"
│
▼
Tool Executor 收到工具调用请求
│
├─── 权限检查(这个工具被允许吗?)
│
├─── 参数验证(参数对不对?)
│
├─── 执行(真的去查天气 API)
│
└─── 返回结果给 AI
5. Memory Manager(记忆管理器)
作用:管理 AI 的”记忆”。
三层记忆:
| 层次 | 存储位置 | 生命周期 | 用途 |
|---|---|---|---|
| Working Memory | 内存 | 当前会话 | 正在处理的信息 |
| Short Term | 文件 | 几天 | 最近的对话 |
| Long Term | 文件 | 永久 | 重要的事实、偏好 |
检索流程:
用户问:"我上次买的那个包怎么样了?"
│
▼
检索记忆
│
├─── 长期记忆:搜"购买"、"包"、"订单"
│
├─── 短期记忆:搜最近的对话
│
└─── 工作记忆:当前会话的内容
│
▼
匹配度排序
│
▼
返回最相关的几条记忆
│
▼
塞到 AI 的上下文里
为什么这样设计?
1. 为什么要 Channel 适配器?
因为每个平台的消息格式都不一样:
- Telegram 用 Markdown
- Discord 用 Embed
- Slack 用 Block Kit
适配器模式让核心代码不用管这些差异,新增平台只要写新的适配器就行。
2. 为什么要 Gateway?
想象没有 Gateway 的情况:
- Telegram 用户 A 跟 Bot 说话
- Discord 用户 B 跟同一个 Bot 说话
- Bot 怎么知道哪个回复该发到哪个平台?
Gateway 就是干这个的——统一入口,统一路由。
3. 为什么要 Pi 这么”简”?
很多 AI Agent 框架给你 100 个工具,结果:
- 学起来累
- 维护成本高
- 容易出 bug
Pi 只给你 4 个核心工具(read/write/edit/bash),但通过组合,可以完成几乎所有任务。
就像乐高积木,给你的零件越少,发挥空间越大。
4. 为什么要记忆分层?
因为:
- 不是所有记忆都一样重要
- 不是所有记忆都需要永久保存
- 查询性能很重要
分层设计让系统更高效。
消息流转示例
场景:用户问天气
1. 用户在 Telegram 发消息:
"北京今天天气怎么样?"
2. TelegramAdapter 收到:
{
"platform": "telegram",
"user_id": "123456",
"chat_id": "789012",
"content": "北京今天天气怎么样?",
"timestamp": "2026-04-24T10:30:00Z"
}3. Gateway 处理:
- 检查用户 ID 123456 在白名单里吗? ✅
- 查询记忆,想起”用户在北京工作”
- 构建上下文
4. Pi Agent 处理:
- 构建提示词……
- 调用 Claude API
- Claude 回复:“需要查下天气” + 调用 weather 工具
5. Tool Executor 执行:
- 调用天气 API
- 收到:北京今天 22°C,晴
6. 返回结果:
🌤️ 北京今天天气:
温度:22°C
天气:晴
空气:良
建议:适合外出,记得防晒!
7. 消息通过 TelegramAdapter 发回给用户
整个过程可能只需要 2-3 秒。
扩展机制
插件怎么接入?
插件 ──→ 工具注册 ──→ Gateway 知道有这个工具
│
└──→ 事件订阅 ──→ Gateway 调用钩子函数
比如你写了一个”翻译插件”:
- 在
get_tools()里注册translate工具 - 在
get_event_handlers()里订阅on_message_received - Gateway 就会在收到消息时调用你的插件
多模型路由
OpenClaw 可以同时配置多个 AI 提供商:
llm:
default: "anthropic" # 默认用 Claude
providers:
anthropic:
model: "claude-sonnet-4-20250514"
openai:
model: "gpt-4-turbo"
groq:
model: "llama-3.3-70b-versatile"路由策略:
- 按任务类型:代码 → OpenAI,分析 → Anthropic
- 按负载:哪个 API 响应快用哪个
- 手动指定:用户指定用哪个
性能优化点
1. 上下文压缩
如果对话太长,OpenClaw 会:
- 自动总结早期对话
- 删除不重要的消息
- 保持总 token 在限制内
2. 缓存
- LLM 响应缓存:同样的问题不用重复调用
- 记忆向量缓存:不用每次都算 embedding
- 工具结果缓存:同样的 API 调用结果复用
3. 并发控制
- 单用户限流:一秒最多处理 N 条消息
- 全局限流:防止 API 超额
- 队列:消息太多就排队
下一步
搞懂了架构?继续学习:
| 教程 | 内容 |
|---|---|
| Pi_Framework深度解析 | Pi 的设计哲学和实现细节 |
| OpenClaw记忆系统 | 记忆是怎么存储和检索的 |
| OpenClaw插件开发 | 自己写插件扩展功能 |
| OpenClaw高级用法 | 高级技巧和工作流 |
文档状态:架构解析
更新时间:2026年4月