# 给龙虾做了个 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 (移动端) |

---

## 二、核心架构全景

![图表1](https://cdn.union.jxyunge.com/self-media/002/arch-01.png)

---

## 三、六大核心子系统详解

### 3.1 Gateway（通信网关）

Gateway 是整个系统的**中枢神经**，负责接收所有外部连接、认证设备、路由消息。

![图表2](https://cdn.union.jxyunge.com/self-media/002/arch-02.png)

**核心文件：**

| 文件 | 职责 |
|------|------|
| `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 启动序列：**

![图表3](https://cdn.union.jxyunge.com/self-media/002/arch-03.png)

**协议帧类型：**

| 帧类型 | 方向 | 用途 |
|--------|------|------|
| `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 运行时之间的翻译层。

![图表4](https://cdn.union.jxyunge.com/self-media/002/arch-04.png)

**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 调度。

![图表5](https://cdn.union.jxyunge.com/self-media/002/arch-05.png)

**支持的 LLM 提供商（10+）：**

| 提供商 | 说明 |
|--------|------|
| Anthropic | Claude Opus / Sonnet / Haiku |
| OpenAI | GPT 系列 |
| Google | Gemini 系列 |
| Qwen | 通义千问（阿里） |
| Minimax | 国产大模型 |
| Ollama | 本地部署任意开源模型 |
| Groq | 高速推理 |
| Grok | xAI |
| Azure | Azure OpenAI Service |
| Volc | 火山引擎（字节） |

**模型降级链（Fallback Chains）：** 当主模型不可用时，自动切换到备用模型，保证服务连续性。

**工具审批机制：**

![图表6](https://cdn.union.jxyunge.com/self-media/002/arch-06.png)

---

### 3.4 Plugin System（插件系统）

插件系统是 OpenClaw 可扩展性的核心——所有通道集成、记忆后端、诊断工具都以插件形式存在。

![图表7](https://cdn.union.jxyunge.com/self-media/002/arch-07.png)

**已包含的 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：**

```typescript
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 长期记忆的基础。

![图表8](https://cdn.union.jxyunge.com/self-media/002/arch-08.png)

**MemoryIndexManager 是单例模式**，每个 Agent + Workspace 一个实例：

```typescript
// 获取或创建记忆管理器
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 **主动醒来执行任务**，而不是被动等待指令。

![图表9](https://cdn.union.jxyunge.com/self-media/002/arch-09.png)

**HEARTBEAT.md 示例：**

```markdown
## 每日任务

- 每天早上 9:00 检查未读邮件，分类后发送摘要到 Slack #daily
- 监控竞品价格变动，降幅超过 10% 立即通知
- 每周五下午生成本周工作总结

## 触发条件

- 仅在工作日执行
- 静默模式：无变化时不发送消息
```

**可见性控制：**

| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| `heartbeat.every` | 心跳间隔 | 30m |
| `heartbeat.enabled` | 是否启用 | true |
| `heartbeat.ackMaxChars` | ACK 最大字符数 | 300 |
| `SILENT_REPLY_TOKEN` | 静默回复标记 | #SILENT_ACK |
| `HEARTBEAT_OK` | 无需操作标记 | HEARTBEAT_OK |

---

## 四、数据流全链路

一条消息从外部平台进入到最终响应，经过的完整链路：

![图表10](https://cdn.union.jxyunge.com/self-media/002/arch-10.png)

---

## 五、持久化与存储架构

![图表11](https://cdn.union.jxyunge.com/self-media/002/arch-11.png)

**会话存储细节：**

| 存储项 | 格式 | 说明 |
|--------|------|------|
| 会话元数据 | JSON | 模型、Token 用量、思考级别等 |
| 会话转录 | JSONL (追加写入) | 不可变的消息日志，按大小/数量自动轮转 |
| 记忆索引 | SQLite | 向量表 + FTS 表 + 缓存表 |
| 设备身份 | JSON | Ed25519 公私钥对 |
| 配置 | JSON | 全局配置，含 Secret 引用 |

**Secrets 引用机制：**

```json
{
  "providers": {
    "anthropic": {
      "apiKey": "${file://~/.openclaw/secrets/anthropic.key}"
    }
  }
}
```

支持 `${file://path}` 和 `${env://VAR_NAME}` 两种引用方式。

---

## 六、安全架构

![图表12](https://cdn.union.jxyunge.com/self-media/002/arch-12.png)

**操作域（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` — 审计日志记录器
- 临时路径防护、外部内容策略

---

## 七、通道集成架构

![图表13](https://cdn.union.jxyunge.com/self-media/002/arch-13.png)

**通道插件必须实现的接口：**

```typescript
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 部署架构

![图表14](https://cdn.union.jxyunge.com/self-media/002/arch-14.png)

### 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 架构模式

![图表15](https://cdn.union.jxyunge.com/self-media/002/arch-15.png)

### 9.2 核心设计决策

| 决策 | 选择 | 理由 |
|------|------|------|
| 协议 | WebSocket + 自定义协议 | 双向实时通信，低延迟 |
| 存储 | 文件系统 + SQLite | 零外部依赖，本地优先 |
| 插件加载 | jiti 动态导入 | 支持 TypeScript 直接加载，无需预编译 |
| 并发控制 | Actor 队列 | 避免锁竞争，每会话串行保证一致性 |
| 记忆检索 | 向量 + BM25 混合 | 语义理解 + 精确匹配，互补短板 |
| 安全模型 | 设备身份 + Scopes | 零信任架构，最小权限原则 |
| 心跳 | 文件驱动 (HEARTBEAT.md) | 无需额外调度基础设施，用户可直接编辑 |

### 9.3 值得关注的工程亮点

1. **协议翻译器模式（ACP Translator）**：将外部标准协议与内部网关协议解耦，允许独立演进
2. **运行时缓存 + 空闲驱逐**：会话不用时自动回收资源，用时自动恢复
3. **Secret 引用而非内联**：配置文件中不存储明文密钥，而是引用外部文件或环境变量
4. **会话转录追加写入**：不可变日志，天然支持故障恢复和审计
5. **嵌入提供商可替换**：同一套记忆系统可无缝切换 OpenAI、Gemini、本地 Ollama 等后端

---

## 十、架构风险与局限

| 风险点 | 说明 | 影响 |
|--------|------|------|
| **明文 Markdown 存储** | HEARTBEAT.md、MEMORY.md 等以明文存储 | API Key 泄露风险 |
| **Root 级终端权限** | `system.run` 工具可执行任意命令 | 需依赖审批机制，但默认可绕过 |
| **心跳无人值守** | Agent 可在用户不知情时自主行动 | MoltMatch 等事件的根因 |
| **第三方 Skill 生态** | ClawHub 26% 插件含漏洞/恶意代码 | 供应链攻击面 |
| **单体网关** | Gateway 是单点，承载所有通道 | 高可用需额外架构 |
| **文件系统依赖** | 会话存储依赖本地文件系统 | 不原生支持分布式部署 |

---

> **总结**：OpenClaw 的架构本质上是一个**面向消息的分布式系统**——Gateway 是交换机，Agent 是 LLM 驱动的任务执行器，Channel 是双向传输管道。记忆、安全和可扩展性是一等公民，而非事后补丁。但其"本地优先"的设计哲学也带来了明文存储和单点依赖的固有风险。
