OpenClaw 架构总览:网关、Agent、渠道、节点、插件五层各管什么,出问题该往哪查
排查 OpenClaw 的问题,最费时间的往往不是修,而是找。消息没回,可能是渠道插件没装、网关没起来、Agent 那一轮被队列挡住了,也可能是节点根本没配对上。这几种情况的日志长得都不一样,但如果心里没有一张分层图,就只能一个个试。
这篇把官方架构文档里的层次关系拆开讲:谁拥有什么、谁跟谁用什么协议说话、一条消息从进来到回复要穿过哪几层。读完之后再遇到问题,至少能先判断该去哪一层看。
先说一个贯穿全篇的前提:一台主机上只有一个网关(Gateway)。文档把它写进了不变量(Invariants):一个网关独占该主机上的单个 Baileys 会话(WhatsApp 的底层库)。你在这台机器上看到的所有连接、所有渠道、所有 Agent 运行,都归这一个长驻进程管。很多”两边行为不一致”的怪现象,根子就是无意中起了第二份。
网关:唯一拥有对外连接的那一层
网关是个守护进程,职责在文档里说得很直白:
- 维持各家消息平台的连接(WhatsApp 走 Baileys、Telegram 走 grammY,以及 Slack、Discord、Signal、iMessage、WebChat);
- 对外暴露一套有类型的 WebSocket API,分请求、响应、服务端推送事件三类;
- 对进来的帧做 JSON Schema 校验;
- 往外发
agent、chat、presence、health、heartbeat、cron这些事件。
它默认绑在 127.0.0.1:18789。同一个端口上还挂着网关的 HTTP 服务,用来托管 canvas:/__openclaw__/canvas/(Agent 可编辑的 HTML/CSS/JS)和 /__openclaw__/a2ui/(A2UI 宿主)。所以端口冲突这类问题会同时打掉 WS 和 canvas 两块,不用当成两件事查。
启动与运维在文档里也就三条:openclaw gateway 前台启动、日志走 stdout;健康检查用 WS 上的 health(hello-ok 里也带一份);自动重启交给 launchd 或 systemd。网关起不来的那一类问题(锁文件、端口、后台进程)另有专门的排查路径,可以看 网关起不来怎么查。
客户端和节点:同一个 WS 端口,两种 role
这是最容易混的一处。控制面客户端(macOS 应用、CLI、Web 管理界面、自动化)和节点(macOS/iOS/Android/无头设备)连的是同一个 WebSocket 服务器,区别在 connect 时声明的角色。
| 连接方 | 声明 | 典型请求 / 命令 | 订阅事件 |
|---|---|---|---|
| 控制面客户端 | 默认操作者身份 | health、status、send、agent、system-presence | tick、agent、presence、shutdown |
| 节点 | role: "node" + caps/commands/permissions | canvas.*、camera.*、screen.record、location.get | 同一套 WS 事件 |
节点文档里有一句定性很关键:节点是外设,不是网关。它们不跑网关服务,渠道消息(Telegram、WhatsApp 等)落在网关上,不会落到节点上。所以”手机上没收到群消息”这种描述,方向从一开始就错了——节点提供的是设备能力(画布、摄像头、屏幕录制、定位),不是消息入口。
握手规则同样是硬的:传输是 WebSocket 文本帧、载荷 JSON,第一帧必须是 connect,任何非 JSON 或非 connect 的首帧会被直接硬关闭。握手之后请求是 {type:"req", id, method, params},响应是 {type:"res", id, ok, payload|error},事件是 {type:"event", event, payload, seq?, stateVersion?}。
有副作用的方法(send、agent)要求带幂等键才能安全重试,服务端保留一份短时去重缓存。这条值得记住:重试逻辑写错了,重复发消息不是平台的锅。
认证方面文档列了几种模式:共享密钥走 connect.params.auth.token 或 connect.params.auth.password;带身份的模式(gateway.auth.allowTailscale: true 的 Tailscale Serve,或非环回的 gateway.auth.mode: "trusted-proxy")从请求头满足认证,不再走 connect.params.auth.*;gateway.auth.mode: "none" 完全关掉共享密钥认证,文档明确要求这种模式别挂在公开或不可信入口上。
配对:为什么本机能连、局域网连不上
配对是一套独立机制,和上面的网关认证并行,两者都要过。文档写得很细:
- 所有 WS 客户端(操作者和节点都算)在
connect时带设备身份; - 新设备 ID 需要配对批准,通过后网关签发设备令牌供后续连接使用;
- 直连本机环回可以自动批准,为的是同主机体验顺畅;
- Tailnet 和局域网连接,包括同主机的 tailnet 绑定,仍然要显式批准;
- 所有连接都要对
connect.challenge随机数签名,签名载荷 v3 还会绑定platform和deviceFamily,网关在重连时会钉住已配对的元数据,元数据变了需要重新配对修复; - 网关认证(
gateway.auth.*)对所有连接都生效,本地远程一视同仁。
“我本机好好的,换台机器就连不上”——绝大多数时候不是配置错了,是这条自动批准边界。节点侧还多一层:待批准的配对请求在设备最后一次重试后 5 分钟过期,而且节点有独立的 node.pair.* 存储记录已批准的命令面,它不管传输认证,传输认证归设备配对管。两个存储、两套语义,查的时候别串。
远程访问文档给的顺序是:优先 Tailscale 或 VPN;备选 SSH 隧道。
ssh -N -L 18789:127.0.0.1:18789 user@gateway-host
隧道之上握手和认证令牌照旧生效,远程场景还可以给 WS 开 TLS 和可选的证书固定。
渠道:几乎每个平台都是一个插件
渠道这一层的实现形态,是新手最容易估错的地方。官方渠道目录把每个条目标了归属:included in core(如 WebChat)、bundled plugin(如 Telegram、Reef)、official plugin(Discord、Slack、Signal、飞书、QQ 机器人等一大批)、external plugin(微信、企业微信、元宝等)。
后两类的安装动作是明确的:官方插件用一条命令装,openclaw plugins install @openclaw/<id>,也可以在 openclaw onboard / openclaw channels add 过程中按需安装,装完需要重启网关。这就解释了一类高频现象:配置改了、插件装了,渠道还是没上线——网关没重启,插件没加载。
其余几条渠道层规则:多个渠道可以同时跑,OpenClaw 按会话路由;文档说最快上手的一般是 Telegram(只要 bot token,不用装插件),而 WhatsApp 需要扫码配对、在磁盘上留的状态更多。渠道接入的通用流程见 渠道接入的通用流程与配对机制。
Agent:一次运行发生在哪一层
消息进来之后,真正”干活”的是 Agent 运行。它的入口是网关的 agent RPC(CLI 侧是 openclaw agent)。文档给的顺序是:agent 校验参数、解析会话、持久化会话元数据,然后立刻返回 { runId, acceptedAt }——注意,返回不等于跑完。想等结果要用 agent.wait,它等的是这个 runId 上的 lifecycle end/error 事件,返回 { status: ok|error|timeout, startedAt, endedAt, error? }。
运行过程中,运行时事件被桥接成三条流:工具事件进 stream: "tool",助手增量进 stream: "assistant",生命周期进 stream: "lifecycle"(phase 为 start/end/error)。你在客户端看到的流式输出,就是这几条流。
并发上文档写得很硬:运行按会话键串行(会话通道),还可以再过一条全局通道,以此避免工具与会话竞态。转录写入用的是写者声明机制——被准入的运行会记下持久的 activeWriterRunId,每次转录追加或重写都要带 expectedWriterRunId,提交事务里校验它是否仍是当前声明,被顶替的运行因此提交不了过期数据。此外还有网关状态目录锁,防止另一个网关或 openclaw agent --local 进程同时占用同一个状态目录。Agent 主循环的完整拆解见 Agent 主循环怎么转。
插件:横切在网关和 Agent 两层
插件不是第六层,而是切进前面几层的扩展点。文档给的能力(capability)模型是:每个原生插件对一种或多种能力类型做注册,比如文本推理用 api.registerProvider(...)、渠道用 api.registerChannel(...)、语音用 api.registerSpeechProvider(...)、网关发现用 api.registerGatewayDiscoveryService(...)。一个能力都不注册、只提供钩子、工具、发现服务或后台服务的插件,属于”仅钩子”的传统形态,文档说明这种模式仍然完全受支持。
钩子分两套,位置不同:**内部钩子(网关钩子)**是事件驱动的脚本,挂在命令和生命周期事件上,比如 agent:bootstrap 在构建引导文件、系统提示定稿之前运行;插件钩子跑在 Agent 循环或网关管线内部,包括 before_model_resolve、before_prompt_build、before_agent_reply、before_tool_call / after_tool_call、agent_end、message_received / message_sending / message_sent、session_start / session_end、gateway_start / gateway_stop 等。
有两条判定规则容易踩坑:before_tool_call 返回 { block: true } 是终结性的,会停掉优先级更低的处理器,而 { block: false } 是空操作,不会清掉之前的拦截;message_sending 的 { cancel: true } / { cancel: false } 同理。指望后置钩子”放行”前置钩子的拦截,是行不通的。插件体系的安装与开发见 插件体系怎么装怎么写。
按症状定位到层
把上面的边界压成一张对照表,出问题时先在这里对号:
| 症状 | 最可能的层 | 先看什么 |
|---|---|---|
| 网关进程根本起不来 | 网关 | 端口 18789 占用、锁文件、是否已有后台进程 |
| 客户端连上就被断开 | 协议 / 握手 | 首帧是不是 connect、载荷是不是合法 JSON |
| 本机能连、局域网或 tailnet 连不上 | 配对 | 是否有待批准的配对请求;非环回连接必须显式批准 |
| 渠道配置了却没上线 | 渠道 / 插件 | 插件是否已安装、装完是否重启了网关 |
| 手机/平板没拿到渠道消息 | 层次误解 | 节点是外设,渠道消息本就落在网关 |
| 提交后拿到 runId 但久无结果 | Agent 运行 | lifecycle 流有没有 end/error;会话通道是否有前一轮在跑 |
| 重试后消息发重了 | 协议 | send / agent 是否带了幂等键 |
| 客户端状态和实际对不上 | 事件语义 | 事件不重放,出现断档必须主动刷新 |
| 两个进程行为互相打架 | 不变量 | 是不是起了第二个网关或 agent --local 抢同一状态目录 |
最后一行值得单独说:文档明确写了事件不重放,客户端遇到序号断档必须自己刷新。所以”界面停在半路”这类现象未必是服务端崩了,可能只是客户端漏了事件又没刷新。
这张图解释不了什么
这套分层是连接与执行的骨架,不是全部。有几块它按下不表:
一是协议的具体契约。架构文档只给了帧格式摘要和几条不变量,方法与事件的完整清单在网关协议文档里。文档还提到协议定义走的是 TypeBox schema 生成 JSON Schema、再由 JSON Schema 生成 Swift 模型这条链路——也就是说,客户端与网关的类型对不上时,源头是 schema,不是手写代码。
二是版本兼容。节点文档说网关的 WebSocket 接受 N-1 协议窗口内的已认证节点客户端:截至 2026-08-17 的文档,v4 网关接受声明了 role: "node" 且 client.mode: "node" 的 v3 节点,而操作者和 UI 会话必须用当前协议。混合版本环境要按这条排升级顺序。
三是模型、记忆、队列策略这些”Agent 内部”的东西。架构文档只把 Agent 运行当成网关上的一类请求来描述,具体到上下文怎么装配、队列怎么调度、记忆怎么存,都是另外的篇幅。
还有一点属于官方文档未说明的范围:网关能承载多少并发连接、多少个渠道同时跑会有什么影响,文档没有给出数字,别按经验拍。真要评估,只能在自己的环境里压。
分层的价值不在于把架构背下来,而在于遇事能少试两轮。下次卡住时先问一句:这个现象归哪一层管——是连接没建立,还是消息没进来,还是运行没跑完。三个方向选一个,日志范围立刻小一大截。
延伸阅读
- 本专题共 40 篇,完整分组目录见专题页
- OpenClaw 的 Agent 循环怎么转:从 agent RPC 到落盘的一整条链路
- OpenClaw 会话模型讲清楚:消息落到哪个 session、主会话汇进来什么、状态怎么不串
本文依据 OpenClaw 官方仓库(github.com/openclaw/openclaw)docs/ 下的官方文档整理,核对日 2026-08-17。
我们没有安装或运行过 OpenClaw,因此不涉及界面外观、操作手感与实测耗时的任何描述;
文中的默认值、命令与配置项均为文档口径,不构成对实际运行结果的保证。
该项目迭代很快,请以仓库最新内容为准。接入即时通讯平台前,请自行确认所在平台的规则与合规要求。