工程主线:从 CLI 到一次回复
这页用“工程主线”的方式串起一次完整链路:一个请求/一条消息 如何走过 OpenClaw 的各层,最终得到可交付的回复。
目标是让你能回答:
- 我现在看到的日志/事件属于哪一层?
- 下一步应该去哪里看(文档 / 方法 / 源码入口)?
最短观测闭环(10 分钟)
先把“可观察”跑通,再读实现更省时间:
- 启动 Gateway 网关:
openclaw gateway- 另开一个终端跟踪日志(文件日志尾随):
openclaw logs --follow- 打开 Control UI 并发起一次对话(或通过任一渠道发一条消息):
openclaw dashboard- 你应该能观察到两类信号:
- 控制面:WS 连接成功后出现
tick/presence等事件(参见 TypeBox)。 - 聊天:
chat.send非阻塞 ACK(返回runId),回复通过chat事件流式回传(参见 Control UI)。
0) 先把控制面搞清楚(WS:connect / subscribe / call)
OpenClaw 的 Control UI 与 CLI 都会通过 Gateway WebSocket:
- 第一个帧必须是
connect - 握手成功后,客户端会持续收到事件流(例如
tick/presence) - 然后再调用方法(例如
chat.send/agent/logs.tail) - 方法通常是非阻塞 ACK,结果通过事件流回传
入口:
端到端链路图(从 connect 到回复)
flowchart TD
A[Control UI / CLI] -->|WS connect| B[Gateway WS 控制面]
B --> C{authorize + dispatch}
C -->|chat.send| D[chat handler]
D --> E[resolve route / sessionKey]
E --> F[enqueue lane: session:<key>]
F --> G[runEmbeddedPiAgent]
G --> H[model + tools]
H --> I[stream chat events]
I --> A
对应的“读源码入口”(建议用 rg 直接搜这些文件名):
- 控制面握手/分发:
src/gateway/server.ts、src/gateway/server/ws-connection/message-handler.ts、src/gateway/server-methods.ts chat.send入口:src/gateway/server-methods/chat.ts- 路由与会话键:
src/config/sessions/session-key.ts、src/gateway/server-session-key.ts - lane/队列:
src/process/command-queue.ts、src/agents/pi-embedded-runner/lanes.ts、src/gateway/server-lanes.ts
1) CLI → Gateway:启动与运行形态
从使用者角度,你通常会通过 CLI 启动/管理 Gateway:
openclaw gateway(启动)openclaw gateway status(检查)openclaw logs --follow(观察运行)
相关文档:
2) Channels → 入站信封:把不同平台“同构化”
不同渠道(WhatsApp/Telegram/Discord/…)在能力与消息形态上差异很大。 OpenClaw 的做法是把它们规范化成共享的入站语义(文本、媒体引用、回复引用上下文等),再进入统一的路由与执行管道。
入口:
3) 路由与会话键:为什么群组不会串线、消息不会乱序
从一条入站消息到一次 agent run,中间最关键的是:
- 解析
agentId(多智能体路由/绑定) - 决定
sessionKey(DM 折叠策略 vs 群组/频道隔离) - 按
sessionKey排队(lane:每会话串行),避免并发写会话导致顺序错乱
入口:
4) agent loop:run → attempt → streaming → persist
当路由与排队完成后,进入真正的“智能体循环”:
- 组装上下文与系统提示
- 调用模型(可流式)
- 运行工具(可能触发审批)
- 产出最终回复并写回会话
入口:
5) 出站回复:回到原渠道(确定性投递)
重要原则:从哪个渠道进来,就回到哪个渠道(模型不“选渠道”)。 这让排障与安全边界更可控:你在日志里能看到明确的入站/出站对应关系。
入口:
调试清单(遇到问题先看这些)
- WS 连不上:先读 Gateway 协议 的
connect.challenge/connect,再看 健康检查。 chat.send没响应:在 Control UI 看chat事件,或用openclaw gateway call做最小验证(见 CLI:gateway)。- 回复串线/乱序:优先复核
sessionKey与 lane(见 Session tool 与 队列与 Lane)。