AI 程式設計教程中文版
官方教程中文版Gateway 執行時

理解 Gateway 架構

理解 OpenClaw Gateway 架構:長期控制面、WebSocket 協議、nodes、pairing、本機 loopback、遠端訪問和執行不變數。

OpenClaw 的中心不是某個聊天視窗,而是 Gateway。Gateway 是一個長期執行的控制面,負責接入訊息渠道、維護會話、排程 Agent、暴露 WebSocket 控制介面,並把 CLI、Web UI、macOS app、移動端、nodes 和自動化任務收束到同一個執行時。

這一章用 13 分鐘換什麼:你會知道為什麼 OpenClaw 不是一次性 CLI,為什麼預設監聽 127.0.0.1:18789,為什麼一個 host 只該有一個 Gateway,以及遠端訪問為什麼優先走 Tailscale / SSH tunnel。

1. 一句話理解 Gateway

Gateway 是 OpenClaw 的控制面。

它做四件事:

  • 連線訊息平臺,例如 WhatsApp、Telegram、Slack、Discord、Signal、iMessage、WebChat。
  • 接收控制端連線,例如 CLI、macOS app、Web UI、自動化指令碼。
  • 接收 node 連線,例如 macOS、iOS、Android 或 headless 節點暴露的裝置能力。
  • 負責會話、健康狀態、心跳、cron、hooks 和 Agent 執行事件。

預設情況下,控制面監聽在:

127.0.0.1:18789

這個預設值很關鍵:OpenClaw 預設把 Gateway 放在本機迴環地址上,而不是直接暴露到公網。

flowchart TD
    Gateway["Gateway"]
    Channels["訊息渠道"]
    Clients["控制端客戶端"]
    Nodes["Nodes"]
    Agents["Agents"]
    State["sessions / auth / health"]
    UI["Canvas / A2UI / Control UI"]

    Channels --> Gateway
    Clients --> Gateway
    Nodes --> Gateway
    Gateway --> Agents
    Gateway --> State
    Gateway --> UI

    style Gateway fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
    style Channels fill:#dcfce7,stroke:#22c55e,stroke-width:2px
    style Nodes fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style State fill:#fee2e2,stroke:#ef4444,stroke-width:2px

Gateway 不是聊天介面:聊天介面只是一個客戶端。真正持有渠道連線、session、auth profiles 和執行狀態的是 Gateway。

2. 元件分工

Gateway daemon:

  • 維護各個 provider 的連線。
  • 暴露 typed WebSocket API。
  • 按 JSON Schema 校驗入站 frame。
  • 推送 agentchatpresencehealthheartbeatcron 等事件。

控制端 clients:

  • CLI、macOS app、Web admin、自動化指令碼都屬於控制端。
  • 每個 client 建立一條 WebSocket 連線。
  • 常見請求包括 healthstatussendagentsystem-presence

Nodes:

  • node 不是 Gateway,也不接管訊息渠道。
  • node 用 role: "node" 連線同一個 WebSocket server。
  • node 暴露裝置能力,例如 canvas.*camera.*device.*notifications.*screen.recordlocation.getsystem.*

WebChat:

  • WebChat 是靜態聊天介面。
  • 它透過 Gateway WebSocket API 讀歷史和傳送訊息。
  • 遠端部署時,它應該走同一條 SSH 或 Tailscale 入口,而不是另開一個無保護入口。
元件負責什麼不負責什麼
Gateway渠道連線、控制面、session、事件、Agent 排程不直接代表某個聊天 UI
Client發控制請求、展示狀態、傳送訊息不持有渠道 session
Node暴露裝置能力和遠端執行面不執行 Gateway 服務
WebChat靜態聊天頁面不替代 Gateway auth 和 pairing

3. 為什麼官方強調一個 host 一個 Gateway

一個 host 上只應該有一個長期 Gateway 控制同一組渠道狀態。尤其是 WhatsApp 這類渠道,官方架構裡強調 Gateway 是開啟會話的唯一位置。

如果同一臺機器起多個 Gateway 去搶同一個渠道,會出現三類問題:

  • provider session 被重複登入或互相踢下線。
  • session、pairing、allowlist、cron 狀態分裂。
  • Agent 記憶和 workspace 寫入分叉,排障時無法判斷哪個程序是真正入口。

實踐判斷很簡單:一個機器、一個信任邊界、一個 Gateway。

多 Gateway 不是橫向擴容捷徑:除非你有明確隔離 profile、隔離渠道和隔離 workspace,否則多個 Gateway 會先帶來狀態分裂,而不是穩定性。

4. WebSocket 握手

Gateway 的協議是 WebSocket 文本 frame,payload 是 JSON。第一幀必須是 connect。握手後才進入請求、響應和事件流。

常見結構可以理解為:

{ "type": "req", "id": "1", "method": "health", "params": {} }

響應:

{ "type": "res", "id": "1", "ok": true, "payload": {} }

事件:

{ "type": "event", "event": "health", "payload": {} }

副作用請求需要 idempotency key,避免重試時重複傳送訊息或重複觸發 Agent。

握手過程可以壓成這張圖:

sequenceDiagram
    participant Client as Client / Node
    participant Gateway as Gateway

    Gateway-->>Client: connect.challenge
    Client->>Gateway: req connect
    Gateway-->>Client: res hello-ok
    Gateway-->>Client: event presence
    Client->>Gateway: req health / agent / send
    Gateway-->>Client: res + event stream
規則含義
第一幀必須是 connect非 JSON 或非 connect 首幀會被關閉
hello-ok 返回能力和快照客戶端知道 server 版本、methods、events、policy
events 不保證 replay客戶端發現 gap 後要重新拉狀態
side-effect method 要冪等鍵sendagent 這類請求重試時不能重複副作用

5. Pairing 和本地信任

所有 WebSocket 客戶端和 nodes 都會在 connect 階段帶裝置身份。新裝置 ID 需要 pairing approval,Gateway 會給後續連線發 device token。

可以這樣理解:

  • 本機 loopback 連線可以有更順滑的體驗。
  • 非本地連線仍然需要顯式 approval。
  • Gateway 的 gateway.auth.* 仍然適用於本地和遠端連線。
  • Tailscale、trusted proxy、shared-secret 只是不同認證入口,不是繞過 pairing 的理由。
  • 所有連線都要簽名 connect.challenge nonce。

這也是為什麼官方安全文件反覆強調:OpenClaw 是個人助手信任模型,不是給互不信任使用者共享一個 Agent 的多租戶邊界。

6. Canvas 和 A2UI

Gateway HTTP server 也承載兩個內建路徑:

/__openclaw__/canvas/
/__openclaw__/a2ui/

它們複用 Gateway 埠。Canvas 面向 Agent 可編輯的 HTML/CSS/JS,A2UI 面向 Agent-to-UI 的互動宿主。你不需要把它們理解成單獨服務;它們屬於 Gateway 執行時的一部分。

7. 遠端訪問

遠端訪問優先順序:

  1. Tailscale 或 VPN。
  2. SSH tunnel。
  3. 有明確認證、TLS、反向代理和審計的受控入口。

SSH tunnel 示例:

ssh -N -L 18789:127.0.0.1:18789 user@host

這條命令的意思是:本機訪問 127.0.0.1:18789,實際轉發到遠端機器的 Gateway loopback 埠。Gateway 仍然不用直接暴露公網埠。

遠端方式適合場景關鍵邊界
Tailscale / VPN常駐主機、家用伺服器、VPS仍然要 auth 和 pairing
SSH tunnel通用兜底、臨時遠端Gateway 保持 loopback-only
受控反向代理明確 TLS、auth、審計的部署不給陌生公網裸露 WS

gateway.remote.token 不是服務端認證開關:它是客戶端憑據來源。服務端 auth 仍然要看 gateway.auth.* 或 trusted proxy 配置。

8. 運維快照

前臺啟動:

openclaw gateway

檢視狀態:

openclaw health
openclaw status
openclaw gateway status

生產使用時,應該交給 launchd、systemd 或 macOS app 監督重啟。不要依賴一個臨時終端視窗長期託管。

9. 不變數

  • 一個 host 上一個 Gateway 控制同一套渠道。
  • Gateway 預設監聽 loopback。
  • 第一幀必須是 connect
  • 非 JSON 或非 connect 首幀會被關閉。
  • events 不保證 replay,客戶端發現事件 gap 後應該重新拉狀態。
  • 遠端入口仍然需要 auth 和 pairing。
  • Nodes 是外圍裝置能力,不是 Gateway 服務。
  • WebChat 複用 Gateway WebSocket,不是單獨安全邊界。

排架構問題先找唯一入口:訊息平臺、UI、CLI、node 和自動化最終都回到 Gateway;如果狀態分裂,先確認是不是啟動了多個控制面或多個 profile。

10. 本章自檢

  1. Gateway、Client、Node 的分工分別是什麼?
  2. 為什麼一個 host 上不應該讓多個 Gateway 搶同一組渠道?
  3. 遠端訪問為什麼優先保留 loopback,再用 Tailscale 或 SSH tunnel?

過關標準:你能用一句話說清 —— “Gateway 是 OpenClaw 的長期控制面,所有客戶端和 nodes 都透過它連線,遠端訪問也不能繞過 auth、pairing 和 loopback-first 的預設安全邊界。”

11. 接下來去哪

12. 官方資料

本頁目錄