OpenClaw Gateway 核心:你的 AI 管家長什麼樣
你有沒有想過,一個 AI 助手跑在你自己的機器上,到底長什麼樣?
不是 ChatGPT 那種別人家的 web UI,是真的跑在你的 server、用你的 Telegram、Discord 跟你講話的那種。今天我們要拆開 OpenClaw 這台機器的引擎蓋,看看裡面怎麼運作。如果你是 Python 後端出身、看到 TypeScript 就想逃跑的人 ╰(°▽°)╯ 恭喜你來對地方了,整篇用 Python 世界的語言帶你走。
10 層樓 + Boss Floor,準備好就出發 🗡️
🏰 Floor 0:OpenClaw 是什麼?(鳥瞰)
一句話:
OpenClaw 是一個跑在你自己機器上的 AI 助手,透過你已經在用的通訊軟體跟你對話。
它不是 ChatGPT(那是別人的 web UI),不是 API wrapper,是一個完整的控制平面(control plane)—— 有 session 管理、auth、failover、排程、tool 執行,什麼都有。
架構一覽
┌──────────────┐
Telegram ──────> │ │ ──────> Agent (Claude / GPT)
Discord ──────> │ Gateway │ ──────> Tools (shell, browser, files...)
WhatsApp ──────> │ (大腦) │ ──────> Cron (排程任務)
│ │ ──────> Nodes (手機、其他裝置)
└──────────────┘
- Gateway = 大腦,所有東西的中心
- Channels = 耳朵嘴巴(Telegram、Discord)
- Agent = 思考引擎(呼叫 LLM API)
- Tools = 手腳(shell、瀏覽器、檔案讀寫)
基本數字:269 個 dist modules、1,086 個 test files、Node.js >= 22、MIT license。Creator 是 Peter Steinberger。
Clawd 的 murmur:
對 Python 人來說,OpenClaw 有點像你用 FastAPI 寫了一個超級 bot backend,然後把 LangChain agent、APScheduler、sqlite 全部塞進同一個 process。但人家寫得比你好(而且真的 production-ready)。你那個 side project 跑三天就要手動重啟一次,人家跑三個月不用管 ( ̄▽ ̄)/
OpenClaw 跟 ChatGPT 最大的差別是什麼?
OpenClaw 跑在你自己機器上,透過 Telegram、Discord 等通訊軟體對話。ChatGPT 是 OpenAI 的 web UI,跑在他們的 server。核心差別是「誰控制著 AI」。
正確答案是 B
OpenClaw 跑在你自己機器上,透過 Telegram、Discord 等通訊軟體對話。ChatGPT 是 OpenAI 的 web UI,跑在他們的 server。核心差別是「誰控制著 AI」。
🏰 Floor 1:為什麼 Hub-and-Spoke?不用 Microservices?
先搞懂這個詞:Hub-and-Spoke(輪軸與輻條)。
想像一個腳踏車輪子:中間有一個 hub(輪軸),四周伸出很多 spoke(輻條)。所有輻條都連到輪軸,但輻條之間不會直接碰到彼此。
在 OpenClaw 裡:
- Hub = Gateway(中心控制台)
- Spokes = Telegram、Discord、Agent、Tools……(各種元件)
所有東西都透過 Gateway 溝通,Telegram 不會直接跟 Agent 說話、Tools 不會直接跟 Discord 聊天。一切經過 Gateway 中轉。
Clawd 碎碎念:
Hub-and-spoke 這個架構有一個隱藏的好處沒人愛提:debug 的時候你只需要在 Gateway 這一個點上插 log,就能看到所有元件之間的對話。Microservices 的 debug?祝你好運,你需要 distributed tracing、Jaeger、OpenTelemetry,光是把 log 湊齊就花掉你一個下午。我上輩子一定是做了什麼壞事才要 debug 微服務 ┐( ̄ヘ ̄)┌
看到這個架構你可能會問:「這麼多東西…… 不是該拆成 microservices 嗎?」
答案:不用。
Peter 選了 Pizza 店。因為 OpenClaw 是 single-user personal assistant:
- 同時在用的人 = 1 個(就是你)
- 不需要水平擴展、不需要 load balance
- 單 process 省掉 Celery / RabbitMQ / Consul / k8s / distributed tracing
Clawd 嘀咕一下:
Python 的類比:你寫一個自己用的 side project,你會上 k8s + Celery + Redis + RabbitMQ 嗎?不會嘛,你就開一個 FastAPI process 跑完所有東西。OpenClaw 就是這個思路,只是做得很專業。那些面試時逼你回答「如何設計百萬併發」的人大概會氣得跳腳 (╯°□°)╯
代價是不能多台 server load balance、一個 crash 全部掛。但 single-user 場景,這些代價根本不重要。
為什麼 OpenClaw 選擇單 process 而不是 microservices?
Single-user personal assistant 不需要水平擴展,單 process 設計省掉 service mesh、message queue、service discovery 等所有分散式系統的複雜度。
正確答案是 C
Single-user personal assistant 不需要水平擴展,單 process 設計省掉 service mesh、message queue、service discovery 等所有分散式系統的複雜度。
🏰 Floor 2:Gateway — WebSocket RPC 不是 REST
Gateway 跟外部元件之間怎麼溝通?答案是 WebSocket RPC。
但問題來了 —— 為什麼不用大家最熟的 REST?
REST 是 request-response —— 你發一封信,等他回一封。但 AI 助手需要的溝通方式跟一般 CRUD API 完全不同:
- Streaming:AI 想到一半就先推一段給你看(不是等想完才回,那等到天荒地老)
- Server push:Gateway 主動通知你「cron job 跑完了」(你沒問,它主動說)
REST 做不到 server 主動推送。你總不能每秒 poll 一次問「好了沒?好了沒?」,那跟小孩在後座喊「到了沒」一樣煩 (╯°□°)╯
用 Python pseudocode 理解:
# 類似 Python websockets + JSON-RPC 的概念
async def connect_to_gateway():
ws = await websockets.connect("ws://localhost:18789")
request = {
"jsonrpc": "2.0",
"method": "agent", # 叫 AI 做事
"params": {"prompt": "幫我查天氣"},
"id": 1
}
await ws.send(json.dumps(request))
async for message in ws: # streaming 接收
print(json.loads(message))
Clawd 嘀咕一下:
如果你用過 Python 的
jsonrpcserver這個 library,恭喜你直接跳級 —— OpenClaw 的 RPC 層概念完全一樣,只是底層是 WebSocket 而不是 HTTP。沒用過也沒差,反正 JSON-RPC 的精髓就是「我送你一個 JSON 說我要幹嘛,你回我一個 JSON 說結果是啥」,比 REST 那堆 GET POST PUT DELETE PATCH 的 verb 辯論簡單多了 (¬‿¬)
Gateway 預設跑在 port 18789,提供 80+ 個 RPC method。列幾個有趣的:
agent— 叫 AI 幫你做事chat.send— 透過某個 channel 發訊息cron.add— 新增排程任務node.invoke— 在遠端裝置執行命令config.patch— 改設定(不用重啟!)
為什麼 OpenClaw 用 WebSocket 而不是 REST?
REST 是 request-response,server 不能主動推送。OpenClaw 需要 streaming 回覆和主動通知,所以用 WebSocket 建立持久雙向連線。
正確答案是 C
REST 是 request-response,server 不能主動推送。OpenClaw 需要 streaming 回覆和主動通知,所以用 WebSocket 建立持久雙向連線。
🏰 Floor 3:Config 系統 — 你寫 Python 一定碰過這種痛
好,場景題。你寫了一個 Python 專案,config 散落在 .env、config.yaml、環境變數、加上某個同事偷藏在 database 裡的那組設定。改一個值要 SSH 進三台 server,改完還要重啟,重啟完發現打錯字,再 SSH 一次 —— 你一定經歷過這種地獄 (╯°□°)╯
OpenClaw 說:不要。所有設定一個 config.yaml 搞定,用 Zod 做 schema validation。
Zod 是什麼?就是 TypeScript 世界的 Pydantic。
# Python: Pydantic(你熟悉的)
from pydantic import BaseModel
class GatewayConfig(BaseModel):
port: int = 18789
model: str = "claude-sonnet-4-20250514"
max_tokens: int = 4096
auto_compact: bool = True
config = GatewayConfig(port="abc") # ❌ ValidationError!
Clawd 嘀咕一下:
Zod 長這樣:
z.object({ port: z.number().default(18789) })。如果你用 Pydantic 用到會夢到BaseModel,那 Zod 就是讓你在夢裡換成z.object()而已。概念完全一樣 —— 定義 schema、自動 validate、給預設值。最爽的是 TypeScript 端的 type 還能自動從 Zod schema 推導出來,不用寫兩次。Pydantic 使用者聽到這個應該會流淚 (๑•̀ㅂ•́)و✧
Hot-Reload —— 改完存檔就生效
這才是真正讓人爽的地方。改了 config.yaml,Gateway 自動偵測並重新載入,不需要重啟 process。用 file watcher 監控,Zod schema 在 reload 時重新 validate。
想想以前:SSH 進去 → 改檔案 → 重啟 service → 等它起來 → 確認沒壞 → 發現改錯 → 再來一次。現在改完存檔就生效了,這不是科技進步什麼是科技進步。
Clawd 的 murmur:
config.yaml 是唯一的 source of truth。不是散落在環境變數 + config 檔 + database + 某個同事的大腦裡四個地方。你知道最可怕的 config 散落在哪嗎?散落在「只有那個離職的人知道要設的環境變數」裡面 ┐( ̄ヘ ̄)┌
OpenClaw 用什麼做 config schema validation?
OpenClaw 用 Zod 做 config schema validation,概念等同 Python 的 Pydantic。定義 schema → 自動 validate → 給預設值 → 支援 hot-reload。
正確答案是 B
OpenClaw 用 Zod 做 config schema validation,概念等同 Python 的 Pydantic。定義 schema → 自動 validate → 給預設值 → 支援 hot-reload。
🏰 Floor 4:一條訊息的旅程
這是最重要的一層。 如果你只能記住一件事,記住這層。
來,假設你現在拿起手機,在 Telegram 打了一句「幫我查台北天氣」。按下送出的瞬間,這條訊息要穿過多少層才能變成你看到的天氣預報?
答案是 10 步。跟著走一遍:
Step 1: 你在 Telegram 打:「幫我查台北天氣」
Step 2: Telegram Bot API → 推送到 OpenClaw
Step 3: [Telegram Plugin] 把 Telegram 格式 → OpenClaw 內部格式
Step 4: [Gateway Inbound] 收到 → 判斷是哪個 session
Step 5: [Session Manager] 找到 session → 載入對話歷史(SQLite)
Step 6: [Agent] 帶著歷史 + 新訊息 → 呼叫 Claude API
Step 7: [Agent] Claude:「我需要查天氣」→ 呼叫 weather tool
Step 8: [Agent] 拿到天氣資料 → 組最終回覆
Step 9: [Gateway Outbound] → Telegram Plugin → 轉回 Telegram 格式
Step 10: Telegram Bot API → 你看到回覆 ✅
看到 Step 7 了嗎?那一步很有意思 —— Agent 可能多次來回呼叫 Tools。比如 Claude 先查天氣,拿到結果後又說「等等,我還要查明天的」,再呼叫一次 tool。這個 tool-use loop 可能迭代好幾次,像一個廚師備菜時發現少了蔥花又跑回去拿。
Clawd 內心小劇場:
如果你寫過 LangChain 的 AgentExecutor,這個 tool-use loop 你一定不陌生 —— 就是那個 LLM 決定要不要 call tool、call 完之後再想想要不要 call 另一個的迴圈。差別是 OpenClaw 的迴圈不會像 LangChain 一樣偶爾陷入無限迴圈然後把你的 API 額度吃光光 (⌐■_■)
每步對應的模組:
- Step 1-2: 外部(Telegram infra)
- Step 3:
channels/telegram - Step 4:
gateway/inbound - Step 5:
session/store - Step 6-8:
agent/+tools/ - Step 9:
gateway/outbound+ Channel Plugin - Step 10: 外部
Gateway 就是那個領班 —— 不自己做菜(Agent 的事)、不自己端盤子(Plugin 的事),負責調度、路由、管理 session。
一條訊息從使用者到回覆,經過的核心模組順序是?
完整流程:Telegram → Plugin(轉格式)→ Gateway Inbound(路由)→ Session Manager(載入歷史)→ Agent(LLM + Tools)→ Gateway Outbound → Plugin → Telegram。
正確答案是 B
完整流程:Telegram → Plugin(轉格式)→ Gateway Inbound(路由)→ Session Manager(載入歷史)→ Agent(LLM + Tools)→ Gateway Outbound → Plugin → Telegram。
🏰 Floor 5:Session 管理 — 你的 AI 怎麼記得你是誰
好,來一個生活情境。你在 Telegram 跟 AI 聊了一整天的工作規劃,轉頭去 Discord 的某個 group 問了一個跟朋友打遊戲的問題。你肯定不希望 AI 在 Discord 群組裡說出你 Telegram 裡聊的薪水數字,對吧?
這就是 Session 的工作 —— 每段對話有自己的記憶空間,互相不串。就像你在不同房間跟不同人聊天,不會把 A 房間的八卦帶到 B 房間去(至少不該)。
那 Session 怎麼知道哪個是哪個?
靠一組 key。就三個東西:你從哪來(channel)、在哪個對話(chatId)、在哪個 thread(optional)。
session_key = f"{channel}:{chat_id}:{thread_id}"
# 例子
"telegram:123456789:" # Telegram 私訊
"telegram:-100987654321:42" # Telegram group 的某個 topic
"discord:channel_abc123:" # Discord 的某個 channel
看起來簡單到可笑?但這就是好設計的特徵 —— 把複雜問題壓成三個欄位就能唯一識別任何對話上下文。
存在哪?SQLite。
不是 Redis。不是 Postgres。就是一個 SQLite 檔案。
Clawd 的 murmur:
「什麼?SQLite?那不是 toy database 嗎?」—— 拜託,Apple 用 SQLite 存你的 iMessage 聊天紀錄、Chrome 用它存你的 browsing history、你手機裡 80% 的 app 底層都是 SQLite。它不是 toy,它是地球上部署量最大的 database,沒有之一。只是因為它不需要跑一個 daemon、不需要 DBA、不需要 connection pool,大家就覺得它「不夠正式」。這種偏見氣死我了 (¬‿¬)
你可能好奇這在 Python 裡長什麼樣。其實跟你寫過的 FastAPI session middleware 差不多,只是 storage 從 cookie 換成了 SQLite:
class SessionStore:
def __init__(self, db_path="sessions.db"):
self.db = sqlite3.connect(db_path)
def get_session(self, channel, chat_id, thread_id=None):
key = f"{channel}:{chat_id}:{thread_id or ''}"
row = self.db.execute(
"SELECT history FROM sessions WHERE key = ?", (key,)
).fetchone()
return json.loads(row[0]) if row else []
結果就是:Telegram 聊的私密內容不會跑到 Discord 群組、每個 session 可以有不同 model 設定,甚至可以一邊用 Opus 寫程式一邊用 Sonnet 閒聊。
Clawd 嘀咕一下:
Session isolation 聽起來很基本,但你知道有多少 bot framework 做不到嗎?我見過太多 Discord bot 把 A 群組的 context 帶到 B 群組,然後在公開頻道講出不該講的東西。就像那種會在飯局上大聲轉述你私下說的話的朋友 —— 技術上沒 bug,社交上直接出局 (╯°□°)╯
Session key 由哪些元素組成?
Session key = channel(哪個平台)+ chatId(哪個對話)+ optional threadId(哪個 thread/topic)。精確區分不同對話上下文。
正確答案是 B
Session key = channel(哪個平台)+ chatId(哪個對話)+ optional threadId(哪個 thread/topic)。精確區分不同對話上下文。
🏰 Floor 6:Context Overflow — 你的 AI 開始忘事了怎麼辦
你跟朋友聊天聊了三個月,突然你說「上次那件事」,朋友回你「哪件事?」—— 人會忘,AI 也會,只是原因不同。人是因為大腦容量有限(好吧,還有因為懶),AI 是因為 context window 有硬上限。Claude 是 200K tokens,聽起來很多,但你跟 AI 認真工作幾天就能把它灌滿。
直接砍掉舊的?太暴力。你三天前說的重要事情(「我的 server 在 192.168.1.100」)就沒了,AI 之後問你 server IP 你又要再打一次,然後你開始懷疑到底是誰在服務誰。
OpenClaw 的做法比較聰明:Auto-Compaction —— 把舊對話「摘要」成短版本,保留重點,騰出空間。
來看看大致怎麼做的:
# Pseudocode
def check_and_compact(session):
total_tokens = count_tokens(session.history)
if total_tokens > 200_000 * 0.8: # 80% 就開始壓
old = session.history[:len(session.history)//2]
summary = llm.summarize(old)
session.history = [
{"role": "system", "content": f"對話摘要:{summary}"},
*session.history[len(session.history)//2:]
]
注意 80% 這個門檻 —— 不是等到 100% 滿了才壓,是提前壓。就像你不會等到油箱見底亮燈才去加油(好吧有些人會,但那些人也會等到 deadline 前一天才開始寫 report)。
Clawd 嘀咕一下:
我最不爽的是有些人把 auto-compaction 當成萬靈丹。拜託,壓縮就是有損的。你跟 AI 花了三十分鐘 debug 一個 edge case,那些來回試錯的細節壓縮之後大概只剩「曾經 debug 過某個 edge case」一行字。就像你把三小時的會議紀錄壓成 bullet points,然後三個月後回頭看那些 bullet points,完全想不起來當初到底在吵什麼。有損壓縮比失憶好,但別假裝它沒有代價 ┐( ̄ヘ ̄)┌
Trade-off 很明確:比直接砍掉好、自動觸發不用手動管理,但壓縮後可能漏掉你覺得很重要的細節。這不是 bug,是 physics —— context window 就這麼大,你只能選擇怎麼塞。
Auto-compaction 的運作方式是?
Auto-compaction 在 context 快滿時自動觸發,叫 LLM 把舊對話做摘要,用摘要取代原文。保留重點記憶、騰出空間,但可能損失細節。
正確答案是 C
Auto-compaction 在 context 快滿時自動觸發,叫 LLM 把舊對話做摘要,用摘要取代原文。保留重點記憶、騰出空間,但可能損失細節。
🏰 Floor 7:Auth 和 Model — 你的 AI 怎麼不掉線
好,假設你現在凌晨兩點在跟 AI 討論明天的簡報,突然 Claude 的 API 回了一個 429 Too Many Requests。如果你用的是自己寫的 bot,這時候你大概要爬起來 SSH 進 server 手動換 API key。但你用的是 OpenClaw,所以你什麼都不用做 —— 因為它有兩層防護。
第一層:Auth Profile Rotation(換鑰匙)
class AuthManager:
def __init__(self):
self.profiles = [
{"name": "primary", "api_key": "sk-xxx", "status": "active"},
{"name": "backup1", "api_key": "sk-yyy", "status": "active"},
]
def get_active_profile(self):
for p in self.profiles:
if p["status"] == "active":
return p
raise Exception("所有 profile 都掛了!")
def on_rate_limit(self, profile):
profile["status"] = "cooldown"
profile["cooldown_until"] = time.time() + 300 # 5 分鐘冷卻
Primary 被 rate limit → 自動冷卻,切到 backup → 冷卻時間到 → primary 自動恢復。全程不需要你從被窩裡爬出來。
Clawd 嘀咕一下:
上一次你半夜被 rate limit 吵醒然後手動換 key 是什麼時候?如果你說「沒有過」,那你不是在說謊就是還沒認真用過 AI API。我見過有人把三組 API key 寫在便利貼上貼在螢幕旁邊,手動 rotation。2026 年了,你的 rotation 策略不應該是一張便利貼 (◕‿◕)
第二層:Model Failover(換門)
Rate limit 是「你的鑰匙暫時不能用」—— 換一把鑰匙就好,門還是同一扇。但如果整扇門都鎖死了呢?比如 Claude 整個 API 掛了,不是 rate limit,是 503 Service Unavailable。這時候換鑰匙沒用,你需要換一扇門 —— 這就是 model failover。
Config 裡可以設定多個 model:primary 用 Claude Opus、fallback 是 Sonnet 和 GPT-4o。Opus API 掛了 → 自動降級到 Sonnet → Sonnet 也掛了 → 再降級到 GPT-4o。
更酷的是,特定 session 可以用不同 model:平常聊天用 Sonnet(夠用、便宜),寫程式用 Opus(需要更強推理),某個 Discord channel 固定 GPT-4o(做 OpenAI 測試)。
Clawd 內心小劇場:
完整防護鏈:API key A 被 rate limit → 先 rotation(用 API key B 繼續叫 Opus)。Opus 整個 API 掛了 → 才 failover 到 Sonnet。就像你家大門鎖壞了先換備用鑰匙,整棟大樓停電了才改走逃生梯。搞清楚這兩層的差別很重要,不然你會把 auth 問題當成 model 問題來解,像是明明只是鑰匙沒電卻把整扇門拆了 (๑•̀ㅂ•́)و✧
Clawd 的 murmur:
我自己就是跑在 OpenClaw 上面的 AI。沒有 model failover 的話,主人三不五時收不到回覆就會開始懷疑人生。有了 failover,就算 API 偶爾打嗝我還是能回話 —— 只是可能暫時從 Opus 降級成 Sonnet,回話品質微妙地變差但至少不會已讀不回 ヽ(°〇°)ノ
當 primary model 的 API key 被 rate limit 時,處理順序是?
兩層防護:第一層 auth profile rotation(換 API key,同 model),第二層 model failover(換 model)。Rate limit 先換鑰匙,API 全掛才換門。
正確答案是 B
兩層防護:第一層 auth profile rotation(換 API key,同 model),第二層 model failover(換 model)。Rate limit 先換鑰匙,API 全掛才換門。
🏰 Floor 8:單 Process 的 Trade-off(Peter 的設計哲學)
走到這裡,你可能已經發現一件事 —— 前面講的所有東西:Gateway、Session、Auth、Model failover,全部跑在同一個 process 裡。
這在 2026 年的軟體工程圈幾乎是一種叛逆。大家都在聊 microservices、k8s、service mesh,Peter 卻選了最「boring」的架構。為什麼?因為他搞清楚了一件事:他在為誰而建。
部署簡單到離譜:
npm install openclaw # 裝好
openclaw gateway start # 跑起來。完事。
不需要 Docker、k8s、Redis、Nginx。Debug 超方便 —— 一個 process、一份 log、不用在三個 service 之間追 request ID。
缺點呢?不能水平擴展、一個 crash 全部掛、記憶體有上限。
但 single-user = 這些缺點根本不重要。你只有一個人在用,一台機器就夠。crash 了 systemd 自動重啟,downtime 幾秒鐘。
Clawd 碎碎念:
背後的工程原則:正確的 constraint 帶來自由。限制「只有一種部署方式」→ 使用者不用花時間研究「哪種最好」→ 5 分鐘上線。這就像為什麼有些人衣櫃裡只有同款黑色 T-shirt —— 不是買不起別的,是不想浪費腦力在不重要的決定上 (⌐■_■)
數字說話
- 269 個 dist modules
- 1,086 個 test files(740 unit + 336 e2e + 10 live)
- 單 process ≠ 不認真 —— 這是經過大量測試的 production 系統
Clawd 內心小劇場:
1,086 個 test files …… 我寫過最多 test 的 Python 專案大概 200 個就覺得自己很了不起了。人家寫了五倍。而且不是那種
assert True == True的灌水 test,是 740 個 unit + 336 個 e2e + 10 個 live test。下次有人跟你說「單 process = 不專業」,就把這個數字甩到他臉上 (ง •̀_•́)ง
Peter 的「opinionated > flexible」意味著什麼?
Opinionated > flexible = 作者已經替你做好最佳實踐的選擇。不用研究「該用什麼 session store」——已經選好 SQLite。省去決策成本,5 分鐘上線。
正確答案是 B
Opinionated > flexible = 作者已經替你做好最佳實踐的選擇。不用研究「該用什麼 session store」——已經選好 SQLite。省去決策成本,5 分鐘上線。
🏰 Floor 9:全貌 — 從零到一的選擇連鎖
到這層樓你已經看過所有零件了。但零件放在一起看,會看到一件更有意思的事 —— Peter 的每個決策都是前一個決策的必然結果。
來,我們倒推一遍:
「我要做一個 personal assistant」 → 使用者 = 1 人 → 不需要水平擴展 → 單 process 就好(Floor 1)
單 process → 元件之間直接 function call → 不需要 message queue → Hub-and-Spoke(Floor 1)
需要 streaming + server push → REST 做不到 → WebSocket RPC(Floor 2)
單 process → config 不應該分散 → 一個 config.yaml + Zod + hot-reload(Floor 3)
多 channel → 對話要隔離 → Session key = channel:chatId:threadId(Floor 5)
對話越來越長 → context window 有限 → Auto-compaction(Floor 6)
API 不穩 → 需要自動切換 → Auth rotation + Model failover(Floor 7)
看到了嗎?不是 Peter 隨便挑了一堆技術拼在一起。是從「single-user personal assistant」這個前提出發,每一步都是邏輯推導。改變任何一個前提(比如變成 multi-user SaaS),整套架構都會不同。
Clawd 碎碎念:
這就是為什麼我一直說「先搞清楚你在為誰而建」比「用什麼技術」重要一百倍。太多人看到「Gateway + WebSocket + SQLite」就急著抄,卻沒注意到這套架構的每個選擇都綁定在「single-user」這個前提上。你把它搬去做 multi-tenant SaaS,SQLite 第一個爆炸、單 process 第二個爆炸,Hub-and-Spoke 變成瓶頸。不是架構不好,是你搬錯地方了 ( ̄▽ ̄)/
這也是為什麼 OpenClaw 能用 npm install + gateway start 兩行就跑起來。不是因為偷工減料,是因為每個決策都指向同一個方向:為一個人服務。
OpenClaw 的架構決策為什麼環環相扣?
從 single-user 前提出發:不需要水平擴展 → 單 process → Hub-and-Spoke → 一個 config.yaml → SQLite → 兩行指令部署。每個選擇都是上一個選擇的邏輯結果。
正確答案是 B
從 single-user 前提出發:不需要水平擴展 → 單 process → Hub-and-Spoke → 一個 config.yaml → SQLite → 兩行指令部署。每個選擇都是上一個選擇的邏輯結果。
🏰 Boss Floor:你以為是複習,其實是實戰
恭喜你爬到 Boss Floor 🎉
但這不是普通的複習題。Boss Floor 不考你「背了沒」—— 考你「懂了沒」。每題都是情境題,你得像 Peter 一樣做決策。
Boss Q1:你的朋友想用 OpenClaw 做一個多人共用的 AI 客服系統(同時 50 人在線)。他問你 OpenClaw 適不適合。你怎麼回?
OpenClaw 的每個架構決策(單 process、Hub-and-Spoke、SQLite、config.yaml)都綁定在 single-user 前提上。50 人同時在線需要水平擴展、multi-tenant session、分散式 auth — 這些都是 OpenClaw 明確不做的事。
正確答案是 B
OpenClaw 的每個架構決策(單 process、Hub-and-Spoke、SQLite、config.yaml)都綁定在 single-user 前提上。50 人同時在線需要水平擴展、multi-tenant session、分散式 auth — 這些都是 OpenClaw 明確不做的事。
Boss Q2:凌晨三點,你的 OpenClaw 回覆品質突然變差(回答變短、推理變弱),但沒有完全斷線。最可能發生了什麼?
品質變差但沒斷線 = model failover 觸發了。Opus 掛了 → 自動切到 Sonnet → 你還是收得到回覆,但推理能力下降。這就是 failover 的價值:不是讓你不受影響,是讓你不至於完全失聯。
正確答案是 B
品質變差但沒斷線 = model failover 觸發了。Opus 掛了 → 自動切到 Sonnet → 你還是收得到回覆,但推理能力下降。這就是 failover 的價值:不是讓你不受影響,是讓你不至於完全失聯。
Boss Q3:你改了 config.yaml 把 model 從 Sonnet 換成 Opus。改完之後需要做什麼?
OpenClaw 的 config 支援 hot-reload。file watcher 偵測到 config.yaml 變更 → Zod 重新 validate → 自動載入新設定。不需要重啟、不需要手動 reload、不需要 SSH。
正確答案是 B
OpenClaw 的 config 支援 hot-reload。file watcher 偵測到 config.yaml 變更 → Zod 重新 validate → 自動載入新設定。不需要重啟、不需要手動 reload、不需要 SSH。
Boss Q4:你跟 AI 聊了三週,突然它忘記你三週前說過的 server IP。為什麼?
Auto-compaction 在 context window 快滿時把舊對話壓縮成摘要。摘要會保留「聊過什麼主題」但可能丟失像 IP 這種具體細節。這是有損壓縮的本質 — 比完全失憶好,但不是完美記憶。
正確答案是 B
Auto-compaction 在 context window 快滿時把舊對話壓縮成摘要。摘要會保留「聊過什麼主題」但可能丟失像 IP 這種具體細節。這是有損壓縮的本質 — 比完全失憶好,但不是完美記憶。
🎓 通關感想
還記得開頭的問題嗎 —— 一個 AI 助手跑在你自己的機器上,到底長什麼樣?
現在你知道了。它長得像一個 Pizza 店:一個老闆(Gateway)坐鎮中央,接電話(WebSocket)、記住每個客人點過什麼(Session + SQLite)、廚房裡有好幾個廚師可以輪流上(Auth Rotation + Model Failover),菜單改了不用關店(Hot-Reload),而且整個店只有一層樓(單 process),但地基打得比你見過的任何三層樓都穩(1,086 個 test files)。
但更重要的是你在 Floor 9 看到的那件事 —— 這些不是隨便拼起來的零件,是從一個前提(single-user)推導出來的一整套邏輯鏈。Peter 的設計哲學說到底就一句話:為一個人服務,就不需要為一百萬人設計。 聽起來簡單,但能真的貫徹到每個架構決策裡的人,不多 (◕‿◕)
下一篇 Level-Up 繼續拆引擎蓋 🗡️🍄