- 新增 15 个 Mermaid 架构图解文件,涵盖系统核心组件 - 添加系统架构全景图,展示外部消息平台到 LLM 提供商的完整流程 - 新增网关层、通道管理、路由层、ACP 协议层、Agent 运行时等模块架构图 - 添加记忆系统、心跳系统、插件系统、安全架构等专项设计图 - 新增消息流转序列图和启动流程图 - 添加容器化部署架构和数据存储结构图 - 配置 Mermaid 图表样式,统一科技感视觉主题 - 添加完整的系统设计模式思维导图 - 新增 456 行深度架构分析文章,覆盖六大核心子系统
15 KiB
给龙虾做了个 CT:43 万行代码的 OpenClaw 架构全拆解
分析日期:2026-03-11 源码版本:基于 GitHub 最新主分支 分析工具:Claude Opus 4.6 代码规模:约 43 万行 TypeScript,monorepo 架构
一、项目总览
OpenClaw 是一个多通道 AI 智能体网关系统——它不是一个简单的聊天机器人框架,而是一个完整的「AI 员工」运行时平台。其核心能力是:让大语言模型通过多种消息渠道(Slack、Telegram、Discord、WhatsApp 等 30+ 平台)接收指令、自主执行任务、并将结果回传。
1.1 Monorepo 结构
openclaw/
├── src/ # 核心运行时源码(主体)
│ ├── gateway/ # WebSocket 网关服务器
│ ├── acp/ # Agent Client Protocol 协议层
│ ├── agents/ # Agent 运行时、模型集成、工具系统
│ ├── memory/ # 向量检索 + 全文搜索记忆系统
│ ├── plugins/ # 插件加载、注册、Hook 执行
│ ├── channels/ # 通道管理器
│ ├── routing/ # 消息路由与会话键解析
│ ├── auto-reply/ # 心跳机制与自动回复
│ ├── config/ # 配置加载与会话持久化
│ ├── security/ # 安全审计与策略执行
│ ├── infra/ # 基础设施(设备身份、TLS、投递)
│ ├── cli/ # CLI 命令行界面
│ ├── web/ # Web/WhatsApp Webhook 处理
│ ├── terminal/ # 终端 TUI 组件
│ └── media-understanding/# 多媒体理解(图片/音频)
├── extensions/ # 34 个通道/功能插件
├── packages/ # 兼容包(clawdbot、moltbot 旧名)
├── apps/ # 原生客户端(macOS/iOS/Android)
├── ui/ # React Web 管理界面
├── skills/ # 内置技能
├── docs/ # 文档
├── test/ # 测试套件
└── vendor/ # 第三方依赖(a2ui 等)
1.2 技术栈
| 层面 | 技术选型 |
|---|---|
| 语言 | TypeScript (ESM),Node.js 22+ |
| 构建 | tsdown (基于 Rolldown) + Vite (UI) |
| 包管理 | pnpm workspace (monorepo) |
| 协议 | WebSocket + ACP (Agent Client Protocol) |
| 存储 | SQLite (sqlite-vec + FTS5) + JSON 文件 |
| 验证 | AJV Schema Validation |
| 测试 | Vitest + V8 Coverage |
| 容器 | Docker / Podman 多阶段构建 |
| 桌面 | SwiftUI (macOS) / React Native (移动端) |
二、核心架构全景
三、六大核心子系统详解
3.1 Gateway(通信网关)
Gateway 是整个系统的中枢神经,负责接收所有外部连接、认证设备、路由消息。
核心文件:
| 文件 | 职责 |
|---|---|
src/gateway/server.impl.ts |
网关启动入口 startGatewayServer() |
src/gateway/client.ts |
WebSocket 客户端,含重连与退避策略 |
src/gateway/server-chat.ts |
聊天消息处理器 |
src/gateway/protocol/index.ts |
协议帧定义与 AJV 校验 |
src/gateway/auth.ts |
认证中间件 |
src/gateway/auth-rate-limit.ts |
速率限制策略 |
src/gateway/server-channels.ts |
通道生命周期管理 |
Gateway 启动序列:
协议帧类型:
| 帧类型 | 方向 | 用途 |
|---|---|---|
RequestFrame |
Client → Server | chat.send, config.get, sessions.list 等 |
ResponseFrame |
Server → Client | 请求响应数据 |
EventFrame |
Server → Client | agent_message, tool_call, usage_update 等 |
HelloOk |
Server → Client | 握手响应,含协议版本和能力声明 |
安全特性:
- CWE-319 防护:
isSecureWebSocketUrl()禁止非回环地址使用明文ws:// - 设备身份:Ed25519 密钥对存储于
~/.openclaw/credentials/ - TLS 指纹:支持证书指纹验证(Certificate Pinning)
- 连接序列号:检测消息间隙,防止重放攻击
3.2 ACP(Agent Client Protocol 协议层)
ACP 是 OpenClaw 定义的标准化 Agent 通信协议,作为 Gateway 与 Agent 运行时之间的翻译层。
AcpGatewayAgent 核心职责:
- 翻译 ACP 协议 ↔ Gateway 协议
- 管理会话生命周期(initialize → prompt → response)
- 速率限制(默认 120 请求 / 10 秒窗口)
- 追踪待处理的 prompt 和 tool call
AcpSessionManager 核心职责:
- 所有 ACP 运行时会话的单例管理器
- 运行时缓存(空闲 TTL 驱逐)
- 活跃回合与延迟统计
- Actor 队列:防止对同一会话的并发写入
会话键格式:
@main → 默认主会话
@jane → 名为 "jane" 的 Agent 会话
$subagent-id:child-key → 子 Agent 会话
thread:123 → 线程绑定会话
acp:uuid → ACP/IDE 会话
3.3 Agent Runtime(Agent 运行时)
Agent 运行时是系统的大脑,负责 LLM 推理、工具调用、子 Agent 调度。
支持的 LLM 提供商(10+):
| 提供商 | 说明 |
|---|---|
| Anthropic | Claude Opus / Sonnet / Haiku |
| OpenAI | GPT 系列 |
| Gemini 系列 | |
| Qwen | 通义千问(阿里) |
| Minimax | 国产大模型 |
| Ollama | 本地部署任意开源模型 |
| Groq | 高速推理 |
| Grok | xAI |
| Azure | Azure OpenAI Service |
| Volc | 火山引擎(字节) |
模型降级链(Fallback Chains): 当主模型不可用时,自动切换到备用模型,保证服务连续性。
工具审批机制:
3.4 Plugin System(插件系统)
插件系统是 OpenClaw 可扩展性的核心——所有通道集成、记忆后端、诊断工具都以插件形式存在。
已包含的 34 个通道插件:
| 类别 | 插件 |
|---|---|
| 即时通讯 | Telegram, WhatsApp, Signal, iMessage, Line, Zalo |
| 团队协作 | Slack, Discord, MS Teams, Mattermost, Google Chat, 飞书 |
| 社交/社区 | Matrix, IRC, Nostr, Twitch, Tlon |
| 企业通讯 | Synology Chat, Nextcloud Talk, BlueBubbles |
| 语音 | voice-call |
| 开发/集成 | acpx, copilot-proxy, lobster |
Plugin Runtime API:
PluginRuntime = {
subagent: {
run(), // 运行子 Agent
waitForRun(), // 等待运行完成
getSessionMessages(),
deleteSession()
},
channel: {
list(), // 列出通道
inspect(), // 检查通道状态
sendMessage() // 发送消息
},
core: {
config, // 全局配置
workspaceDir, // 工作区目录
agentId // 当前 Agent ID
}
}
Hook 系统:
| Hook | 触发时机 |
|---|---|
gateway.startup() |
网关启动时 |
gateway.shutdown() |
优雅关闭时 |
channel.ready() |
通道连接就绪 |
channel.message() |
收到消息时 |
session.start() |
会话开始 |
session.prompt() |
LLM 推理前 |
session.response() |
LLM 响应后 |
3.5 Memory System(记忆系统)
记忆系统实现了向量检索 + BM25 全文搜索的混合搜索架构,是 Agent 长期记忆的基础。
MemoryIndexManager 是单例模式,每个 Agent + Workspace 一个实例:
// 获取或创建记忆管理器
const memory = await MemoryIndexManager.get({
cfg: config,
agentId: "main",
purpose: "chat"
});
// 混合搜索
const results = await memory.search({
query: "用户上周提到的跑步习惯",
limit: 10,
threshold: 0.7,
hybrid: { weight: 0.6 } // 向量权重 60%, BM25 权重 40%
});
关键特性:
- 时间衰减:近期记忆权重更高
- 批量嵌入:失败自动恢复
- 查询缓存:TTL 控制的 embedding 缓存层
- 额外记忆路径:可引入外部文档目录
3.6 Heartbeat(心跳机制)
心跳是 OpenClaw 最具争议也最核心的设计——让 AI 主动醒来执行任务,而不是被动等待指令。
HEARTBEAT.md 示例:
## 每日任务
- 每天早上 9:00 检查未读邮件,分类后发送摘要到 Slack #daily
- 监控竞品价格变动,降幅超过 10% 立即通知
- 每周五下午生成本周工作总结
## 触发条件
- 仅在工作日执行
- 静默模式:无变化时不发送消息
可见性控制:
| 配置项 | 说明 | 默认值 |
|---|---|---|
heartbeat.every |
心跳间隔 | 30m |
heartbeat.enabled |
是否启用 | true |
heartbeat.ackMaxChars |
ACK 最大字符数 | 300 |
SILENT_REPLY_TOKEN |
静默回复标记 | #SILENT_ACK |
HEARTBEAT_OK |
无需操作标记 | HEARTBEAT_OK |
四、数据流全链路
一条消息从外部平台进入到最终响应,经过的完整链路:
五、持久化与存储架构
会话存储细节:
| 存储项 | 格式 | 说明 |
|---|---|---|
| 会话元数据 | JSON | 模型、Token 用量、思考级别等 |
| 会话转录 | JSONL (追加写入) | 不可变的消息日志,按大小/数量自动轮转 |
| 记忆索引 | SQLite | 向量表 + FTS 表 + 缓存表 |
| 设备身份 | JSON | Ed25519 公私钥对 |
| 配置 | JSON | 全局配置,含 Secret 引用 |
Secrets 引用机制:
{
"providers": {
"anthropic": {
"apiKey": "${file://~/.openclaw/secrets/anthropic.key}"
}
}
}
支持 ${file://path} 和 ${env://VAR_NAME} 两种引用方式。
六、安全架构
操作域(Scopes)细粒度控制:
| Scope | 权限 |
|---|---|
gateway:full |
网关完全控制 |
gateway:read |
只读访问 |
channels:read |
读取通道信息 |
messages:send |
发送消息 |
config:write |
修改配置 |
agents:manage |
Agent 管理 |
沙箱策略:
| 策略 | 说明 |
|---|---|
inherit |
继承父会话沙箱模式 |
require |
强制更严格的沙箱 |
forbidden |
禁止子 Agent 派生 |
安全审计(src/security/):
dangerous-tools.ts— 危险工具扫描器dangerous-config-flags.ts— 危险配置标记检测audit.ts— 审计日志记录器- 临时路径防护、外部内容策略
七、通道集成架构
通道插件必须实现的接口:
interface ChannelPlugin {
// 配置 Schema 定义
configSchema: JSONSchema;
// 生命周期
initialize(config: ChannelConfig): Promise<void>;
shutdown(): Promise<void>;
// 消息处理
onMessage(handler: MessageHandler): void;
sendMessage(target: Target, message: Message): Promise<void>;
// 状态
getStatus(): ChannelStatus;
getAccounts(): AccountInfo[];
}
消息标准化: 所有通道的消息都会被标准化为统一格式,包括:
- 文本内容
- 附件(图片/文件/音频)
- 发送者身份
- 线程/回复关系
- 通道特定元数据
八、构建与部署
8.1 Docker 部署架构
8.2 发布通道
| 通道 | 版本格式 | npm dist-tag |
|---|---|---|
| Stable | vYYYY.M.D | latest |
| Beta | vYYYY.M.D-beta.N | beta |
| Dev | main 分支 | 无 tag |
8.3 客户端矩阵
| 平台 | 技术栈 | 位置 |
|---|---|---|
| CLI | Commander.js + Clack | src/cli/ |
| Web UI | React + Vite | ui/ |
| macOS | SwiftUI + XPC Bridge | apps/macos/ |
| iOS | React Native | apps/ios/ |
| Android | React Native | apps/android/ |
九、关键设计模式总结
9.1 架构模式
9.2 核心设计决策
| 决策 | 选择 | 理由 |
|---|---|---|
| 协议 | WebSocket + 自定义协议 | 双向实时通信,低延迟 |
| 存储 | 文件系统 + SQLite | 零外部依赖,本地优先 |
| 插件加载 | jiti 动态导入 | 支持 TypeScript 直接加载,无需预编译 |
| 并发控制 | Actor 队列 | 避免锁竞争,每会话串行保证一致性 |
| 记忆检索 | 向量 + BM25 混合 | 语义理解 + 精确匹配,互补短板 |
| 安全模型 | 设备身份 + Scopes | 零信任架构,最小权限原则 |
| 心跳 | 文件驱动 (HEARTBEAT.md) | 无需额外调度基础设施,用户可直接编辑 |
9.3 值得关注的工程亮点
- 协议翻译器模式(ACP Translator):将外部标准协议与内部网关协议解耦,允许独立演进
- 运行时缓存 + 空闲驱逐:会话不用时自动回收资源,用时自动恢复
- Secret 引用而非内联:配置文件中不存储明文密钥,而是引用外部文件或环境变量
- 会话转录追加写入:不可变日志,天然支持故障恢复和审计
- 嵌入提供商可替换:同一套记忆系统可无缝切换 OpenAI、Gemini、本地 Ollama 等后端
十、架构风险与局限
| 风险点 | 说明 | 影响 |
|---|---|---|
| 明文 Markdown 存储 | HEARTBEAT.md、MEMORY.md 等以明文存储 | API Key 泄露风险 |
| Root 级终端权限 | system.run 工具可执行任意命令 |
需依赖审批机制,但默认可绕过 |
| 心跳无人值守 | Agent 可在用户不知情时自主行动 | MoltMatch 等事件的根因 |
| 第三方 Skill 生态 | ClawHub 26% 插件含漏洞/恶意代码 | 供应链攻击面 |
| 单体网关 | Gateway 是单点,承载所有通道 | 高可用需额外架构 |
| 文件系统依赖 | 会话存储依赖本地文件系统 | 不原生支持分布式部署 |
总结:OpenClaw 的架构本质上是一个面向消息的分布式系统——Gateway 是交换机,Agent 是 LLM 驱动的任务执行器,Channel 是双向传输管道。记忆、安全和可扩展性是一等公民,而非事后补丁。但其"本地优先"的设计哲学也带来了明文存储和单点依赖的固有风险。














