OpenClaw 深度剖析:一個 Self-Hosted AI 助理平台的技術全貌


OpenClaw 是一個開源的 self-hosted AI 助理平台,主張「在你自己的裝置上、在你習慣的通訊管道裡、按你自己的規則運行 AI」。它不是又一個 ChatGPT wrapper,而是一整套從 Gateway 控制平面、多頻道訊息路由、Agent 執行引擎、Plugin 生態到跨平台 Companion App 的完整架構。本文將以原始碼為依據,深入拆解這個專案的技術全貌。


專案規模

在展開分析之前,先看看數字:

維度數值
TypeScript 原始碼(src/)~399,000 行 / 2,326 檔案
測試程式碼~274,000 行 / 1,404 檔案
擴充套件(extensions/)~73,500 行 / 418 檔案
Swift(macOS + iOS)~89,000 行 / 497 檔案
Kotlin(Android)~14,000 行 / 82 檔案
內建 Skills54+ 個
支援頻道(built-in + extension)20+ 個
Commits14,700+

這是一個接近 85 萬行程式碼的大型專案,且測試覆蓋率要求 70% 以上(lines / branches / functions / statements,透過 Vitest + V8 coverage)。


核心架構:Gateway 控制平面

OpenClaw 的架構核心是一個 WebSocket 控制平面(Gateway),所有的 Agent、Channel、Client 都透過它進行通訊。這個設計將「路由」與「執行」集中在同一個受信任的 operator boundary 內。

架構概覽

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│   Telegram   │  │   Discord    │  │    Slack     │
│   Channel    │  │   Channel    │  │   Channel    │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                 │                 │
       └─────────────────┼─────────────────┘
                         │  Inbound Messages
                   ┌─────▼─────┐
                   │  Channel  │
                   │  Router   │
                   └─────┬─────┘
                         │  Resolve Agent + Session
                   ┌─────▼─────────────────┐
                   │     Gateway Server     │
                   │  (WebSocket Control)   │
                   │                        │
                   │  ┌──────────────────┐  │
                   │  │  Session Store   │  │
                   │  │  Event Broadcast │  │
                   │  │  Auth & Rate     │  │
                   │  │  Limit           │  │
                   │  └──────────────────┘  │
                   └─────┬─────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
  ┌─────▼─────┐   ┌─────▼─────┐   ┌─────▼─────┐
  │   Agent   │   │  Canvas   │   │  Browser  │
  │  Runtime  │   │  (A2UI)   │   │  Control  │
  └───────────┘   └───────────┘   └───────────┘

WebSocket 連線生命週期

Gateway 在 src/gateway/server.impl.ts(這是整個 Gateway 的核心實作,超過 27,000 行)中建立 WebSocket 伺服器。連線流程:

  1. 客戶端發起 WebSocket 連線
  2. 分配唯一 connId(UUID),記錄 headers:host、origin、user-agent、x-forwarded-for
  3. Handshake timeout 限制(防止空連線佔資源)
  4. 透過 attachGatewayWsMessageHandler() 掛載訊息處理器
  5. 客戶端狀態追蹤:pendingconnectedfailed(或 closed)

認證機制

Gateway 支援多種認證模式,在 src/gateway/auth.ts 中實作:

  • none -- loopback-only 場景,不需認證
  • token -- Bearer token 認證
  • password -- 密碼認證
  • trusted-proxy -- 反向代理信任模式
  • tailscale -- Tailscale whois 身分識別
  • device-token -- Companion App 裝置配對 token

還有完整的速率限制機制(auth-rate-limit.ts),基於 IP 的 fixed-window rate limiter 防止暴力破解。

事件廣播系統

src/gateway/server-broadcast.ts 實作了事件分發:

broadcastInternal(event, payload, opts?, targetConnIds?):
  // 建立 JSON frame: {type: "event", event, payload, seq, stateVersion}
  // 序列號碼追蹤(非定向廣播)
  // 遍歷所有 clients Set 進行發送

背壓處理(backpressure):

  • 偵測慢速消費者:socket.bufferedAmount > MAX_BUFFERED_BYTES
  • dropIfSlow: true -- 跳過傳送
  • dropIfSlow: false -- 關閉連線(code 1008)

事件還有 scope guard 控制:

  • exec.approval.requested/resolved → 需要 operator.approvals scope
  • device.pair.requested/resolved → 需要 operator.pairing scope
  • Admin scope(operator.admin)可繞過所有限制

Session 管理

Session 是 OpenClaw 的核心狀態單元。每個對話都對應一個 session,session 透過 composite key 識別。

Session Key 格式

{agentId}:{channel}:{accountId}:{chatType}:{peerId}

例如:

  • main:telegram:default:direct:123456789
  • default:discord:main:channel:987654321
  • main:slack:bot:thread:ts1234567890.thread001

DM Scope 模式

針對私訊(DM),提供四種 scope 模式:

模式說明
main所有 DM 共用一個 session
per-peer每個對話對象一個 session
per-channel-peer按頻道 + 對話對象隔離
per-account-channel-peer完全隔離

持久化

  • 儲存格式:sessions.json~/.openclaw/agents/{agentId}/sessions/
  • Transcript:{sessionId}-{topic}.jsonl(JSONL 格式,支援串流追加)
  • Stale lock 清理:30 分鐘閾值
  • 安全性:Session ID 驗證拒絕 ..//\\ 等路徑穿越字元

多頻道整合架構

OpenClaw 最有野心的設計之一,是它的多頻道架構。支援超過 20 個通訊平台,每個都透過統一的 ChannelPlugin 介面接入。

雙層抽象

系統維護兩層 Channel 定義:

  1. ChannelDock(輕量級 metadata)

定義在 src/channels/dock.ts,提供路由、設定讀取、allowlist 等共用邏輯,不需要載入完整的 plugin:

type ChannelDock = {
  id: ChannelId;
  capabilities: ChannelCapabilities;  // chatTypes, nativeCommands, blockStreaming
  outbound?: { textChunkLimit?: number };
  config?: { resolveAllowFrom, formatAllowFrom, resolveDefaultTo };
  threading?: { resolveReplyToMode, buildToolContext };
  // ...
};
  1. ChannelPlugin(完整實作)

每個頻道的完整整合,包含 config adapter、security adapter、gateway adapter、outbound adapter、pairing adapter 等:

type ChannelPlugin<T> = {
  config: ChannelConfigAdapter<T>;
  security?: ChannelSecurityAdapter;
  gateway?: { startAccount: (ctx) => Promise<void> };
  outbound?: ChannelOutboundAdapter;
  pairing?: ChannelPairingAdapter;
  threading?: ChannelThreadingAdapter;
  // ...
};

內建頻道

頻道文字分塊上限特殊能力
Telegram4,000 chars原生 /command、Channel 類型
Discord2,000 charsGuild + Role 路由、按鈕互動
Slack4,000 charsThread 支援、Workspace 路由
Signal4,000 charsE2E 加密(via signal-cli)
iMessage4,000 charsmacOS only(via BlueBubbles)
WhatsApp4,000 charsWeb 版整合(Baileys SDK)
IRC350 chars最小文字塊限制
Google Chat4,000 charsWorkspace 整合

擴充頻道(Extensions)

透過 Plugin SDK 實作的外部頻道,以獨立的 workspace package 形式存在:

  • MS Teams (extensions/msteams/)
  • Matrix (extensions/matrix/)
  • Zalo (extensions/zalo/)
  • Feishu/Lark (extensions/feishu/)
  • Mattermost (extensions/mattermost/)
  • LINE (extensions/line/)
  • Nostr (extensions/nostr/)
  • Twitch (extensions/twitch/)
  • Nextcloud Talk (extensions/nextcloud-talk/)
  • Voice Call (extensions/voice-call/)

Plugin 開發者只需實作 ChannelPlugin 介面:

const plugin = {
  id: "matrix",
  name: "Matrix",
  register(api: OpenClawPluginApi) {
    api.registerChannel({ plugin: matrixPlugin });
  }
};

DM 配對安全模型

OpenClaw 預設啟用 pairing-based DM policy:陌生發送者必須通過配對才能與 bot 對話。

配對流程:

  1. 陌生人發送訊息 → bot 生成 8 字元配對碼(ABCDEFGHJKLMNPQRSTUVWXYZ23456789,排除易混淆字元)
  2. 配對碼透過 crypto.randomInt() 生成,最多 500 次嘗試確保唯一
  3. 配對碼有效期 1 小時,每個頻道最多 3 個 pending 碼
  4. operator 在其他管道核准配對碼 → 發送者加入 allowFrom 清單
  5. 原子檔案鎖確保沒有 race condition

訊息路由

src/routing/resolve-route.ts 實作了多層級的 binding 路由:

優先順序(由高到低):

  1. Peer binding -- 直接指定某對話對象走某 agent
  2. Parent peer binding -- Thread 繼承父訊息的路由
  3. Guild + Roles -- Discord 伺服器 + 角色組合
  4. Guild binding -- Discord 伺服器級別
  5. Team binding -- Slack workspace / Teams 級別
  6. Account binding -- 帳號級別預設
  7. Channel binding -- 頻道級別預設
  8. Default -- 預設 agent

AI Agent 系統

多 Provider 抽象

src/providers/ 抽象了多個 AI 模型供應商:

  • Anthropic Claude(推薦,原生整合)
  • OpenAI GPT-4o / o1
  • Google Gemini
  • GitHub Copilot(OAuth 認證)
  • Qwen Portal
  • Mistral、Groq、DeepGram
  • 本地模型(via node-llama-cpp)

Provider 選擇採用 Auth Profile 機制:

// 多 profile 認證,帶 fallback 排序和 cooldown
authProfiles: [
  { provider: "anthropic", apiKey: "sk-..." },
  { provider: "openai", apiKey: "sk-..." },   // fallback
]

當某個 provider 認證失敗時,自動 cooldown 並切換到下一個。

Plugin 系統

OpenClaw 的 Plugin 系統是整個平台可擴充性的基礎:

三種 Plugin 來源:

  • Bundled -- 隨 OpenClaw 核心一起發佈(src/plugins/
  • Managed -- 從 npm 安裝到 ~/.openclaw/plugins/managed/
  • Workspace -- 使用者在 Agent workspace 的 .plugins/ 目錄自建

Plugin 載入機制:

  • 使用 jiti 進行 TypeScript 的動態 import,不需要預先 build
  • Registry 層級快取,以 workspace + plugin config hash 為 key
  • Plugin SDK alias 解析(openclaw/plugin-sdk

Plugin 能力:

  • CLI 指令擴充
  • Gateway 請求處理器
  • 自訂 Agent 工具(ToolFactory)
  • 生命週期 Hook
  • 記憶體插槽
  • Config schema 驗證(Zod)

Memory 系統

src/memory/ 實作了混合搜尋記憶體:

  • 向量搜尋 -- sqlite-vec 擴充(1536 維 embeddings)
  • 全文搜尋 -- SQLite FTS5(BM25 排序)
  • 混合搜尋 -- 結合兩者結果,以 MMR(Maximal Marginal Relevance)重新排序

Embedding 供應商支援 OpenAI ada-002、Gemini、Voyage、Mistral、本地模型,且有自動 fallback。

記憶體來源:

  • 明確指定的目錄(例如 ~/.notes/
  • Session 歷史(JSONL)
  • 支援時間衰減加權

Skills 生態系統

OpenClaw 內建 54+ 個 Skill,涵蓋:

類別Skill 範例
系統整合apple-notes、apple-reminders、bear-notes、things-mac
訊息discord、slack、voice-call
開發工具coding-agent、github、gh-issues
AI / LLMgemini、openai-image-gen、openai-whisper
生產力notion、obsidian、trello
基礎設施clawhub、mcporter、model-usage

此外還有 ClawHub(clawhub.ai)作為社群 Skill 發布平台。

Canvas / A2UI

Canvas 是 OpenClaw 的互動式視覺工作區,使用 A2UI(Anthropic UI)框架:

  • HTTP + WebSocket 雙協定伺服器
  • 路徑:/__openclaw__/canvas/(HTTP)、/__openclaw__/ws(WebSocket)
  • 支援 Live Reload 開發模式
  • 沙箱式檔案解析,限制在 root directory 內

Browser Automation

基於 Playwright 的瀏覽器自動化:

  • CDP(Chrome DevTools Protocol)橋接
  • 角色式元素選擇(role-based,比 XPath 更穩定)
  • 操作:點擊、雙擊、懸停、拖曳、表單輸入、截圖
  • 進階功能:元素高亮、頁面狀態觀察、網路活動監控、檔案下載攔截
  • Chrome Extension 注入(Manifest v3)

Voice / TTS

多供應商 TTS 整合:

供應商模型特色
OpenAIgpt-4o-mini-ttsalloy、echo、nova 等 6 種聲音
ElevenLabs多語言模型stability / similarity boost 調整
Microsoft Edge TTSNeural 聲音支援語言/地區選擇

輸出格式會根據頻道自動適配(Telegram 用 Opus voice note、預設 MP3)。


Agent Client Protocol(ACP)

OpenClaw 實作了 ACP 協定,讓 IDE 和外部工具能透過標準化介面驅動 Agent:

# 在 Gateway 上啟動 ACP bridge
openclaw acp --url wss://gateway-host:18789 --token <token>

ACP 到 Gateway 的映射:

  • promptchat.send
  • cancelchat.abort
  • listSessionssessions.list

Session 映射:

  • 預設 acp:<uuid> 隔離 session
  • 可自訂 --session agent:main:main 指向特定 agent

支援 Zed Editor 整合:

{
  "agent_servers": {
    "OpenClaw ACP": {
      "type": "custom",
      "command": "openclaw",
      "args": ["acp"]
    }
  }
}

跨平台 Companion App

OpenClaw 不只是一個 CLI 工具,它有完整的跨平台 App 生態。

macOS Menu Bar App(Swift)

  • 使用 Swift @Observable 框架的現代 SwiftUI 架構
  • 連線模式:unconfiguredlocal(loopback)→ remote(SSH / WebSocket)
  • Config File Watcher 監控 ~/.openclaw/config.json 變動,自動套用
  • Voice Wake 語音喚醒(觸發詞:Claude、Computer、Jarvis、自訂)
  • 透過 LaunchdManager 管理 launchd daemon

iOS App(Swift)

最有趣的是 iOS 的 雙 Gateway Session 設計:

┌──────────────────┐
│   iOS App        │
│   (Single Process)│
└────────┬─────────┘
         │
    ┌────┴────────────────────────┐
    │                             │
    ▼                             ▼
  Node Session              Operator Session
  (device capabilities)     (chat, talk mode)
  - Camera                  - Message send/recv
  - Location                - Voice wake sync
  - Screen record           - Config updates
  - SMS

Node Session 負責裝置能力(相機、定位、螢幕錄影、SMS),Operator Session 負責對話和設定。兩者獨立運作,chat 不會被 device 操作阻塞。

裝置能力透過 NodeCapabilityRouter 路由到平台 handler:

  • CameraHandler、ScreenHandler、LocationHandler、SmsHandler
  • CalendarHandler、ContactsHandler
  • A2UIHandler(Canvas 互動 UI)

Android App(Kotlin)

與 iOS 類似的架構,但使用 Kotlin Coroutine + StateFlow:

  • NodeRuntime 中央協調器
  • GatewayDiscovery 透過 mDNS 掃描區域網路上的 Gateway
  • Foreground Service 維持背景語音操作(Android API 31+ 要求)
  • 安全儲存:SecurePrefs + DeviceAuthStore

通訊協定

所有 Companion App 與 Gateway 之間使用版本化的 WebSocket 協定(目前 v3):

Handshake 流程:

  1. Client 發送 ConnectParams(min/max protocol version、client metadata、capabilities)
  2. Server 回應 HelloOk(negotiated version、features、initial snapshot、canvas host URL)

Frame 格式:

// Request
{ type: "request", id: "uuid", method: "chat.send", params: {...} }

// Response
{ type: "response", id: "uuid", ok: true, payload: {...} }

// Event (server-initiated)
{ type: "event", event: "agent.stream", payload: {...}, seq: 42 }

CLI / TUI

  • CLI:完整的指令系統(src/cli/),支援 channel 管理、browser 控制、model 設定、skill 管理
  • TUI:使用 @mariozechner/pi-tui 的終端 UI,支援多行輸入、語法高亮、slash command、bash mode(! prefix)

Web UI

基於 Lit Element 的 Web 介面:

  • Vite + Lit(Custom Elements)架構
  • Legacy decorators(@state()@property()
  • WebSocket 即時連線 + 自動重連
  • 回應式設計

Daemon 與部署

跨平台 Daemon

平台服務類型管理指令
macOSLaunchAgent(launchd)launchctl
Linuxsystemd user servicesystemctl --user
WindowsScheduled Taskschtasks

macOS 生成 .plist~/Library/LaunchAgents/ai.openclaw.gateway.plist),設定 KeepAlive 自動重啟。Linux 生成 ~/.config/systemd/user/openclaw-gateway.service

Docker 部署

# docker-compose.yml
services:
  openclaw-gateway:
    image: openclaw/openclaw:latest
    ports:
      - "18789:18789"   # Gateway
      - "18790:18790"   # Bridge
    volumes:
      - ~/.openclaw:/home/node/.openclaw
    command: gateway --bind lan --port 18789
    restart: unless-stopped

安全加固:

  • 以非 root 使用者(node)執行
  • 支援 --read-only + --cap-drop=ALL
  • 支援 Fly.io 部署(fly.toml 已包含)

安全模型

OpenClaw 的安全模型是 personal assistant(單一受信任 operator),而非多租戶系統。

信任邊界

  • 通過 Gateway 認證的呼叫者被視為受信任的 operator
  • Session ID 是路由控制,不是使用者級別的授權邊界
  • 建議每個使用者一台主機 / 一個 Gateway
  • 插件在 Gateway 進程內執行,視為受信任程式碼

防禦措施

  • SSRF 防護:URL 提取時驗證 hostname / IP,阻擋內網存取
  • 路徑沙箱:Canvas 檔案解析限制在 root directory 內
  • 速率限制:ACP session 建立、auth 嘗試都有 fixed-window limiter
  • Prompt 大小限制:2MB 上限(DoS 防護)
  • Exec 審批系統:工具執行可要求 operator 核准

工具與檔案系統硬化

tools:
  exec:
    applyPatch:
      workspaceOnly: true      # apply_patch 限制在 workspace 內
  fs:
    workspaceOnly: true         # 檔案操作限制在 workspace 內

技術棧總覽

層級技術選擇
RuntimeNode.js 22+(Bun 亦支援)
語言TypeScript(ESM、strict typing)
建構tsdown(build)、Vitest(test)、Oxlint + Oxfmt(lint/format)
套件管理pnpm(monorepo workspace)
Schema 驗證Zod 4
HTTPExpress 5
WebSocketws
資料庫SQLite(FTS5 + sqlite-vec)
瀏覽器自動化Playwright
macOS / iOSSwift + SwiftUI + @Observable
AndroidKotlin + Jetpack Compose + Coroutine
Web UILit Element + Vite
文件Mintlify
CI/CDGitHub Actions
部署Docker / Fly.io / launchd / systemd

設計哲學

從原始碼和 VISION.md 中,可以提煉出幾個核心設計哲學:

1. Terminal-First

OpenClaw 刻意選擇終端優先的設計,讓使用者在設定時能明確看到認證、權限、安全態勢。他們不想用「便利的包裝」隱藏關鍵的安全決策。

2. 為什麼選 TypeScript

官方解釋是:OpenClaw 本質上是一個 編排系統(orchestration system)-- prompts、tools、protocols、integrations。TypeScript 廣為人知、迭代快速、容易閱讀和修改。這是一個務實的選擇。

3. 核心精簡、擴充外掛

Plugin 系統的設計原則是:核心保持精簡,可選能力透過 plugin 發佈。新 skill 應該先上 ClawHub,不是直接加到核心。Plugin 進入核心的門檻刻意設得很高。

4. MCP 橋接而非原生

OpenClaw 透過 mcporter(外部工具)支援 MCP,而非在核心中實作 MCP runtime。這讓 MCP 整合保持彈性和解耦,減少 MCP 頻繁變動對核心穩定性的衝擊。

5. 單使用者信任模型

這是一個重要的架構決策:OpenClaw 不做多租戶隔離。每個 Gateway 對應一個受信任的 operator。如果需要多使用者,就用多個 Gateway。這大幅簡化了安全模型,但也意味著它不適合作為 SaaS 平台。


訊息處理的完整流程

最後,用一張流程圖總結一條訊息從進入到回覆的完整路徑:

使用者在 Telegram 發送訊息
    ↓
Telegram Webhook 接收
    ↓
解析 MsgContext(提取 sender、chatType、text、media、thread info)
    ↓
DM 安全檢查(pairing policy → allowFrom 驗證)
    ↓
路由解析(binding 優先級:peer → guild+role → account → channel → default)
    ↓
Session Key 生成(main:telegram:default:direct:123456789)
    ↓
Agent 處理
    ├─ Link 提取 + SSRF 驗證
    ├─ Media 理解(Gemini / OpenAI / Anthropic)
    ├─ Memory 搜尋(hybrid vector + keyword)
    └─ Model 選擇(auth profile fallback chain)
    ↓
工具執行(browser、TTS、bash、custom plugin tools)
    ↓
回覆生成(LLM prompt + tools)
    ↓
文字分塊(按頻道限制:Telegram 4000 / Discord 2000 / IRC 350)
    ↓
Outbound 遞送(plugin adapter → channel SDK)
    ↓
Threading 裝飾(reply-to mode、cross-context prefix)
    ↓
使用者收到回覆

結語

OpenClaw 展現了一個 self-hosted AI 助理平台可以走多遠。它不只是一個 chatbot framework,而是一個完整的作業系統級別的 AI 整合層 -- 從底層的 WebSocket 控制平面、到中間的多頻道路由和 Agent 編排、到上層的跨平台 Companion App。

幾個值得技術團隊參考的設計亮點:

  • ChannelDock 雙層抽象 -- 將輕量 metadata 和完整 plugin 分離,讓路由邏輯不需要載入所有頻道的完整程式碼
  • Binding-based 路由 -- 支援從 peer level 到 channel level 的多層級路由,配合 DM scope 實現彈性的 session 隔離
  • Auth Profile 帶 cooldown 的 fallback chain -- 多 provider 切換時的可靠性保證
  • Hybrid Memory Search -- 向量搜尋 + 全文搜尋 + MMR re-ranking 的實用組合
  • Dual Gateway Session(iOS/Android) -- 裝置能力和對話分離,不互相阻塞

當然,85 萬行程式碼的專案也帶來挑戰:Gateway 核心的 server.impl.ts 超過 27,000 行(雖然專案指南建議 500-700 行),文件散落在多個位置。但從工程成熟度來看 -- 70%+ 測試覆蓋率、完整的 CI/CD、Cross-platform 支援、活躍的社群 -- 這是一個值得認真對待的開源專案。