简介
本指南面向首次接触 OpenClaw 的用户,目标是在约 15 分钟内完成从安装到首次使用的全流程。内容覆盖系统要求、推荐安装方式与环境准备、向导驱动的设置流程(openclaw onboard)、多平台安装要点(macOS/Linux/Windows WSL2),以及常见问题与故障排除建议。
项目结构
OpenClaw 提供统一的 CLI 入口 openclaw,通过内置的“引导向导”完成网关安装、工作空间配置、渠道连接与技能启用等关键步骤。仓库中包含完整的文档与平台指南,便于按需查阅。
graph TB
A["终端/脚本"] --> B["openclaw CLI<br/>入口: openclaw.mjs"]
B --> C["构建产物 dist/entry(.mjs)<br/>运行时加载"]
C --> D["网关服务<br/>本地或远程"]
C --> E["通道适配器<br/>Telegram/WhatsApp/Slack/Discord 等"]
C --> F["技能与工具<br/>内置/工作空间/扩展"]
核心组件
- CLI 入口与版本校验:openclaw.mjs 在启动时检查 Node 版本(≥22.12),并在不满足条件时给出明确指引。
- 引导向导(openclaw onboard):交互式配置模型/认证、工作空间、网关、通道、守护进程与技能,支持 QuickStart 与 Advanced 模式。
- 平台支持:macOS(菜单栏应用 + 网关代理)、Linux(systemd 用户服务)、Windows(WSL2 推荐)。
- 文档与参考:安装、入门、平台、CLI、故障排除等文档目录完备。
架构总览
下图展示了从终端到网关、通道与技能的整体关系,帮助理解“首次使用”的端到端路径。
sequenceDiagram
participant U as "用户"
participant CLI as "openclaw CLI"
participant GW as "网关服务"
participant CH as "通道适配器"
participant SK as "技能/工具"
U->>CLI : 运行 onboard 安装向导
CLI->>GW : 配置网关/守护进程
CLI->>CH : 配置通道可选
CLI->>SK : 安装推荐技能
U->>CLI : 打开 Dashboard 或发送测试消息
CLI->>GW : 建立控制连接
GW-->>U : 返回状态/日志/诊断
详细组件分析
系统要求与环境准备
- Node.js 要求:Node ≥22.12(openclaw.mjs 内置版本校验)。若未安装或版本过低,可通过包管理器或版本管理器安装。
- 包管理器:npm/pnpm/bun 均可;从源码构建时推荐 pnpm。
- 平台建议:Windows 强烈推荐 WSL2;macOS/Linux 可直接安装。
推荐安装方式与步骤
- 官方安装脚本(推荐):在 macOS/Linux/WSL2 上一键安装 CLI、全局注册并启动引导向导;Windows 使用 PowerShell 脚本。
- npm/pnpm:手动安装后运行引导向导;pnpm 需要批准构建脚本。
- 从源码:克隆仓库、安装依赖、构建 UI 与二进制,再运行引导向导。
向导驱动的设置流程(openclaw onboard)
- QuickStart:默认本地网关、常用端口与认证策略、工具策略、DM 隔离策略、关闭 Tailscale 暴露、默认允许 Telegram/WhatsApp DM(需要手机号)。
- Advanced:逐项配置网关模式、工作空间、端口/绑定/认证、通道、守护进程、健康检查与技能。
- 关键输出:生成配置、凭据、会话、工作空间种子文件、守护进程安装与健康检查。
- 重用与扩展:可对现有配置执行 configure;为新代理创建独立工作空间与会话。
多平台安装要点
- macOS
- 菜单栏应用负责权限与网关生命周期管理;可本地或远程模式运行。
- LaunchAgent 控制网关服务;节点能力通过 macOS 应用暴露。
- Linux
- systemd 用户服务为默认守护进程;适合 VPS/服务器场景。
- 可通过 SSH 隧道访问本地网关。
- Windows(WSL2)
- 强烈推荐在 WSL2 中安装与运行;支持开机自启链路配置。
- 如需局域网访问,可使用 portproxy 将 Windows 端口转发至 WSL IP。
首次使用与验证
- 快速聊天:无需通道配置,直接打开 Dashboard 即可进行首次对话。
- 前台运行:如需快速调试,可在前台启动网关。
- 发送测试消息:配置通道后,使用消息子命令发送测试消息。
- 环境变量:可通过 OPENCLAW_HOME/OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH 自定义路径。
依赖分析
- CLI 入口 openclaw.mjs 会在启动时校验 Node 版本,并尝试加载构建产物(dist/entry 或 dist/entry.mjs)。
- package.json 定义了 CLI 入口、构建脚本、依赖与引擎要求(Node ≥22.12)。
- 文档与平台指南相互补充,形成从安装到运维的闭环。
graph LR
MJS["openclaw.mjs"] --> ENG["引擎要求<br/>Node ≥22.12"]
MJS --> DIST["构建产物<br/>dist/entry(.mjs)"]
PKG["package.json"] --> BIN["CLI 入口<br/>openclaw"]
PKG --> DEPS["运行时依赖"]
DOC["文档与平台指南"] --> INST["安装/更新/卸载"]
DOC --> WIZ["引导向导"]
DOC --> TROUBLE["故障排除"]
性能考虑
- 首次运行建议使用 QuickStart,默认工具策略与 DM 隔离策略有助于降低误用风险。
- 若计划处理 webhook/钩子内容或执行工具,优先选择更强更新的模型,并保持工具策略严格。
- 在 Linux/VPS 场景,使用 systemd 用户服务以获得稳定的后台运行与自动重启能力。
故障排除指南
- 60 秒快速诊断:依次执行 status、status --all、gateway probe、gateway status、doctor、channels status --probe、logs --follow。
- 常见问题定位:
- 无回复:检查网关运行状态、通道连接状态与配对/白名单。
- 控制界面无法连接:确认网关 URL/端口、认证模式与令牌/密码正确。
- 网关无法启动:检查服务是否已安装、端口占用、非回环绑定是否配置认证。
- 通道已连接但消息不流动:检查提及门禁、配对状态与权限令牌。
- Cron/心跳未触发:检查调度器启用状态、活跃时段与并发限制。
- 节点工具失败:确认节点已配对、能力存在且权限已授予。
- 浏览器工具失败:检查浏览器可执行路径、扩展附加状态与 CDP 目标可达性。
- PATH/命令未找到:核对 npm prefix -g 输出是否在 PATH 中,必要时在 shell 启动文件中追加。
引言
本文件系统化阐述 OpenClaw 的安全架构与信任模型,覆盖认证授权、访问控制、设备配对、网络传输与数据保护、权限与沙箱隔离、威胁建模与风险缓解等关键主题。文档以 MITRE ATLAS 威胁模型为框架,结合源码实现与官方安全文档,给出可操作的安全建议与可视化图示,帮助开发者与运营者正确部署与维护 OpenClaw。
项目结构
围绕安全相关的关键目录与文件:
- 安全策略与威胁模型:SECURITY.md、docs/security/*
- 网关认证与访问控制:src/gateway/auth.ts、src/web/inbound/access-control.ts
- 执行审批与工具策略:src/infra/exec-approvals.ts、src/agents/sandbox/tool-policy.ts
- 外部内容处理与提示注入防护:src/security/external-content.ts
- 设备配对协议与流程:src/gateway/protocol/schema/devices.ts、extensions/device-pair/index.ts
- 运行时与平台安全脚本:scripts/debug-claude-usage.ts
- 沙箱路径安全与边界:src/agents/sandbox/fs-bridge-path-safety.ts
- 安全审计 CLI:docs/cli/security.md
graph TB
subgraph "安全策略与文档"
A["SECURITY.md"]
B["docs/security/README.md"]
C["docs/security/THREAT-MODEL-ATLAS.md"]
D["docs/security/CONTRIBUTING-THREAT-MODEL.md"]
end
subgraph "网关与通道"
E["src/gateway/auth.ts"]
F["src/web/inbound/access-control.ts"]
G["src/gateway/protocol/schema/devices.ts"]
H["extensions/device-pair/index.ts"]
end
subgraph "执行与沙箱"
I["src/infra/exec-approvals.ts"]
J["src/agents/sandbox/tool-policy.ts"]
K["src/agents/sandbox/fs-bridge-path-safety.ts"]
end
subgraph "外部内容与传输"
L["src/security/external-content.ts"]
end
subgraph "工具与脚本"
M["docs/cli/security.md"]
N["scripts/debug-claude-usage.ts"]
end
A --> B
B --> C
C --> D
E --> F
F --> G
G --> H
E --> I
I --> J
J --> K
L --> E
M --> E
N --> E
核心组件
- 认证与授权(Gateway)
- 支持 token/password/trusted-proxy/none 等模式;默认 token;支持速率限制与 Tailscale 身份校验;严格区分会话路由与主机执行边界。
- 入站访问控制(Channel)
- 基于 AllowFrom/AllowList、群组策略与配对宽限期的多层过滤;对未授权发送者进行阻断并触发配对挑战。
- 执行审批与工具策略(Sandbox)
- 可配置的执行安全级别(deny/allowlist/full)与“询问”策略;基于通配与代理的白名单;通过 socket 交互式审批。
- 外部内容处理
- 统一封装与安全提示,标记与转义可疑边界符,降低提示注入风险。
- 设备配对
- 基于一次性配对码与 30 秒宽限期;支持 QR 与通知联动;记录请求与决策事件。
- 沙箱路径安全
- 限定容器挂载根,边界读写检查,防止逃逸与越权访问。
- 安全审计 CLI
- 提供快速安全审计与修复建议,涵盖权限收紧、默认策略调整与危险参数提示。
架构总览
下图展示 OpenClaw 的信任边界与数据流,强调通道接入、会话隔离、执行沙箱、外部内容与供应链五个边界,并映射到关键实现文件。
graph TB
U["用户/通道客户端"] --> |消息| GW["网关(Gateway)<br/>认证/路由"]
GW --> |会话键| SS["会话隔离<br/>按 sender/channel/peer"]
SS --> |工具调用| TP["工具策略(Sandbox)<br/>allow/deny/通配"]
TP --> |执行审批| EA["执行审批<br/>socket/白名单/询问"]
EA --> SB["沙箱运行时<br/>挂载/路径/边界"]
GW --> EC["外部内容封装<br/>XML标记/安全提示"]
CH["ClawHub/技能市场"] -.-> TP
subgraph "信任边界"
B1["通道接入边界"]
B2["会话隔离边界"]
B3["执行沙箱边界"]
B4["外部内容边界"]
B5["供应链边界"]
end
U --- B1
GW --- B2
SS --- B3
TP --- B4
CH --- B5
详细组件分析
认证与授权(Gateway)
- 模式解析与配置
- 解析优先级:显式覆盖 > 配置 > 密码 > Token > 默认;支持 Tailscale 身份校验与受信代理头。
- 请求授权
- 受信代理:校验代理列表、必需头、用户头与允许用户集合。
- Tailscale:仅在非本地直连且允许时启用,通过反查校验登录一致性。
- Token/Password:常量时间比较,失败计入速率限制;支持本地直连判定。
- 速率限制与安全
- 对共享密钥场景统一限流;成功后重置,失败记录;支持自定义客户端 IP 来源与范围。
sequenceDiagram
participant C as "客户端"
participant GW as "网关认证(authorizeGatewayConnect)"
participant TS as "Tailscale Whois"
participant RL as "速率限制器"
C->>GW : "携带凭据/代理头/请求"
GW->>RL : "检查限流"
alt 受信代理模式
GW->>GW : "校验代理与用户头"
GW-->>C : "授权结果"
else Tailscale 模式
GW->>TS : "校验登录一致性"
TS-->>GW : "返回用户信息"
GW-->>C : "授权结果"
else Token/Password
GW->>GW : "常量时间比较"
GW-->>C : "授权结果"
end
入站访问控制(Channel)
- 策略组合
- DM 策略:pairing/allowlist/open/disabled;群组策略:open/disabled/allowlist;默认策略从配置解析。
- 授权判定
- 自对话、历史消息抑制、配对宽限期(默认 30 秒);未授权发送者触发配对挑战并暂不投递。
- 存储与回退
- 允许列表可来自配置、存储与运行时回退;支持通配与 E164 归一化。
flowchart TD
Start(["进入入站控制"]) --> LoadCfg["加载账户配置与默认策略"]
LoadCfg --> Normalize["归一化发送方标识"]
Normalize --> GroupCheck{"是否群组消息?"}
GroupCheck --> |是| GroupPolicy["应用群组策略与允许列表"]
GroupPolicy --> GroupAllowed{"允许?"}
GroupAllowed --> |否| BlockGroup["阻断并记录原因"]
GroupAllowed --> |是| ProceedDM
GroupCheck --> |否| ProceedDM["处理 DM 流程"]
ProceedDM --> FromMe{"是否来自自己?"}
FromMe --> |是| SkipOutbound["跳过并记录"]
FromMe --> |否| DMPolicy["应用 DM 策略"]
DMPolicy --> Pairing{"是否需要配对?"}
Pairing --> |是| IssueChallenge["发出配对挑战并暂不投递"]
Pairing --> |否| FinalCheck["最终授权判定"]
FinalCheck --> Decision{"允许/阻断/暂不投递"}
BlockGroup --> End(["结束"])
SkipOutbound --> End
IssueChallenge --> End
Decision --> End
设备配对流程
- 协议与事件
- 设备请求/已决事件包含请求 ID、设备 ID、公钥、显示名、平台、角色、作用域、远端 IP、静默标志、修复模式与时间戳。
- 配对动作
- 生成网关 URL 与凭据;根据渠道渲染二维码或设置一次性通知;在 Telegram 场景下尝试一次性配对提醒。
- 安全要点
- 30 秒宽限期;一次性配对码;记录请求与决策事件;支持静默与修复模式。
sequenceDiagram
participant Dev as "设备"
participant Ext as "device-pair 插件"
participant GW as "网关"
Dev->>Ext : "请求配对"
Ext->>Ext : "解析认证/网关URL"
Ext->>GW : "发送配对请求(含公钥/角色/作用域)"
GW-->>Ext : "返回决策(接受/拒绝)"
Ext-->>Dev : "通知结果/二维码(如适用)"
执行审批与工具策略
- 执行安全级别
- deny(默认):除非白名单命中;allowlist:仅白名单命令;full:全部放行。
- 询问策略
- off/on-miss/always;on-miss 表示未命中白名单或分析不通过时触发。
- 工具策略
- 支持全局/代理级 allow/deny;通配展开;默认允许 image 工具以保障多模态工作流。
- 文件与权限
- 执行审批文件采用严格权限保存;socket 令牌随机生成;支持持久化与热更新。
flowchart TD
Req(["收到工具调用"]) --> Resolve["解析代理/全局策略"]
Resolve --> Compile["编译/展开通配符"]
Compile --> CheckAllow{"allow 列表为空?"}
CheckAllow --> |是| AllowAll["默认允许"]
CheckAllow --> |否| MatchAllow["匹配 allow 列表"]
MatchAllow --> DenyCheck{"匹配 deny 列表?"}
DenyCheck --> |是| Deny["拒绝"]
DenyCheck --> |否| Next["进入执行审批"]
AllowAll --> Next
Next --> Ask{"询问策略触发?"}
Ask --> |是| Socket["通过 socket 发起审批"]
Ask --> |否| Direct["直接执行(若满足安全级别)"]
Socket --> Decision{"审批结果"}
Decision --> |允许| Direct
Decision --> |拒绝| Deny
外部内容处理与提示注入防护
- 包装与标记
- 使用唯一随机 ID 的 XML 风格边界标记;对常见边界符进行折叠与替换,避免伪造与逃逸。
- 安全提示
- 明确声明外部来源、不可视为系统指令、禁止执行敏感操作与泄露信息。
- 提示构建
- 将包装后的内容与任务上下文拼接,形成安全提示;支持 web_search/web_fetch 的简化包装。
flowchart TD
In(["原始外部内容"]) --> Sanitize["替换/折叠边界标记"]
Sanitize --> Warn["附加安全提示块"]
Warn --> Mark["插入起止边界标记(带随机ID)"]
Mark --> Meta["添加来源/发件人/主题元数据"]
Meta --> Out(["安全提示输出"])
沙箱路径安全与边界
- 挂载与路径
- 依据容器路径解析挂载根;仅允许在限定挂载内打开文件;支持别名策略与类型约束。
- 边界读写
- 通过边界文件打开器校验宿主路径是否位于挂载根内;拒绝越界访问。
- 校验链路
- 解析容器路径 → 查找挂载 → 边界打开 → 安全性断言 → 返回结果。
classDiagram
class SandboxFsPathGuard {
+assertPathChecks(checks)
+openReadableFile(target)
-resolveRequiredMount(containerPath, action)
-openBoundaryWithinRequiredMount(target, action, options)
-assertGuardedPathSafety(target, options, guarded)
}
class BoundaryFileOpenResult {
+ok
+error
}
SandboxFsPathGuard --> BoundaryFileOpenResult : "使用"
安全审计 CLI
- 功能概览
- 审计报告、深度扫描、自动修复、JSON 输出;针对会话作用域、危险参数、Docker 网络、浏览器沙箱等发出告警与建议。
- 修复范围
- 紧急修复:组策略、日志敏感度、状态文件权限等;不涉及凭证轮换、禁用工具、暴露网关等高风险变更。
依赖关系分析
- 组件耦合
- 网关认证与速率限制紧密耦合;通道入站控制依赖账户配置与存储;执行审批依赖工具策略与 socket 通信。
- 外部依赖
- Tailscale 身份校验;受信代理头;Node.js 内置模块(fs/path/crypto)。
- 潜在环路
- 当前实现未见循环依赖;各模块职责清晰,接口稳定。
graph LR
Auth["auth.ts"] --> AccCtrl["access-control.ts"]
AccCtrl --> DevPair["devices.ts/schema"]
Auth --> ExecApp["exec-approvals.ts"]
ExecApp --> ToolPol["tool-policy.ts"]
ToolPol --> FsGuard["fs-bridge-path-safety.ts"]
Auth --> ExtWrap["external-content.ts"]
CLI["docs/cli/security.md"] --> Auth
CLI --> ExecApp
性能考量
- 速率限制与缓存
- 合理设置限流阈值与范围,避免误伤合法流量;成功授权后及时重置计数。
- 执行审批
- 在 allowlist 策略下尽量减少交互频率;必要时开启“on-miss”以平衡安全与体验。
- 外部内容处理
- 标记与转义开销可控;建议对高频来源启用缓存与去重。
- 沙箱路径检查
- 挂载解析与边界打开为轻量操作;避免在热路径中重复解析同一挂载。
故障排查指南
- 常见问题定位
- 认证失败:核对 token/password 是否正确;检查速率限制状态;确认受信代理头与用户列表。
- 通道阻断:检查 AllowFrom/AllowList 与群组策略;确认配对宽限期内的历史消息抑制逻辑。
- 执行被拒:查看工具策略与白名单;确认审批 socket 是否可用;评估“询问”策略触发条件。
- 外部内容异常:检查边界标记是否被替换;确认来源标签与安全提示是否完整。
- 平台与密钥
- macOS Keychain 读取 Chrome Cookie 示例脚本可用于调试与取证,注意错误分支与解密参数。
项目结构
OpenClaw 采用多平台、多客户端与多通道的分布式控制架构:
- 网关(Gateway)作为单一 WebSocket 控制平面,承载所有客户端(CLI、Web、桌面应用、移动节点、无头节点)与工具/事件的统一接入。
- 代理引擎(Pi Agent)通过 RPC 模式运行,负责执行工具调用、流式输出与会话状态管理。
- 会话模型(Session)贯穿消息路由、上下文压缩、权限与沙箱策略。
- 插件与技能(Plugins/Skills)以扩展方式提供能力,遵循“核心精简、插件外置”的原则。
graph TB
subgraph "客户端"
CLI["CLI 客户端"]
Web["Web 控制界面"]
Desktop["桌面应用"]
Nodes["移动/节点设备"]
end
subgraph "网关控制平面"
GW_WS["Gateway WebSocket 控制平面"]
Auth["认证与配对"]
Sessions["会话管理"]
Events["事件与心跳"]
end
subgraph "代理引擎"
PiAgent["Pi AgentRPC"]
Tools["工具集浏览器/节点/系统等"]
end
subgraph "外部通道"
Channels["多通道适配器<br/>WhatsApp/Telegram/Slack/Discord/..."]
end
CLI --> GW_WS
Web --> GW_WS
Desktop --> GW_WS
Nodes --> GW_WS
GW_WS --> Auth
GW_WS --> Sessions
GW_WS --> Events
GW_WS --> PiAgent
PiAgent --> Tools
Tools --> Channels
核心组件
- 网关 WebSocket 控制平面:统一的传输层与协议层,负责握手、鉴权、配对、心跳、事件广播与请求响应。
- 会话管理:会话解析、存储、键名规范化、全局/未知会话处理、会话缓存预热。
- 代理引擎(Pi Agent):以 RPC 形式运行,承载工具流式输出、会话补丁与上下文管理。
- 工具与节点:浏览器控制、Canvas/A2UI、节点能力(macOS 系统命令、通知、相机、屏幕录制、位置等)。
- 插件与技能:通过扩展加载,遵循 npm 分发与本地开发加载路径;内存插件为单实例。
架构总览
OpenClaw 的“网关控制平面”是系统中枢,所有客户端与工具均通过 WebSocket 连接至网关。网关负责:
- 客户端握手与角色/范围声明
- 设备身份与配对流程
- 会话解析与路由
- 事件广播与心跳
- 请求/响应编解码与校验
- 远程访问(Tailscale Serve/Funnel)与安全策略
sequenceDiagram
participant C as "客户端CLI/Web/桌面/节点"
participant GW as "网关Gateway"
participant PI as "代理引擎Pi Agent"
participant CH as "通道适配器"
C->>GW : "connect 握手含设备身份/角色/范围"
GW-->>C : "hello-ok协议版本/策略"
C->>GW : "请求如 sessions.resolve / chat.send / tools.*"
GW->>PI : "转发到代理引擎RPC"
PI->>CH : "调用通道/工具浏览器/节点/系统"
CH-->>PI : "执行结果/事件"
PI-->>GW : "响应/事件"
GW-->>C : "响应/事件"
GW-->>C : "心跳/事件presence/tick/shutdown 等"
详细组件分析
网关 WebSocket 协议与握手
- 传输:WebSocket 文本帧(JSON)
- 首帧必须为 connect 请求
- 握手阶段网关下发挑战,客户端签名后完成认证
- 客户端需声明角色(role)与作用域(scopes),并携带设备身份信息
- 协议版本协商与策略返回(如心跳间隔)
sequenceDiagram
participant Client as "客户端"
participant Gateway as "网关"
Client->>Gateway : "event(connect.challenge)"
Gateway-->>Client : "nonce/ts"
Client->>Gateway : "req(connect){client, role, scopes, device}"
Gateway-->>Client : "res(hello-ok){protocol, policy}"
会话管理与解析
- 支持按标签/键解析会话,必要时进行存在性校验
- 全局/未知会话键的特殊处理
- 会话存储路径解析与兼容旧键扫描
- 会话管理器缓存预热与 TTL 控制,降低冷启动开销
flowchart TD
Start(["进入会话解析"]) --> CheckLabel["检查 meta.sessionLabel"]
CheckLabel --> |存在| ResolveLabel["sessions.resolve(label)"]
ResolveLabel --> FoundLabel{"解析成功?"}
FoundLabel --> |否| Error1["抛出异常:无法解析标签"]
FoundLabel --> |是| ReturnKey["返回解析后的键"]
CheckLabel --> |不存在| CheckKey["检查 meta.sessionKey"]
CheckKey --> |存在且允许| ReturnKey
CheckKey --> |存在但要求已存在| ResolveKey["sessions.resolve(key)"]
ResolveKey --> FoundKey{"解析成功?"}
FoundKey --> |否| Error2["抛出异常:会话键不存在"]
FoundKey --> |是| ReturnKey
CheckKey --> |不存在| UseRequested["使用传入的 requestedLabel/requestedKey"]
UseRequested --> ReturnKey
ReturnKey --> End(["结束"])
代理引擎与工具链
- 代理引擎以 RPC 模式运行,承载工具调用与流式输出
- 浏览器工具支持状态查询、启动/停止、配置与代理请求
- 节点能力通过网关进行描述与调用(macOS 系统命令、通知、Canvas、相机、屏幕录制、位置等)
classDiagram
class PiAgent {
+执行工具调用
+流式输出
+会话补丁
}
class BrowserTool {
+status()
+start()
+stop()
+profiles()
}
class NodeCapabilities {
+system.run()
+system.notify()
+canvas.*
+camera.*
+screen.record()
+location.get()
}
PiAgent --> BrowserTool : "调用"
PiAgent --> NodeCapabilities : "通过网关调用"
事件驱动与心跳
- 网关周期性发送心跳事件(tick),客户端据此维护连接健康
- 支持关闭事件(shutdown)与策略提示(如服务重启)
- 控制界面与远程访问场景下,心跳与策略参数影响客户端行为
sequenceDiagram
participant GW as "网关"
participant Client as "客户端"
GW-->>Client : "event(tick){policy.tickIntervalMs}"
Note over GW,Client : "客户端按策略定时发送心跳/处理事件"
GW-->>Client : "event(shutdown)"
Client-->>GW : "close(代码/原因)"
微服务设计与插件体系
- 核心保持轻量,能力以外部插件形式提供
- 内存插件为单实例,其他插件可按需加载
- 技能优先发布于 ClawHub,减少核心默认技能数量
- MCP 通过 mcporter 桥接,避免在核心中直接集成
graph LR
Core["核心轻量"] --> Plugins["插件系统"]
Plugins --> Memory["内存插件单实例"]
Plugins --> Skills["技能ClawHub"]
Plugins --> MCP["MCP 通过 mcporter 桥接"]
依赖分析
- 协议与校验:TypeBox Schema + AJV 校验,确保请求/响应一致性与错误格式化
- 传输与安全:WebSocket 文本帧 + 可选 TLS 固定指纹
- 会话与缓存:会话键解析与 TTL 缓存,提升启动与切换效率
- 工具链:浏览器控制、节点能力经由网关统一调度
graph TB
Proto["协议与校验AJV/Schema"] --> WS["WebSocket 传输"]
WS --> Auth["认证与配对"]
WS --> Sessions["会话解析与缓存"]
WS --> Tools["工具与节点调度"]
Tools --> Browser["浏览器控制"]
Tools --> Nodes["节点能力"]
项目结构
OpenClaw 的数据流涉及多个子系统:通道接入(入站)、自动回复与路由、出站投递、会话与上下文引擎、内存检索与索引、配置与校验等。下图概览了主要模块及其交互关系:
graph TB
subgraph "入站通道"
CH_IN["通道适配器<br/>src/channels/plugins/outbound/load.ts"]
IN_DEBOUNCE["入站去抖策略<br/>src/channels/inbound-debounce-policy.test.ts"]
IN_ENVELOPE["入站信封构建<br/>src/plugin-sdk/inbound-envelope.ts"]
end
subgraph "自动回复与路由"
DISPATCH["按配置派发<br/>src/auto-reply/reply/dispatch-from-config.ts"]
ROUTER["绑定投递路由<br/>src/infra/outbound/bound-delivery-router.ts"]
GATEWAY_HOOKS["网关钩子会话键归一化<br/>src/gateway/hooks.ts"]
end
subgraph "出站投递"
DELIVER_RUNTIME["出站运行时<br/>src/infra/outbound/deliver-runtime.ts"]
CHANNEL_PLUGIN["通道插件加载(轻量)<br/>src/channels/plugins/outbound/load.ts"]
end
subgraph "会话与上下文"
SESSION_KEY["会话键解析<br/>src/commands/agent/session.ts"]
STORE_CACHE["会话存储缓存<br/>src/config/sessions/store-cache.ts"]
CTX_ENGINE["上下文引擎接口<br/>src/context-engine/types.ts"]
MEM_INDEX["内存索引管理<br/>src/memory/manager.ts"]
end
subgraph "配置与校验"
CFG_VALIDATE["配置校验与错误格式化<br/>src/gateway/protocol/index.ts"]
CFG_SCHEMAS["配置模式回归测试<br/>src/config/config.schema-regressions.test.ts"]
CRON_STORE["定时任务存储字段迁移<br/>src/cron/service/store.ts"]
end
CH_IN --> IN_DEBOUNCE --> IN_ENVELOPE --> DISPATCH
DISPATCH --> ROUTER --> DELIVER_RUNTIME
DISPATCH --> SESSION_KEY --> STORE_CACHE
DISPATCH --> CTX_ENGINE --> MEM_INDEX
ROUTER --> CHANNEL_PLUGIN
GATEWAY_HOOKS --> DISPATCH
CFG_VALIDATE --> DISPATCH
CFG_SCHEMAS --> CFG_VALIDATE
CRON_STORE --> CFG_VALIDATE
核心组件
- 入站信封与路由
- 入站信封构建器负责将原始消息封装为统一格式,并携带会话更新时间戳等元信息,便于后续路由与派发。
- 绑定投递路由根据目标会话键与活动绑定关系选择最佳投递通道,支持回退策略。
- 自动回复与钩子
- 按配置派发逻辑负责重复消息过滤、会话状态标记、钩子执行与上下文提取。
- 插件钩子提供 message_received 等扩展点,允许外部插件参与消息生命周期。
- 出站投递
- 出站运行时负责将消息负载分发给具体通道插件,通道插件通过轻量加载器按需拉取。
- 会话与上下文
- 会话键解析结合配置与上下文推导主键与作用域;会话存储缓存提供 TTL 与一致性检查。
- 上下文引擎定义了组装、压缩、摄取等生命周期方法,支撑模型上下文管理与历史记录处理。
- 内存与检索
- 内存索引管理器提供向量与全文混合检索、批处理与只读数据库恢复能力,支持会话级增量同步。
- 配置与校验
- 配置校验与错误格式化确保输入安全与可诊断性;配置模式回归测试覆盖典型场景;定时任务存储字段迁移保障兼容性。
架构总览
下图展示了从消息进入系统到最终响应的关键路径与组件协作关系:
sequenceDiagram
participant CH as "入站通道"
participant ENV as "入站信封构建器"
participant DIS as "按配置派发"
participant HOOK as "插件钩子"
participant SKEY as "会话键解析"
participant CACHE as "会话存储缓存"
participant CTX as "上下文引擎"
participant MEM as "内存索引管理"
participant RT as "出站运行时"
participant PLG as "通道插件"
CH->>ENV : "原始消息"
ENV-->>DIS : "封装后的消息体+元信息"
DIS->>HOOK : "触发 message_received 钩子"
HOOK-->>DIS : "异步回调完成"
DIS->>SKEY : "解析会话键/作用域"
SKEY->>CACHE : "读取/写入会话存储缓存"
DIS->>CTX : "组装/压缩上下文"
CTX->>MEM : "检索/同步会话相关记忆"
DIS->>RT : "生成投递计划"
RT->>PLG : "调用通道插件发送"
PLG-->>CH : "响应/确认"
详细组件分析
入站信封与去抖策略
- 入站信封构建器
- 负责基于路由与会话更新时间戳格式化消息体,形成统一的内部表示,便于后续派发与路由。
- 提供运行时参数以支持不同通道的格式化需求。
- 入站去抖策略
- 支持按通道粒度的去抖配置,避免重复文本、媒体与控制命令的无效触发,提升吞吐与稳定性。
flowchart TD
Start(["收到原始消息"]) --> BuildEnv["构建入站信封<br/>携带会话更新时间戳"]
BuildEnv --> DebounceCheck{"是否需要去抖?"}
DebounceCheck --> |是| DropOrDelay["丢弃或延后处理"]
DebounceCheck --> |否| EnvelopeReady["信封就绪"]
DropOrDelay --> EnvelopeReady
EnvelopeReady --> Dispatch["进入派发流程"]
自动回复与会话状态管理
- 按配置派发
- 在派发前进行重复消息检测与跳过、会话状态标记(processing/idle)与日志记录,确保状态机正确流转。
- 提取钩子上下文(含消息 ID、群组标识等),用于插件与内部钩子使用。
- 会话键解析
- 结合配置的作用域与主键规则,从上下文推导会话键;支持显式会话键与会话 ID 的优先复用。
- 会话存储缓存
- 提供 TTL 过期、mtime/size 校验与序列化缓存,避免频繁磁盘 IO 并保证一致性。
flowchart TD
A["派发入口"] --> B["重复消息检测"]
B --> |重复| Skip["记录并跳过"]
B --> |非重复| C["解析会话键/作用域"]
C --> D["读取/写入会话存储缓存"]
D --> E["标记会话状态 processing"]
E --> F["触发钩子(message_received)"]
F --> G["准备上下文并进入处理"]
G --> H["标记会话状态 idle"]
出站投递与通道绑定
- 绑定投递路由
- 基于目标会话键查询活动绑定,若存在唯一绑定则直接投递;否则回退并返回原因(如缺少目标会话、无活动绑定、请求者缺失导致歧义)。
- 出站运行时与通道插件
- 出站运行时负责将消息负载分发至具体通道;通道插件通过轻量加载器按需导入,降低启动成本。
sequenceDiagram
participant DIS as "派发"
participant ROUTER as "绑定投递路由"
participant BIND as "会话绑定服务"
participant RUNTIME as "出站运行时"
participant ADAPTER as "通道适配器"
DIS->>ROUTER : "解析目标会话键"
ROUTER->>BIND : "列出活动绑定"
BIND-->>ROUTER : "返回匹配结果"
alt 唯一绑定
ROUTER-->>RUNTIME : "bound 模式"
else 多个或缺失
ROUTER-->>RUNTIME : "fallback 模式(带原因)"
end
RUNTIME->>ADAPTER : "调用通道插件发送"
上下文引擎与历史记录
- 上下文引擎接口
- 定义 bootstrap/ingest/ingestBatch/afterTurn/assemble/compact 等生命周期方法,支撑历史导入、消息摄取、回合后处理、上下文组装与压缩。
- 记忆与检索
- 内存索引管理器提供向量与全文混合检索、批处理与只读数据库恢复能力;支持会话级增量同步与缓存统计。
classDiagram
class ContextEngine {
+info : ContextEngineInfo
+bootstrap(params) BootstrapResult
+ingest(params) IngestResult
+ingestBatch(params) IngestBatchResult
+afterTurn(params) void
+assemble(params) AssembleResult
+compact(params) CompactResult
+prepareSubagentSpawn(params) SubagentSpawnPreparation
+onSubagentEnded(params) void
+dispose() void
}
class MemoryIndexManager {
+search(query, opts) MemorySearchResult[]
+sync(params) void
+readFile(params) {text,path}
+status() MemoryProviderStatus
+probeEmbeddingAvailability() MemoryEmbeddingProbeResult
+close() void
}
ContextEngine <.. MemoryIndexManager : "配合使用"
数据验证、清洗与格式化
- 配置校验与错误格式化
- 对 AJV 校验错误进行统一格式化,支持去重与友好提示,便于定位问题。
- 配置模式回归测试
- 覆盖通道启用、IMessage 远端主机安全限制、附件根路径等典型场景,确保配置安全与兼容。
- Google 模型 Schema 清洗
- 针对不支持关键字进行扫描与清洗,保证与特定模型的兼容性。
- TUI 与会话状态
- TUI 状态访问器维护当前会话键、会话 ID、聊天运行 ID 等,确保界面与后台状态一致。
flowchart TD
CFG["配置对象"] --> VALIDATE["AJV 校验"]
VALIDATE --> |通过| OK["通过"]
VALIDATE --> |失败| FORMAT["格式化错误信息"]
FORMAT --> REPORT["输出可诊断错误"]
SCHEMA["模型 Schema"] --> CLEAN["扫描不支持关键字"]
CLEAN --> PATCH["清洗/替换"]
PATCH --> READY["可用 Schema"]
数据缓存策略、持久化与一致性
- 会话存储缓存
- 使用 Map 缓存会话存储对象与序列化字符串,支持 TTL 过期与 mtime/size 变更失效,避免重复加载。
- 内存索引缓存
- 管理器内部维护索引实例缓存与等待中的创建 Promise,避免并发重复初始化;提供批量失败计数与只读数据库恢复。
- 定时任务存储字段迁移
- 在配置迁移中对字段进行安全移动与去重,确保向后兼容与一致性。
flowchart TD
LOAD["读取会话存储"] --> CACHE_HIT{"缓存命中且有效?"}
CACHE_HIT --> |是| RETURN["返回缓存副本"]
CACHE_HIT --> |否| LOAD_DISK["从磁盘加载"]
LOAD_DISK --> WRITE_CACHE["写入缓存(TTL/mtime/size)"]
WRITE_CACHE --> RETURN
subgraph "内存索引"
IDX_GET["获取索引管理器"] --> IDX_CACHE{"缓存/等待中?"}
IDX_CACHE --> |缓存| USE["使用现有实例"]
IDX_CACHE --> |等待中| WAIT["等待创建完成"]
IDX_CACHE --> |无| CREATE["创建新实例并缓存"]
end
依赖关系分析
- 组件耦合与内聚
- 入站信封构建器与派发逻辑高内聚,共同完成消息标准化与路由决策。
- 出站运行时与通道插件解耦,通过轻量加载器实现按需导入,降低耦合度。
- 会话键解析与存储缓存紧密耦合,保证状态一致性与性能。
- 外部依赖与集成点
- 通道插件注册表与适配器加载器提供统一扩展点。
- 配置校验与模式回归测试确保输入安全与兼容性。
- 循环依赖风险
- 当前模块间通过函数与接口解耦,未见明显循环依赖迹象。
graph LR
IN_ENVELOPE["入站信封"] --> DISPATCH["派发"]
DISPATCH --> ROUTER["绑定路由"]
ROUTER --> DELIVER["出站运行时"]
DELIVER --> PLUGIN["通道插件"]
DISPATCH --> SESSION["会话键解析"]
SESSION --> CACHE["会话缓存"]
DISPATCH --> CTX["上下文引擎"]
CTX --> MEM["内存索引"]
CFG["配置校验"] --> DISPATCH
性能考量
- 缓存与并发
- 会话存储缓存采用 TTL 与文件元信息校验,减少磁盘访问;内存索引管理器缓存实例与等待中的创建 Promise,避免重复初始化。
- 批处理与只读恢复
- 内存索引管理器支持批处理嵌入与失败计数,遇到只读数据库错误时自动重建连接并重试,提升稳定性。
- 去抖与路由优化
- 入站去抖策略减少无效负载;绑定路由在唯一绑定时直接投递,降低分支判断开销。
故障排查指南
- 配置校验失败
- 使用统一错误格式化输出,定位额外属性、路径与消息内容,结合模式回归测试用例快速定位问题。
- 通道绑定失败
- 检查目标会话键是否存在活动绑定;若缺失或歧义,路由将回退并返回原因(如缺少目标会话、无活动绑定、请求者缺失导致歧义)。
- 会话状态异常
- 关注派发前后的状态标记(processing/idle)与重复消息跳过记录,核对会话键解析与存储缓存一致性。
- 内存检索异常
- 观察只读数据库恢复次数与最后错误,必要时重建索引或调整批处理配置。
通信模式
OpenClaw 的通信层主要由以下部分组成:
- 协议定义:统一的帧模型与参数 Schema,定义了连接、请求、响应与事件三类帧,以及各方法的参数与结果类型。
- 服务器端:WebSocket 握手与认证、事件广播、节点订阅管理。
- 客户端:跨平台(iOS/macOS/Android)的 WebSocket 客户端实现与帧解析。
- 文档与测试:协议版本说明、默认令牌认证测试用例等。
graph TB
subgraph "协议层"
P1["frames.ts<br/>连接/请求/响应/事件帧定义"]
P2["protocol-schemas.ts<br/>协议版本与Schema集合"]
end
subgraph "服务端"
S1["握手与认证<br/>message-handler.ts"]
S2["事件广播<br/>server-broadcast.ts"]
S3["节点订阅管理<br/>server-node-subscriptions.ts"]
end
subgraph "客户端"
C1["通用客户端<br/>client.ts"]
C2["macOS 模型<br/>GatewayModels.swift"]
C3["Swift 客户端通道<br/>GatewayChannel.swift"]
end
P1 --> S1
P2 --> S1
S1 --> S2
S1 --> S3
S2 --> C1
S2 --> C3
S3 --> C1
S3 --> C3
C1 --> P1
C3 --> P1
C2 --> P1
核心组件
- 帧模型与协议版本
- 连接参数、Hello 响应、请求/响应帧、事件帧与错误形状在帧定义文件中统一声明,并通过协议版本常量对外暴露。
- 协议版本号在协议 Schema 中集中定义,用于握手阶段的协商与兼容性校验。
- 服务器握手与认证
- 严格校验首帧是否为连接请求,校验连接参数合法性;进行协议版本协商;执行浏览器来源检查;完成设备身份与令牌校验;必要时触发配对流程。
- 广播与事件推送
- 服务器根据事件作用域过滤目标连接,按缓冲区状态选择丢弃或关闭慢消费者,支持定向广播与全量广播。
- 节点订阅管理
- 提供节点级订阅、会话级订阅、向所有订阅者与所有已连接节点广播的能力,支持清理与批量发送。
- 客户端实现
- 通用客户端封装 WebSocket、设备身份与令牌加载、协议版本与帧校验;跨平台 Swift 客户端负责解码与事件分发。
架构总览
下图展示了从客户端发起连接到服务器完成认证与事件分发的整体流程,以及广播与订阅模块的交互。
sequenceDiagram
participant Client as "客户端"
participant WS as "WebSocket 服务器"
participant Auth as "认证与配对"
participant Sub as "订阅管理"
participant Broad as "事件广播"
Client->>WS : "连接请求(携带连接参数)"
WS->>WS : "校验首帧与连接参数"
WS->>WS : "协议版本协商"
WS->>Auth : "设备身份/令牌/来源校验"
Auth-->>WS : "认证结果(允许/拒绝)"
alt "需要配对"
WS-->>Client : "返回配对所需错误"
WS->>Auth : "触发配对流程"
Auth-->>WS : "配对结果"
end
WS-->>Client : "Hello 响应(含协议/特性/快照)"
Client->>WS : "后续请求(req)"
WS->>WS : "路由到对应处理器"
WS-->>Client : "响应(res)"
WS->>Sub : "注册/查询订阅"
WS->>Broad : "广播事件(event)"
Broad-->>Client : "事件推送"
详细组件分析
WebSocket 握手与认证流程
- 首帧校验:必须是连接请求,且连接参数通过 Schema 校验。
- 协议版本协商:客户端声明 min/maxProtocol,服务器检查是否包含当前协议版本;不匹配则拒绝并关闭连接。
- 浏览器来源检查:根据配置与请求头决定是否强制校验 Origin;支持 Host 头回退的安全提示。
- 设备身份与令牌校验:校验设备公钥、签名时间窗口、随机数一致性;生成/校验设备令牌;角色与作用域解析与绑定。
- 配对流程:若设备未配对或权限升级,触发配对请求;本地受信环境可静默批准;否则等待人工审批。
- Hello 响应:返回协议版本、服务器信息、特性列表、快照与可选认证信息。
flowchart TD
Start(["开始握手"]) --> First["校验首帧为连接请求"]
First --> Params["校验连接参数Schema"]
Params --> Version["协议版本协商"]
Version --> Origin["浏览器来源检查"]
Origin --> Device["设备身份/令牌校验"]
Device --> Pair{"是否需要配对?"}
Pair --> |是| PairReq["触发配对请求/静默批准"]
Pair --> |否| Hello["发送Hello响应"]
PairReq --> PairRes{"配对结果"}
PairRes --> |同意| Hello
PairRes --> |拒绝| Close["关闭连接"]
Hello --> End(["完成握手"])
Close --> End
事件驱动架构与消息传递
- 帧类型:请求(req)、响应(res)、事件(event),统一通过网关帧联合类型承载。
- 订阅发布:节点订阅管理维护节点与会话的订阅映射,支持按会话或全部订阅者广播。
- 广播策略:按事件作用域过滤目标连接;当连接缓冲区过大时,可选择丢弃或关闭慢消费者,保障整体稳定性。
classDiagram
class NodeSubscriptionManager {
+subscribe(nodeId, sessionKey) void
+unsubscribe(nodeId, sessionKey) void
+unsubscribeAll(nodeId) void
+sendToSession(sessionKey, event, payload, sendEvent) void
+sendToAllSubscribed(event, payload, sendEvent) void
+sendToAllConnected(event, payload, listConnected, sendEvent) void
+clear() void
}
class GatewayBroadcaster {
+broadcast(event, payload, opts) void
+broadcastToConnIds(event, payload, connIds, opts) void
}
NodeSubscriptionManager <.. GatewayBroadcaster : "配合使用"
客户端-服务器通信与跨平台实现
- 通用客户端:封装 WebSocket 连接、设备身份与令牌加载、协议版本与帧校验,支持 pending 请求队列与响应分发。
- macOS 模型:定义节点配对、重命名、调用等参数结构,便于序列化与跨语言互操作。
- Swift 客户端通道:解析网关帧、处理响应与事件、维护待确认请求、处理心跳与序列号断层检测。
sequenceDiagram
participant Swift as "Swift 客户端通道"
participant Net as "网络层"
participant Gate as "网关服务器"
Swift->>Net : "建立WebSocket连接"
Net-->>Swift : "接收Hello/事件"
Swift->>Gate : "发送请求(req)"
Gate-->>Swift : "返回响应(res)"
Swift->>Swift : "解析事件(event)<br/>更新序列号/心跳"
节点间通信与远程访问
- 节点命令白名单:节点连接时根据平台与设备型号解析命令允许清单,仅保留允许的命令。
- 远程节点元数据:记录远端节点信息与能力,支持远程技能与资源的发现与使用。
- 会话与存在性:节点连接时更新存在性记录,便于远程侧感知节点在线状态。
安全传输与身份验证
- 设备签名验证:校验设备公钥、签名时间窗口与随机数,确保连接方身份可信。
- 来源校验:浏览器来源检查,支持 Host 头回退的安全提示与配置开关。
- 令牌与配对:设备令牌生成与轮换、设备配对审批,支持静默批准与人工审批两种模式。
- 默认令牌认证测试:覆盖协议不匹配、非连接首帧、设备认证必需等场景。
协议版本管理与向后兼容
- 协议版本:当前协议版本在协议 Schema 中集中定义,握手阶段双方进行 min/max 协商。
- 向后兼容:文档明确桥接协议为隐式 v1,预期向后兼容;任何破坏性变更前需增加协议版本字段。
- 版本不匹配处理:服务器拒绝并关闭连接,返回协议不匹配错误。
依赖关系分析
- 协议层依赖:服务器与客户端均依赖统一的帧定义与 Schema 校验,保证消息结构一致。
- 服务器内部:握手处理依赖认证、配对、来源检查、节点命令白名单与存在性记录;广播与订阅模块独立但被握手与业务逻辑调用。
- 客户端依赖:通用客户端依赖协议定义与设备身份/令牌存储;跨平台 Swift 客户端依赖网关帧解码与事件处理。
graph LR
Frames["frames.ts"] --> MH["message-handler.ts"]
Proto["protocol-schemas.ts"] --> MH
MH --> Broad["server-broadcast.ts"]
MH --> Sub["server-node-subscriptions.ts"]
Client["client.ts"] --> Frames
Swift["GatewayChannel.swift"] --> Frames
SwiftModel["GatewayModels.swift"] --> Frames
性能考量
- 缓冲区保护:广播时检测连接缓冲区大小,超过阈值可丢弃或关闭慢消费者,避免内存膨胀。
- 事件作用域过滤:仅向具备相应作用域的连接推送事件,减少无效传输。
- 心跳与序列号:客户端维护事件序列号与心跳时间,检测断层并上报,提升可靠性。
- 节点命令白名单:限制节点声明命令数量,降低服务器处理压力。
故障排查指南
- 握手失败
- 非连接首帧:服务器返回无效握手错误并关闭连接。
- 协议不匹配:检查客户端/服务器协议版本,确保 min/max 范围包含当前版本。
- 浏览器来源不被允许:调整允许来源配置或使用受信上下文。
- 设备身份缺失或签名无效:确认设备公钥、签名时间与随机数正确。
- 认证失败
- 设备令牌或共享令牌无效:重新生成或轮换令牌;检查配对状态。
- 来源校验失败:确保使用受信来源或正确配置允许来源。
- 广播异常
- 慢消费者被关闭:检查客户端处理能力与网络状况;适当降低事件频率。
- 事件未到达:确认事件作用域与订阅关系;核对目标连接状态。
系统设计
OpenClaw 采用多语言混合工程组织方式,核心网关与协议位于 src/gateway 下,配套文档位于 docs 目录,跨平台客户端与节点位于 apps 目录,插件生态位于 extensions 目录。下图给出与系统设计相关的关键目录与职责概览:
graph TB
subgraph "核心网关与协议"
GW["src/gateway/*"]
SCHEMA["src/gateway/protocol/schema.ts"]
end
subgraph "文档与规范"
DOC_EN["docs/concepts/architecture.md"]
DOC_ZH["docs/zh-CN/concepts/architecture.md"]
PROTO_EN["docs/gateway/protocol.md"]
PROTO_ZH["docs/zh-CN/gateway/protocol.md"]
end
subgraph "客户端与节点"
MAC["apps/macos/*"]
IOS["apps/ios/*"]
ANDROID["apps/android/*"]
EXT["extensions/*"]
end
subgraph "应用与工具"
ROOT_README["README.md"]
end
GW --> SCHEMA
DOC_EN --> GW
DOC_ZH --> GW
PROTO_EN --> GW
PROTO_ZH --> GW
MAC --> GW
IOS --> GW
ANDROID --> GW
EXT --> GW
ROOT_README --> GW
核心组件
- 网关控制平面(Gateway Daemon)
- 统一维护各消息平台连接(如 WhatsApp、Telegram、Slack、Discord、Signal、iMessage、WebChat 等),暴露类型化 WebSocket API,并发布事件(agent、chat、presence、health、heartbeat、cron 等)。
- 默认绑定地址为回环地址与指定端口,支持远程访问通过 Tailscale 或 SSH 隧道。
- 客户端与控制平面
- macOS 应用、CLI、Web 管理界面等作为 operator 角色连接网关,执行健康检查、状态查询、消息发送、代理调用等操作。
- 节点(Nodes)
- macOS/iOS/Android/headless 设备以 node 角色连接,声明能力与命令白名单,提供 canvas、camera、screen、location、voice 等能力。
- 协议与类型系统
- 基于 TypeBox 定义协议模式,生成 JSON Schema 与 Swift 模型,确保跨语言一致性与强类型约束。
- 文档与规范
- 英文与中文双语架构与协议文档,覆盖握手、帧格式、版本管理、认证与配对、TLS 固定等细节。
架构总览
OpenClaw 的系统边界清晰:单主机一个网关守护进程负责所有消息通道与控制平面功能;客户端与节点通过同一 WebSocket 服务器进行通信,区分角色与权限范围。下图展示典型连接生命周期与消息流:
sequenceDiagram
participant Client as "客户端(operator)"
participant Gateway as "网关控制平面"
participant Provider as "消息平台(Provider)"
Client->>Gateway : 请求 : connect
Gateway-->>Client : 响应 : ok(包含hello-ok)
Gateway-->>Client : 事件 : presence/heartbeat
Client->>Gateway : 请求 : agent/chat/send
Gateway-->>Client : 响应 : ack(final)
Gateway-->>Client : 事件 : agent(chat/streaming)
Gateway->>Provider : 调用/转发消息
Provider-->>Gateway : 返回结果
Gateway-->>Client : 推送事件/最终结果
详细组件分析
网关协议与帧模型
- 传输与握手
- 使用 WebSocket 文本帧承载 JSON;首个帧必须是 connect 请求;握手阶段由网关下发 connect.challenge,客户端需签名并返回。
- 帧类型
- 请求: {type:"req", id, method, params}
- 响应: {type:"res", id, ok, payload|error}
- 事件: {type:"event", event, payload, seq?, stateVersion?}
- 版本与校验
- 协议版本在 schema 中定义;客户端发送 minProtocol/maxProtocol,服务端拒绝不兼容版本。
- 入站帧按 JSON Schema 校验,错误直接关闭连接。
- 角色与权限
- operator: 控制平面客户端,具备读写/管理/审批/配对等权限范围。
- node: 设备节点,声明能力(caps)、命令(commands)与权限(permissions),服务端进行严格白名单校验。
- 认证与配对
- 支持全局网关令牌;设备首次连接需配对并通过签名挑战;后续颁发设备令牌;支持 TLS 固定证书指纹。
- 事件与幂等
- 事件不重放,客户端需在断连后刷新;有副作用的方法需要幂等键去重缓存。
flowchart TD
Start(["开始: 客户端发起 connect"]) --> Challenge["网关下发 connect.challenge"]
Challenge --> Sign["客户端签名挑战并返回 connect"]
Sign --> Verify{"验证通过?"}
Verify --> |否| Close["关闭连接"]
Verify --> |是| Hello["网关返回 hello-ok(含协议版本/策略)"]
Hello --> Ready["建立会话: 可发送请求/订阅事件"]
Ready --> Request["客户端发送请求(req)"]
Request --> Response["网关返回响应(res)"]
Ready --> Event["网关推送事件(event)"]
Event --> Ready
Response --> Ready
类型系统与代码生成
- TypeBox 模式定义协议字段与约束,生成 JSON Schema 与 Swift 模型,保证跨语言一致性与强类型校验。
- schema.ts 导出各类协议模式(agent、channels、config、cron、devices、frames、nodes、sessions 等)。
classDiagram
class SchemaIndex {
+导出 : agent
+导出 : channels
+导出 : config
+导出 : cron
+导出 : devices
+导出 : frames
+导出 : logs-chat
+导出 : nodes
+导出 : protocol-schemas
+导出 : push
+导出 : secrets
+导出 : sessions
+导出 : snapshot
+导出 : types
+导出 : wizard
}
网关服务器与启动入口
- server.ts 提供网关服务器的对外接口与启动函数,隐藏实现细节,便于测试与复用。
- 结合 README 与概念文档,网关默认绑定回环地址与端口,支持远程访问与 TLS 固定。
客户端并发连接与重试保障
- 测试用例验证了并发 connect 的单飞行(single-flight)行为:多个并发连接共享一次握手,失败时同步传播,避免重复握手与资源浪费。
- 这体现了网关在高并发场景下的稳定性与一致性保障。
事件驱动与消息传递机制
- 网关通过 WebSocket 向客户端推送事件(agent、chat、presence、health、heartbeat、cron 等),客户端据此刷新 UI 或继续发起请求。
- 协议明确事件不重放,客户端需在断连后主动刷新状态,确保最终一致。
分层架构与组件职责
- 表现层(客户端)
- macOS 应用、CLI、Web 管理界面、WebChat UI 等,负责用户交互与命令下发。
- 控制层(网关)
- 统一接入与编排消息平台,提供类型化 API、事件分发、鉴权与配对、会话管理。
- 数据与能力层(节点)
- 设备侧能力(canvas、camera、screen、location、voice 等),通过 node 角色声明与授权。
- 插件与扩展层(extensions)
- 丰富渠道与工具链,遵循协议与权限模型。
系统边界与集成点
- 系统边界
- 单主机一网关:每台主机仅运行一个网关守护进程,统一维护 Baileys WhatsApp 会话。
- 远程访问:通过 Tailscale Serve/Funnel 或 SSH 隧道,保持网关绑定回环地址不变。
- 集成点
- WebSocket 控制平面:所有客户端与节点共用同一网关 WS 服务。
- HTTP Canvas/A2UI:网关内置 HTTP 服务提供可视化工作区。
- 外部渠道:通过各平台 SDK/HTTP API 与网关对接。
WebSocket 协议设计选择与实现要点
- 设计选择
- 以 WebSocket 作为统一传输层,满足长连接、低延迟、事件推送需求;文本帧 JSON 化便于调试与跨语言处理。
- 首帧强制 connect,确保握手与鉴权前置,降低未授权连接风险。
- 实现要点
- 握手挑战签名、设备身份与配对、角色与权限白名单、TLS 固定、版本协商、幂等键去重、事件不重放。
- 与媒体/语音场景的结合
- 语音通话扩展模块中,存在 WebSocket 升级的限流与清理逻辑,体现对连接密度与资源占用的控制。
依赖关系分析
- 协议到实现
- schema.ts 定义协议模式,协议文档与测试共同约束实现行为(如 connect 流程、角色权限、事件语义)。
- 客户端到网关
- 客户端并发连接测试表明网关在握手阶段即进行去重与一致性控制。
- 网关到外部
- 网关通过远程隧道与 TLS 固定,确保远端访问的安全性与稳定性。
graph LR
Client["客户端(operator/node)"] --> WS["WebSocket 控制平面"]
WS --> Gateway["网关控制平面"]
Gateway --> Providers["消息平台(Provider)"]
Gateway --> HTTP["HTTP Canvas/A2UI"]
Gateway --> Ext["插件/扩展"]
性能考虑
- 连接与握手
- 单飞行并发连接减少握手开销,避免重复握手导致的资源浪费。
- 事件与消息
- 事件不重放,客户端需主动刷新,降低服务端状态存储压力;请求/响应模式适合高吞吐场景。
- 远程访问
- Tailscale/SSH 隧道与 TLS 固定在保证安全的同时,尽量减少额外加密开销;建议在网关侧启用必要的压缩与缓冲策略(依据部署环境)。
- 幂等与去重
- 幂等键去重缓存降低重复请求带来的副作用与计算开销。
组件关系
OpenClaw 采用多模块分层组织:网关负责请求接入与方法路由;插件系统承载扩展能力;通道适配器抽象不同即时通讯平台;工具与代理围绕会话与消息处理;SDK 提供统一的对外接口与类型约束。下图概览主要模块与文件位置:
graph TB
subgraph "网关层"
GW_IMPL["gateway/server.impl.ts"]
GW_METHODS["gateway/server-methods.ts"]
GW_WS["gateway/server.ws.ts"]
GW_CLIENT["gateway/client.ts"]
end
subgraph "插件系统"
PL_LOADER["plugins/loader.ts"]
PL_RUNTIME["plugins/runtime/index.ts"]
PL_RT_SCOPE["plugins/runtime/gateway-request-scope.ts"]
PL_RT_CHAN["plugins/runtime/runtime-channel.ts"]
PL_RT_CFG["plugins/runtime/runtime-config.ts"]
PL_RT_EVT["plugins/runtime/runtime-events.ts"]
PL_RT_LOG["plugins/runtime/runtime-logging.ts"]
PL_RT_MEDIA["plugins/runtime/runtime-media.ts"]
PL_RT_SYS["plugins/runtime/runtime-system.ts"]
PL_RT_TOOLS["plugins/runtime/runtime-tools.ts"]
end
subgraph "通道与SDK"
CH_TYPES["channels/plugins/types.ts"]
CH_ADAPTERS["channels/plugins/types.adapters.ts"]
CH_CORE["channels/plugins/types.core.ts"]
SDK_IDX["plugin-sdk/index.ts"]
AGT_TOOLS["agents/channel-tools.ts"]
end
subgraph "客户端"
IOS["OpenClawKit/GatewayChannel.swift"]
WEB["ui/gateway.ts"]
end
GW_IMPL --> GW_METHODS
GW_METHODS --> GW_WS
GW_WS --> GW_CLIENT
GW_IMPL --> PL_LOADER
PL_LOADER --> PL_RUNTIME
PL_RUNTIME --> PL_RT_SCOPE
PL_RUNTIME --> PL_RT_CHAN
PL_RUNTIME --> PL_RT_CFG
PL_RUNTIME --> PL_RT_EVT
PL_RUNTIME --> PL_RT_LOG
PL_RUNTIME --> PL_RT_MEDIA
PL_RUNTIME --> PL_RT_SYS
PL_RUNTIME --> PL_RT_TOOLS
CH_TYPES --> CH_ADAPTERS
CH_TYPES --> CH_CORE
SDK_IDX --> CH_TYPES
SDK_IDX --> PL_RUNTIME
AGT_TOOLS --> CH_TYPES
IOS --> GW_CLIENT
WEB --> GW_CLIENT
核心组件
- 网关(Gateway)
- 负责 WebSocket 连接、认证握手、方法授权与路由、速率限制、健康检查与事件广播。
- 关键实现:服务初始化、方法注册、请求处理与作用域隔离。
- 插件系统(Plugin System)
- 动态加载、注册与诊断;提供运行时环境(配置、系统、媒体、TTS/STT、工具、通道、事件、日志、状态)。
- 支持请求作用域内的子代理调用与回注。
- 通道(Channel)
- 抽象各即时通讯平台的能力边界(适配器、核心类型、消息动作、线程、目录、安全策略等)。
- 通过 SDK 暴露统一接口,支持工具聚合与代理集成。
- 工具(Tool)
- 由插件注册或通道提供,面向代理执行;支持命令式与模型驱动式两类。
- 客户端(Client)
- 包括 iOS 与 Web 客户端,负责连接、重连、事件处理与帧解析。
架构总览
下图展示从客户端到网关、再到插件运行时与通道适配器的整体交互路径,以及方法授权、速率限制与请求作用域的关键节点。
sequenceDiagram
participant C as "客户端<br/>iOS/Web"
participant WS as "WebSocket 服务器<br/>server.ws.ts"
participant GW as "网关核心<br/>server-methods.ts"
participant REG as "插件注册表<br/>loader.ts"
participant RT as "插件运行时<br/>runtime/index.ts"
participant CH as "通道适配器<br/>types.adapters.ts"
C->>WS : 建立连接/认证
WS->>GW : 分发请求含方法、参数、角色与范围
GW->>GW : 授权校验/速率限制
GW->>REG : 查找/调用处理器
REG-->>GW : 处理器返回
GW->>RT : 请求作用域内执行子代理可用
RT->>CH : 通道能力调用发送/解析/线程/目录/安全
CH-->>RT : 结果/状态
RT-->>GW : 处理结果
GW-->>C : 返回响应/事件
详细组件分析
网关组件(Gateway)
- 初始化与方法装配
- 在启动时构建默认代理工作区、收集基础与通道方法、合并去重后形成最终方法集。
- 加载插件注册表与网关方法,建立通道日志与运行时环境映射。
- 请求处理与授权
- 统一入口函数对方法进行角色与范围授权校验,写入控制面预算并进行速率限制。
- 在请求作用域中执行处理器,确保子代理调用可回注到网关。
- 客户端交互
- 客户端选项包含令牌、实例标识、角色与权限、协议版本、事件回调等。
- 客户端侧维护连接状态、重连退避与挂起队列,关闭时清理并触发重连策略。
flowchart TD
Start(["启动网关"]) --> Init["解析配置/默认代理ID<br/>构建方法集合"]
Init --> LoadPlugins["加载插件注册表与方法"]
LoadPlugins --> BuildEnv["构建通道日志与运行时环境"]
BuildEnv --> Ready["就绪:等待请求"]
Ready --> Req["接收请求"]
Req --> Auth{"授权/范围校验"}
Auth --> |失败| Err["返回错误"]
Auth --> |通过| Rate{"速率限制"}
Rate --> |超限| RL["返回限流错误"]
Rate --> |允许| Scope["进入请求作用域"]
Scope --> Exec["调用处理器"]
Exec --> Done(["返回响应"])
Err --> Done
RL --> Done
插件系统组件(Plugin System)
- 注册与加载
- 懒加载运行时以避免启动路径中预热所有通道依赖;通过代理访问运行时属性,延迟初始化。
- 激活注册表并初始化全局钩子运行器;对未跟踪加载的插件发出诊断警告。
- 运行时能力
- 提供版本、配置、系统、媒体、TTS/STT、工具、通道、事件、日志、状态等子模块。
- 子代理方法仅在请求作用域内可用,否则抛出不可用错误。
- 请求作用域
- 将处理器执行包裹在请求作用域中,使插件运行时可在工具执行期间回注子代理调用。
classDiagram
class PluginRuntime {
+version
+config
+system
+media
+tts
+stt
+tools
+channel
+events
+logging
+state
}
class RuntimeChannel
class RuntimeConfig
class RuntimeEvents
class RuntimeLogging
class RuntimeMedia
class RuntimeSystem
class RuntimeTools
PluginRuntime --> RuntimeChannel : "通道能力"
PluginRuntime --> RuntimeConfig : "配置"
PluginRuntime --> RuntimeEvents : "事件"
PluginRuntime --> RuntimeLogging : "日志"
PluginRuntime --> RuntimeMedia : "媒体"
PluginRuntime --> RuntimeSystem : "系统"
PluginRuntime --> RuntimeTools : "工具"
通道与工具组件(Channel & Tool)
- 类型与适配器
- 通道类型定义包括账户快照、能力、线程、目录、安全策略、消息动作、轮询等。
- 适配器定义登录/登出、心跳、目录解析、消息发送、状态采集等能力接口。
- 工具聚合
- 聚合各通道提供的工具清单,支持按配置动态生成工具列表。
- SDK 对外暴露
- SDK 汇总导出通道类型、适配器、工具、状态辅助、Webhook 等能力,便于插件与外部扩展使用。
classDiagram
class ChannelPlugin {
+id
+meta
+gatewayMethods
+agentTools
}
class ChannelGatewayAdapter {
+startAccount()
+stopAccount()
+loginWithQrStart()
+loginWithQrWait()
+logoutAccount()
}
class ChannelOutboundAdapter {
+deliveryMode
+resolveTarget()
+sendPayload()
+sendText()
+sendMedia()
+sendPoll()
}
class ChannelMessageActionAdapter {
+listActions()
+supportsAction()
+extractToolSend()
+handleAction()
}
ChannelPlugin --> ChannelGatewayAdapter : "网关适配"
ChannelPlugin --> ChannelOutboundAdapter : "发送适配"
ChannelPlugin --> ChannelMessageActionAdapter : "消息动作"
客户端组件(Client)
- iOS 客户端
- 解析帧类型,区分响应与事件;维护挂起队列与序列号;处理心跳与断线间隙检测。
- Web 客户端
- 启动/停止连接、打开事件、消息事件、关闭事件;关闭时清理挂起请求并按指数退避重连。
sequenceDiagram
participant IOS as "iOS 客户端"
participant WEB as "Web 客户端"
participant GW as "网关"
IOS->>GW : 建立连接/认证
IOS->>IOS : 解析帧/维护挂起队列
IOS->>GW : 发送请求
GW-->>IOS : 返回响应/事件
WEB->>GW : 建立连接
WEB->>WEB : 监听 open/message/close
WEB->>GW : 发送请求
GW-->>WEB : 返回响应/事件
WEB->>WEB : 关闭时清理并重连
依赖分析
- 组件耦合
- 网关对插件系统的依赖:方法装配、插件注册表激活、运行时作用域。
- 插件系统对通道适配器的依赖:通过运行时通道模块调用具体平台能力。
- 通道类型与适配器:类型定义与能力接口解耦,便于扩展新通道。
- 外部依赖与集成点
- 客户端通过 WebSocket 与网关通信;网关内部通过请求作用域隔离插件运行时。
- 循环依赖
- 当前结构以“网关→插件→通道”单向依赖为主,未见明显循环。
graph LR
GW["网关"] --> PL["插件系统"]
PL --> RT["运行时子模块"]
RT --> CH["通道适配器"]
GW --> CL["客户端"]
性能考量
- 启动优化
- 插件懒加载减少冷启动时间;仅在需要时初始化运行时对象。
- 请求处理
- 方法授权与速率限制在入口集中处理,避免重复校验。
- 请求作用域隔离减少上下文污染,提升并发稳定性。
- 通道能力
- 通道适配器按需调用,避免不必要的网络往返;文本分块与媒体处理在运行时模块内完成。