工程主线:从 CLI 到一次回复

工程主线:从 CLI 到一次回复

这页用“工程主线”的方式串起一次完整链路:一个请求/一条消息 如何走过 OpenClaw 的各层,最终得到可交付的回复。

目标是让你能回答:

  • 我现在看到的日志/事件属于哪一层?
  • 下一步应该去哪里看(文档 / 方法 / 源码入口)?

最短观测闭环(10 分钟)

先把“可观察”跑通,再读实现更省时间:

  1. 启动 Gateway 网关:
openclaw gateway
  1. 另开一个终端跟踪日志(文件日志尾随):
openclaw logs --follow
  1. 打开 Control UI 并发起一次对话(或通过任一渠道发一条消息):
openclaw dashboard
  1. 你应该能观察到两类信号:
  • 控制面: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.tssrc/gateway/server/ws-connection/message-handler.tssrc/gateway/server-methods.ts
  • chat.send 入口:src/gateway/server-methods/chat.ts
  • 路由与会话键:src/config/sessions/session-key.tssrc/gateway/server-session-key.ts
  • lane/队列:src/process/command-queue.tssrc/agents/pi-embedded-runner/lanes.tssrc/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) 出站回复:回到原渠道(确定性投递)

重要原则:从哪个渠道进来,就回到哪个渠道(模型不“选渠道”)。 这让排障与安全边界更可控:你在日志里能看到明确的入站/出站对应关系。

入口:

调试清单(遇到问题先看这些)