OpenClaw技术架构深度解析:从三层设计到插件系统的全面解读

引言

在短短两个月内,OpenClaw从一个周末WhatsApp脚本发展成GitHub历史上增长最快的开源项目之一,在2026年2月初就突破了18万颗星。这种爆发式增长并非偶然——其核心在于产品化的成功。

OpenClaw将”聊天机器人”转变为”可以实际执行任务的AI代理”,一个运行在你自己硬件上的持久化助手,通过你已使用的消息应用和接口进行访问。

Andrej Karpathy称其为”我所见过的最令人难以置信的科幻起飞级别的产品。”

今天,我们将深入解析OpenClaw的技术架构,了解它如何通过精妙的设计实现这一革命性的AI代理平台。

一、整体架构:三层设计哲学

OpenClaw采用清晰的三层架构,每一层管理自己的关注点:

1. Gateway层(会话管理中心)

  • 管理用户会话的完整生命周期
  • 消息排队和调度(优先级控制)
  • 认证和权限控制
  • WebSocket持久连接维护

2. Channel层(平台适配器)

  • 适配不同平台的消息格式(WhatsApp和Telegram格式完全不同)
  • 消息路由规则(私信或群组,是否需要@触发)
  • 事件处理(接收消息、发送消息、错误处理)

3. LLM层(模型接口)

  • 统一的Provider接口(使用Claude或GPT调用方式一致)
  • 工具调用(Function Calling)
  • 流式响应处理
  • MCP服务器集成

架构演变:2026年重构

在2026年,OpenClaw进行了一次重大重构:LLM层从硬编码改为Provider插件系统,支持动态注册Anthropic、OpenAI、本地模型等。这次重构使核心包大小缩减到约8MB。

这种插件优先设计让核心保持轻量,同时支持无限扩展。

二、Gateway层:控制平面核心

Gateway是OpenClaw系统的单一事实来源,运行在Node.js 22或更高版本上。它不仅仅是路由器,而是整个OpenClaw系统的控制中心。

会话生命周期管理

每个用户都有独立的Session,存储内容包括:

  • conversationHistory - 对话历史(最近N条消息)
  • context - 上下文变量(用户设置、临时数据)
  • state - 当前状态(空闲、处理中、等待)
  • channelInfo - 来源平台信息

关键设计:per-channel-peer隔离模式

同一用户在WhatsApp和Telegram上有两个独立的Session,互不影响。这设计防止了上下文混淆——你在WhatsApp上讨论技术问题,在Telegram上询问天气,两个不会交叉污染。

消息调度策略

Gateway不会收到消息后立即处理,而是使用调度队列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 消息队列核心逻辑
class MessageQueue {
async enqueue(session, message) {
// 检查并发限制
if (this.activeJobs >= this.maxConcurrency) {
this.waitingQueue.push({ session, message });
return;
}

// 执行处理
this.activeJobs++;
try {
await this.process(session, message);
} catch (error) {
// 重试逻辑:1秒、2秒、4秒指数退避
await this.retryWithBackoff(session, message);
} finally {
this.activeJobs--;
this.processNext();
}
}
}

这种设计解决了两个问题:

  1. 并发控制 - 避免同时向LLM发起太多请求导致API限流
  2. 错误重试 - LLM调用失败时自动重试3次,避免瞬态故障导致消息丢失

WebSocket连接管理

对于需要高实时性的应用(如客服机器人),WebSocket连接管理是关键:

  • 心跳检测 - 每30秒发送ping,超时则认为连接死亡
  • 自动重连 - 断开后指数退避重连(1秒、2秒、4秒…最大30秒)
  • 状态同步 - 重连后自动恢复Session状态

三、Channel层:多平台消息路由

Channel层解决了核心问题:不同平台的消息格式完全不同,如何统一处理?

适配器模式的魔力

不同平台的消息格式差异巨大:

WhatsApp格式:

1
2
3
4
5
{
"from": "1234567890",
"body": "Hello",
"type": "text"
}

Telegram格式:

1
2
3
4
5
6
{
"message": {
"chat": {"id": 123},
"text": "Hello"
}
}

OpenClaw使用经典的适配器模式:定义标准化的Message接口,每个Channel负责将平台消息转换为这个格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 标准化消息格式
interface StandardMessage {
userId: string; // 统一用户ID
content: string; // 消息内容
timestamp: number; // 时间戳
metadata: any; // 平台特定数据
}

// WhatsApp适配器
class WhatsAppChannel implements Channel {
adaptMessage(rawMessage): StandardMessage {
return {
userId: rawMessage.from,
content: rawMessage.body,
timestamp: Date.now(),
metadata: { platform: 'whatsapp' }
};
}
}

路由规则实现

Channel层的另一个重要职责:决定哪些消息应该响应,哪些应该忽略。

OpenClaw支持两种路由策略:

1. dmPolicy(私信策略)

  • pairing - 需要先配对才能聊天(最安全)
  • allowlist - 只有白名单用户可以使用
  • open - 所有人都可以使用(公开机器人)
  • disabled - 禁用私信

2. mentionGating(群组@触发)
只在群组中@提及时响应,避免垃圾消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TelegramChannel {
shouldRespond(message): boolean {
// 私信直接响应
if (message.chat.type === 'private') {
return this.checkDmPolicy(message.from.id);
}

// 群组检查@
if (message.chat.type === 'group') {
const mentioned = message.entities?.some(
e => e.type === 'mention' && e.user.id === this.botId
);
return mentioned;
}

return false;
}
}

四、LLM层:可插拔的Provider系统

LLM层在2026年经历了重大重构,从硬编码转换为插件系统。

Provider插件系统

旧设计(硬编码):

1
2
3
4
5
if (config.provider === 'anthropic') {
return new AnthropicClient();
} else if (config.provider === 'openai') {
return new OpenAIClient();
}

问题:每次添加新模型都需要修改if-else,代码越来越臃肿。

新设计(插件接口):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Provider接口定义
interface LLMProvider {
name: string; // 'anthropic', 'openai', 'ollama'

// 发送消息,返回流式响应
chat(messages: Message[], options: ChatOptions): AsyncIterator<string>;

// 工具调用支持
supportTools(): boolean;

// 初始化配置
initialize(config: ProviderConfig): void;
}

// 插件注册机制
class ProviderRegistry {
private providers = new Map<string, LLMProvider>();

register(provider: LLMProvider) {
this.providers.set(provider.name, provider);
}

get(name: string): LLMProvider {
return this.providers.get(name);
}
}

// 自动发现和注册
const registry = new ProviderRegistry();
registry.register(new AnthropicProvider());
registry.register(new OpenAIProvider());
registry.register(new OllamaProvider());

主流Provider的差异

虽然接口统一,但不同Provider的实现细节差异很大:

Anthropic Provider(Claude)

  • 原生支持流式响应(stream: true)
  • 特殊的Tool Use格式(需要包装在tools数组中)
  • 大上下文窗口(Claude 3.5可处理20万tokens)

OpenAI Provider(ChatGPT)

  • Function Calling和Tool Use是两个独立的API(旧版用functions,新版用tools)
  • 流式响应返回delta片段,需要手动拼接
  • 严格的速率限制(需要同时控制RPM/TPM)

Ollama Provider(本地模型)

  • 无API密钥,直接HTTP调用本地服务
  • 性能严重受硬件影响(CPU推理很慢,需要GPU)
  • 不同模型的工具支持不一致(llama3支持,但qwen可能不支持)

工具调用机制

Tool Use(工具调用)是LLM层的核心功能。简单说,它允许AI”调用函数”。

示例流程:

  1. 你问”北京时间现在几点?”
  2. AI决定需要调用get_current_time工具
  3. 返回工具调用请求:{"name": "get_current_time", "args": {"city": "Beijing"}}
  4. OpenClaw执行工具,返回结果:{"time": "2026-03-07 20:30"}
  5. AI基于结果生成答案:”北京时间现在是晚上8:30”

安全机制:

OpenClaw只允许调用预定义的工具,不支持动态代码执行——这已经避免了大部分风险。如果扩展工具,必须仔细评估安全性:

  1. 白名单机制(最重要) - 只注册安全工具,禁止注册危险工具如文件系统操作、网络请求
  2. 参数验证 - 严格验证工具参数,拒绝异常输入
  3. 沙箱执行(高级) - 使用vm2或isolated-vm在隔离环境中执行工具代码
  4. 权限分层 - 不同用户有不同的工具调用权限

五、端到端消息流程

让我们通过一个具体场景来完整追踪消息流:当你在WhatsApp上发送消息给机器人,整个流程如下:

Phase 1: 接收(Ingestion)

  1. Baileys库接收来自WhatsApp服务器的WebSocket事件
  2. WhatsApp适配器解析事件,提取消息文本、媒体附件和发送者元数据

Phase 2: 访问控制与路由(Access Control & Routing)

  1. 访问控制层检查:发送者是否在白名单中?如果是首次私信,是否已配对?
  2. auto-reply系统解析哪个Session应该处理此消息:
    • 直接来自你 → main session
    • 通过WhatsApp的私信 → agent:main:whatsapp:dm:+123…
    • 群组 → agent:main:whatsapp:group:120...@g.us

Phase 3: 上下文组装(Context Assembly)

  1. Agent Runtime从磁盘加载已解析的Session
  2. 组装系统提示词:读取AGENTS.md、SOUL.md、TOOLS.md
  3. 注入相关技能和内存搜索结果
  4. 将富上下文流式发送到配置的模型Provider

Phase 4: 模型调用(Model Invocation)

  1. 模型开始流式响应(token-by-token而非等待最终blob)
  2. 运行时监视工具调用,拦截并执行

Phase 5: 工具执行(Tool Execution)

  1. 如果模型决定运行bash命令,运行时拦截调用并执行(可能在Docker沙箱内)
  2. 如果模型想打开浏览器并抓取网页,运行时启动Chromium并执行自动化

Phase 6: 响应交付(Response Delivery)

  1. 响应块通过Gateway流回
  2. WhatsApp适配器格式化每个块,将markdown转换为WhatsApp的标记格式
  3. 格式化后的消息通过Baileys发送到WhatsApp服务器,最终到达你的手机
  4. 运行时持久化整个对话状态(你的消息、模型响应、所有工具调用和结果)回磁盘

延迟预算:

  • 访问控制:< 10ms
  • 从磁盘加载Session:< 50ms
  • 组装系统提示词:< 100ms
  • 获得第一个token:200-500ms(取决于网络)
  • Bash命令:< 100ms
  • 浏览器自动化:1-3秒

六、数据存储和状态管理

OpenClaw在主目录的多个位置存储数据:

配置文件(~/.openclaw/openclaw.json)

使用JSON5格式,支持注释和尾随逗号——让手工编辑更愉快。配置分层:环境变量覆盖配置文件值,后者覆盖内置默认值。

Session文件(~/.openclaw/sessions/)

每个对话存储为追加-only事件日志,支持分支,易于恢复状态和检查历史。Session标识符编码了所有权和信任边界:

  • agent:<agentId>:main - 主操作者session,具有完整能力
  • agent:<agentId>:<channel>:dm:<identifier> - 私信session,默认沙箱化
  • agent:<agentId>:<channel>:group:<identifier> - 群组session,默认沙箱化

自动压缩:

为了保持在模型上下文限制内,OpenClaw执行自动压缩:对话的旧部分被总结并持久化,以便session可以在不丢失基本上下文的情况下继续。压缩前,系统可以运行轻量级”内存刷新”步骤,将持久信息提升到内存文件。

内存系统(~/.openclaw/memory/)

OpenClaw维护对话的可搜索内存,在交互时提供相关上下文。

存储结构:

  • MEMORY.md - 长期记忆,包含策划的、稳定的事实(仅在私有/main会话加载)
  • memory/YYYY-MM-DD.md - 每日笔记,提供每天活动和上下文的原始运行日志

技术实现:

  • 使用SQLite数据库和向量嵌入
  • 混合搜索:向量相似性(语义匹配)+ BM25关键词相关性(精确token匹配)
  • 文件监视器自动重新索引
  • 如果配置了sqlite-vec,加速SQLite内的向量搜索

嵌入模型自动选择:

  1. 本地嵌入模型(local.modelPath)→ 使用它
  2. 否则检查OpenAI API密钥 → 使用OpenAI嵌入
  3. 否则检查Gemini API密钥 → 使用Gemini嵌入
  4. 如果都没有 → 禁用内存搜索

凭证存储(~/.openclaw/credentials/)

敏感认证数据存储在这里:

  • WhatsApp的session数据
  • Discord等平台的OAuth凭据
  • 其他通道访问所需的密钥

文件权限限制为0600(仅所有者读写),目录自动从版本控制中排除以防止意外泄露。

七、安全架构

OpenClaw通过多层实现深度防御。每层提供不同类型的保护,它们共同工作创建全面的安全姿态。

网络安全

默认情况下,Gateway仅绑定到127.0.0.1(回环接口),这意味着Gateway只能从本地机器访问,从未暴露到公共互联网。

远程访问需要通过以下方式之一进行明确配置:

  • SSH隧道(推荐用于VPS):

    1
    ssh -N -L 18789:127.0.0.1:18789 user@host
  • Tailscale Serve(仅tailnet HTTPS):

    1
    2
    3
    config: {
    gateway.tailscale.mode: "serve"
    }
  • Tailscale Funnel(公共HTTPS,需要密码):

    1
    2
    3
    4
    config: {
    gateway.tailscale.mode: "funnel",
    gateway.auth.mode: "password"
    }

认证和设备配对

令牌或密码认证保护非回环绑定。设置OPENCLAW_GATEWAY_TOKEN环境变量后,所有WebSocket客户端必须在连接的connect.params.auth.token字段中包含该令牌。

设备配对添加额外的安全层。当新设备连接时:

  • 本地连接(回环或同一Tailscale网络)可以配置为自动批准
  • 远程连接必须在握手期间签署挑战nonce以证明拥有有效凭据,并需要显式批准

通道访问控制

白名单明确指定哪些电话号码或用户名可以与你的机器人交互:

1
2
3
4
5
6
7
8
9
10
11
{
"channels": {
"whatsapp": {
"enabled": true,
"allowFrom": ["+1234567890"],
"groups": {
"*": { "requireMention": true }
}
}
}
}

DM配对提供直接消息的人工在环批准。当dmPolicy="pairing"(默认)时,未知发送者触发特定流程:他们发送第一条消息,Gateway用唯一的配对码响应而不是处理消息。

工具沙箱化

OpenClaw使用基于Docker的沙箱隔离每个会话的工具执行。主session(你的直接交互作为操作者)通常在主机上本地运行工具,具有完全访问权限。相比之下,DM和群组session可以配置在临时Docker容器内执行工具,减少不受信任输入的影响。

沙箱策略映射:

  • 主session:完整主机访问(无Docker开销)
  • DM sessions:默认沙箱化(即使对已批准联系人)
  • 群组sessions:默认沙箱化,防御高风险、多参与者输入

可配置的隔离级别:

  • 沙箱内容:是否沙箱化适用于工具
  • 容器粒度:隔离可以每个会话、每个代理或跨沙箱化会话共享
  • 主机暴露:工作区和绑定挂载确定容器看到主机的内容
  • 网络访问:启用容器网络扩展能力但也增加风险
  • 逃生舱口:任何显式”主机级别”或提升工具绕过沙箱应被视为仅高信任表面

提示注入防御

上下文隔离通过保持输入清晰分离来防御提示注入攻击:

  • 用户消息携带源元数据
  • 系统指令与用户提供的内容保持不同
  • 工具结果包装在结构化格式中,与用户输入区分

这种分离使得攻击者更难欺骗代理将不受信任的消息视为系统指令。

八、部署架构

OpenClaw支持四种主要部署模式,每种针对不同用例和环境进行了优化。

1. 本地开发(macOS/Linux)

一切在开发者机器上运行。通过pnpm dev在前台启动Gateway,启用代码更改时的热重载。Gateway绑定到127.0.0.1:18789,仅可从本地机器访问。无需认证,因为回环接口被认为是受信任的,调试日志以完整详细程度运行。

2. 生产macOS(菜单栏应用)

macOS生产部署使用LaunchAgent作为后台服务运行Gateway。服务在登录时自动启动并持续运行。macOS菜单栏应用提供:

  • Gateway生命周期管理(启动、停止、重启)
  • 嵌入WebChat的原生WebKit视图
  • 通过SSH隧道控制远程Gateway
  • Voice Wake功能(配合ElevenLabs实现语音识别和合成)

3. Linux/VM(远程Gateway)

在VPS或虚拟机上运行OpenClaw提供24/7可用性,而无需个人计算机保持开启。Gateway作为systemd服务在远程主机上运行,可以保持绑定到回环(127.0.0.1)以实现安全性。本地客户端(CLI和Web UI)通过SSH隧道连接。

架构图:

1
你的本地机器 ← SSH隧道 → 远程VPS(Gateway) → LLM APIs

4. Fly.io(容器部署)

Fly.io是云原生部署选项,Gateway在由Fly.io管理的Docker容器中运行。持久卷存储OpenClaw状态(配置、会话、凭据),以便在部署和重启时存活。Fly.io提供托管HTTPS端点(带TLS终止),使Gateway可通过公共互联网远程访问。

架构图:

1
公共互联网 → Fly.io(HTTPS/TLS) → 容器(Gateway) → LLM APIs

九、插件系统

OpenClaw设计为在不修改核心代码的情况下进行扩展。插件通过四种主要方式扩展系统:

1. Channel插件

额外的消息平台(Microsoft Teams、Matrix、Mattermost等)

开发自定义Channel的工作流:

  1. 创建Channel类,实现Channel接口
  2. 实现必需方法:
    • start() - 启动Channel(监听webhook或WebSocket)
    • sendMessage() - 向平台发送消息
    • adaptMessage() - 消息格式转换
  3. 在config文件中注册Channel配置
  4. 使用ngrok暴露本地服务,测试webhook

2. Memory插件

替代存储后端(向量存储、知识图谱vs默认SQLite)

3. Tool插件

超越内置bash、浏览器和文件操作的自定义能力

4. Provider插件

自定义LLM提供商或自托管模型

插件加载机制:

插件系统位于extensions/并遵循基于发现的模型。src/plugins/loader.ts中的插件加载器扫描工作区包的package.json中的openclaw.extensions字段,根据声明的架构进行验证,并在配置存在时热加载。

十、实际应用案例

场景1:多平台统一管理

一个销售团队使用OpenClaw管理客户咨询:

  • WhatsApp - 主要客户沟通(公开bot,@触发)
  • Telegram - 技术支持群组(私密,配对模式)
  • Slack - 内部协作(企业集成)
  • iMessage - CEO快速请求(本地macOS)

所有平台共享同一个智能中心,上下文在会话间隔离但工具可以跨平台调用(如CRM系统查询)。

场景2:多代理协作

一个内容创建团队设置多个专业代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"agents": {
"mapping": {
"group:discord:123456": {
"workspace": "~/.openclaw/workspaces/content-creator",
"model": "anthropic/claude-sonnet-4-5",
"systemPromptOverrides": {
"SOUL.md": "You are a creative content writer..."
}
},
"dm:telegram:*": {
"workspace": "~/.openclaw/workspaces/editor",
"model": "openai/gpt-4o",
"sandbox": { "mode": "always" }
}
}
}
}
  • Discord代理:创意人格,专注于内容创作
  • Telegram支持DM:正式语调,GPT-4o,严格沙箱
  • 不同上下文可以有不同工具访问
  • 隔离沙箱确保即使有人试图利用提示注入漏洞,爆炸半径也保持包含

场景3:定时任务自动化

通过cron jobs实现自动化:

每日早上9点摘要:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"name": "daily-morning-briefing",
"schedule": {
"kind": "cron",
"expr": "0 9 * * *",
"tz": "Asia/Shanghai"
},
"payload": {
"kind": "agentTurn",
"message": "Generate a morning briefing summarizing yesterday's activities and today's schedule"
},
"sessionTarget": "isolated",
"delivery": {
"mode": "announce",
"channel": "telegram",
"to": "ou_ada5a4d5aa9105ec4bede472f9662033"
}
}

Webhook集成:
Gmail发布到webhook端点触发代理操作:

  • 新邮件到达 → webhook触发 → OpenClaw自动分类和归档
  • 日历邀请 → webhook触发 → OpenClaw检查冲突并回复
  • 付款确认 → webhook触发 → OpenClaw更新财务记录

十一、性能优化实践

Session缓存优化

默认情况下Sessions存储在内存中,重启时丢失。可以集成Redis:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class RedisSessionStore {
private redis: Redis;

async get(userId: string, channelId: string): Promise<Session> {
const key = `session:${channelId}:${userId}`;
const data = await this.redis.get(key);
return data ? JSON.parse(data) : null;
}

async set(session: Session) {
const key = `session:${session.channelId}:${session.userId}`;
await this.redis.setex(key, 3600, JSON.stringify(session)); // 1小时过期
}
}

消息队列调优

在高并发场景中,内存队列不足——可以切换到Bull(基于Redis的任务队列):

1
2
3
4
5
6
7
8
9
10
import Queue from 'bull';

const messageQueue = new Queue('openclaw-messages', {
redis: { host: 'localhost', port: 6379 }
});

messageQueue.process(10, async (job) => { // 最大10并发
const { session, message } = job.data;
return await gateway.processMessage(session, message);
});

并发连接控制

LLM API通常有速率限制(如OpenAI的60 RPM)。可以使用p-limit库控制并发:

1
2
3
4
5
6
7
8
9
import pLimit from 'p-limit';

const limit = pLimit(10); // 最大10并发请求

const tasks = messages.map(msg =>
limit(() => provider.chat(msg))
);

await Promise.all(tasks);

优化结果对比(实际测试数据):

  • 优化前:100并发请求,平均响应时间8秒,15%失败率
  • 优化后:100并发请求,平均响应时间3秒,性能提升2.6倍

十二、总结

OpenClaw的架构设计真正清晰明了。每一层只管理自己的关注点,有明确定义的责任边界,使得扩展特别方便。

核心优势

  1. 清晰的关注点分离 - Gateway管理会话,Channel处理路由,LLM管理接口
  2. 插件化设计 - Provider和Channel都可以动态加载和注册
  3. 灵活的部署 - 支持本地、VPS、容器等多种部署模式
  4. 多层安全防护 - 网络隔离、访问控制、沙箱执行、提示注入防御
  5. 丰富的扩展点 - 可以添加新的平台、模型、工具、内存后端
  6. 数据本地化 - 所有数据存储在你控制的硬件上

适合的场景

  • 个人助理 - 多平台统一AI助手
  • 团队协作 - 多代理协同工作
  • 自动化任务 - Cron jobs和Webhook集成
  • 开发者工具 - 自定义技能和工作流
  • 企业集成 - 与CRM、工具、系统集成

如何开始

如果你想深入了解或定制OpenClaw:

  1. 克隆源码 - git clone https://github.com/openclaw/openclaw
  2. 阅读核心文件 - Gateway、Channel、Provider的实现
  3. 尝试开发扩展 - 创建自定义Channel或Provider
  4. 加入社区 - GitHub Issues、Discord社区交流

OpenClaw不仅仅是一个聊天机器人包装器。它是一个AI代理的操作系统。LLM提供智能;OpenClaw提供执行环境。

这就是为什么它能在短短两个月内从脚本成长为18万星的开源奇迹。


参考资料


标签: #OpenClaw #技术架构 #开源 #AI代理 #插件系统 #三层设计