02 · 一條訊息的旅程
拆解一條訊息從渠道進入 OpenClaw 到 Agent 回覆的完整鏈路,包括路由、session、佇列、上下文、工具和回覆分塊。
你在 Telegram、Discord 或 Slack 裡發一句:“幫我查一下伺服器狀態。”
表面上看,這是一次普通聊天。實際上,這條訊息進入 OpenClaw 之後,會經過渠道標準化、路由、session 定位、佇列、上下文組裝、模型呼叫、工具迴圈、回覆投遞等多個階段。
理解這條路徑的價值很直接:以後 Agent 不回覆、回覆重複、答非所問、群聊亂觸發、長回覆切壞,你知道該查哪一層,而不是隻說“AI 壞了”。
這一篇的核心不是背流程,而是建立排錯順序:入口、許可權、路由、session、佇列、context,再到模型和工具。
1. 全鏈路先看一遍
OpenClaw 官方訊息文件把高層流程概括成:inbound message → routing/bindings → session key → queue → agent run → outbound replies。展開後可以這樣理解:
flowchart TD
Inbound[外部訊息] --> Channel[Channel 標準化]
Channel --> Policy[DM / group / mention 策略]
Policy --> Routing[Binding 路由]
Routing --> Session[Session key]
Session --> Queue[Queue / steer / followup]
Queue --> Context[Context 組裝]
Context --> Model[模型呼叫]
Model --> Tools{需要工具嗎}
Tools -->|是| ToolRun[工具執行]
ToolRun --> Context
Tools -->|否| Reply[回覆生成]
Reply --> Chunk[Streaming / chunking]
Chunk --> Outbound[發回原渠道]
這條鏈路裡,真正需要模型參與的主要是模型呼叫和工具迴圈。前面的路由、session、佇列,大多是確定性系統邏輯。多數“訊息沒到”問題,不是模型能力問題,而是入口、路由或許可權問題。
2. 八個階段
| 階段 | 系統在做什麼 | 常見故障 |
|---|---|---|
| Channel 標準化 | 把 Telegram、Slack、Discord 等平臺訊息轉成內部格式 | channel auth、賬號狀態、平臺 webhook |
| 訪問策略 | 判斷 DM、群組、mention、allowlist、pairing 是否允許觸發 | 群聊不回、私信被拒絕 |
| Binding 路由 | 按 channel、account、peer、team、guild 等規則選 Agent | 發給了錯誤 Agent |
| Session 定位 | 用 session key 找到對話桶和 transcript | 上下文串臺、歷史丟失 |
| Queue 處理 | 當前 session 忙時決定 steer、排隊、合併或中斷 | 回覆延遲、重複回覆 |
| Context 組裝 | 把系統提示、workspace、記憶、歷史、當前訊息拼成輸入 | 答非所問、忘記規則 |
| Agent run | 模型推理,必要時呼叫工具,多輪迴圈 | 卡住、超時、工具失敗 |
| Outbound 投遞 | 分塊、流式、執行緒回覆、發回原渠道 | 長訊息切壞、發錯執行緒 |
新手排錯時不要從第 7 階段開始。先確認前 4 個階段:訊息有沒有進來、是否允許觸發、路由到哪個 Agent、session key 是哪個。
多數“Agent 沒反應”的問題,不在模型,而在訊息是否進來、是否被允許觸發、是否路由到正確 Agent。
3. Channel 標準化:先把平臺差異抹平
不同渠道的訊息格式完全不同。Telegram 有 chat id、message id、topic;Slack 有 team、channel、thread;Discord 有 guild、channel、author、thread。Gateway 不能讓後面的 Agent 分別理解每個平臺的原始格式。
Channel 層的職責是把外部訊息統一成 OpenClaw 能處理的內部訊息,並保留必要的路由後設資料:
- sender / user id 主要影響 DM allowlist、pairing、session key。
- group / room / channel id 主要影響群組策略、binding、session key。
- thread / topic id 主要影響執行緒或 topic 隔離。
- accountId 主要影響多賬號隔離和預設賬號選擇。
- message id 主要影響去重和 reply threading。
- text / media / reply context 會進入當前 prompt、附件和引用上下文。
這一步一般不需要 AI 判斷。它越確定,後面的行為越穩定。
4. 訪問策略:不是每條訊息都應該觸發 Agent
訊息標準化之後,系統先判斷這條訊息有沒有資格觸發 Agent:
- 私信不回:看 DM policy、pairing、allowFrom。
- 群裡不回:看 group policy、group allowlist。
- 群裡隨便一句就觸發:看 mention gating 是否配置。
- 多賬號訊息混亂:看 accountId 和 defaultAccount。
- 執行緒回覆不對:看 thread / topic 解析和 replyToMode。
這一層的目標不是“儘量多回復”,而是“只在該回復的時候回覆”。OpenClaw 面向的是能呼叫工具的 Agent,入口預設應該收緊。
5. Binding 路由:模型不決定訊息給誰
OpenClaw 路由是確定性的。官方 channel routing 文件列出的匹配順序包括 exact peer、parent peer、Discord guild / roles、Slack team、account、channel、default agent 等。
flowchart TD
Msg[標準化訊息] --> Exact[exact peer]
Exact --> Parent[parent peer / thread]
Parent --> Guild[Discord guild / roles]
Guild --> Team[Slack team]
Team --> Account[accountId]
Account --> Channel[channel match]
Channel --> Default[default agent]
| 路由條件 | 適合場景 |
|---|---|
| exact peer | 某個固定群、頻道、私信入口進指定 Agent |
| guild / roles | Discord 伺服器按角色分流 |
| teamId | Slack workspace 級分流 |
| accountId | 同一渠道多個賬號分流 |
| channel match | 所有 Telegram 或 Slack 入口統一進某 Agent |
| default agent | 沒匹配到規則時兜底 |
重要的是:路由不讓模型自由發揮。模型不應該決定“這條訊息交給誰”。如果這一步讓 AI 猜,系統就不可預測。
路由越確定,系統越可審計。AI 負責生成回覆,配置負責決定訊息歸屬。
6. Session key:找到正確的對話桶
路由選出 Agent 之後,還要決定這條訊息屬於哪個 session。Session 是對話上下文和併發控制的基本單位。
常見 session key 形狀:
- Agent main session:
agent:{agentId}:main。 - 群組:
agent:{agentId}:{channel}:group:{id}。 - 頻道 / 房間:
agent:{agentId}:{channel}:channel:{id}。 - Slack / Discord thread:在基礎 key 後追加
:thread:{threadId}。 - Telegram forum topic:在 group key 中包含
:topic:{topicId}。
session key 解決兩個問題:
- 上下文隔離:不同人、不同群、不同執行緒不要混在一起。
- 併發控制:同一個 session 同一時間只允許一個 active run。
很多“Agent 怎麼把 A 群的上下文帶到 B 群了”這類問題,本質都要回到 session key 設計。
7. Inbound dedupe 和 debounce
現實裡的訊息入口不乾淨。網路重連、平臺重試、使用者分多條傳送,都會讓系統收到比你想象更多的訊息。
7.1 去重解決重複投遞
Channel 可能重複投遞同一條訊息。OpenClaw 會用 channel、account、peer、session、message id 等資訊做短期快取,避免同一訊息觸發多次 agent run。
如果使用者說“怎麼回了兩次”,先看訊息 id 是否重複進入、channel 是否重連、Gateway 日誌是否顯示重複 run。
7.2 防抖解決分條傳送
使用者經常這樣發:
帮我查一下
服务器状态
主要看 CPU 和内存如果每一條都立刻觸發模型,系統會浪費三次呼叫,還可能因為第一條意圖不完整而答偏。messages.inbound.debounceMs 會把同一 sender 在短時間內的連續文本訊息合成一次 agent turn。
相關配置先記四個點:
messages.inbound.debounceMs:全域性防抖視窗,預設常見寫法是 2000ms。messages.inbound.byChannel.whatsapp:WhatsApp 這類分條習慣明顯的平臺可以更長。- media / attachments:通常立即 flush,不和純文本一樣等待。
- control commands:通常獨立處理,不應被普通訊息合併。
防抖不是越長越好。太短會重複處理,太長會讓使用者覺得系統慢。
8. Queue:Agent 正忙時怎麼辦
同一個 session 同時跑兩個 Agent turn 會破壞上下文一致性,所以 OpenClaw 用佇列保證同一 session 的執行被序列管理。
官方佇列文件裡,當前預設模式是 steer。常見模式可以這樣理解:
| 模式 | 行為 | 適合場景 |
|---|---|---|
steer | 把新訊息注入當前 run 的下一個模型邊界;不行就 fallback 到 followup | 使用者經常中途糾正方向 |
followup | 當前 run 結束後逐條處理 | 每條訊息都應獨立響應 |
collect | 當前 run 後把等待訊息合併為一次 followup | 使用者會連續補充上下文 |
steer-backlog | 既嘗試 steer,也保留 followup | 需要即時性但要避免丟後續 |
interrupt | 中斷當前 run,處理最新訊息 | 舊任務可拋棄的場景 |
queue | legacy one-at-a-time steering | 只為相容舊行為 |
如果你看到 Agent “等很久才回”,不一定是模型慢,也可能是 session 正在排隊。看 Gateway 日誌、openclaw status 和任務狀態,比盲目調 prompt 更有用。
9. Context 組裝:AI 看到的遠不止你那句話
當訊息真正進入 Agent run,系統會把多種上下文拼起來:
- system prompt 定義執行規則、工具邊界、行為約束。
- workspace bootstrap 包括
AGENTS.md、SOUL.md、TOOLS.md、USER.md等。 - memory 提供長期事實、偏好、近期記憶。
- session transcript 提供當前 session 歷史。
- group pending history 提供群聊中未觸發 run 但可作為背景的訊息。
- current message 是使用者這次真正要回復的內容。
- reply / forward metadata 提供被引用訊息、轉發上下文。
你發的一句話,通常只是最終輸入包的一小部分。Agent 答非所問時,不要只看使用者訊息,要看 system prompt、workspace 檔案、歷史 transcript 和 memory 有沒有汙染或缺失。
flowchart TD
System[System prompt] --> Prompt[模型輸入]
Workspace[Workspace files] --> Prompt
Memory[Memory / notes] --> Prompt
History[Session history] --> Prompt
Current[Current message] --> Prompt
Prompt --> Model[Model]
理解 context 組裝,是理解“為什麼同一句話有時快、有時慢、有時答偏”的關鍵。
Agent 答非所問時,不要只改 prompt。先看本輪 context 裡混進了什麼、缺了什麼、歷史有沒有汙染。
10. Agent run:模型、工具和多輪迴圈
模型第一次收到 context 後,不一定馬上給最終回覆。它可能決定呼叫工具:
- 查狀態。
- 讀取日誌。
- 根據日誌再查程序。
- 再生成結論。
每次工具結果都會回到 context,模型再決定下一步。這就是 Agent loop。
常見現象可以先這樣判斷:
- 一直轉圈:可能是工具執行慢、provider 慢、session 佇列未釋放。
- 反覆呼叫同一個工具:可能是指令不清、工具結果不足、loop detection 觸發前仍在嘗試。
- 工具失敗但 Agent 繼續:錯誤被當作工具結果回到模型,由模型決定替代路徑。
- 上下文突然變大:可能是工具輸出太長、歷史太長、workspace 檔案太重。
工具失敗不是系統崩潰。失敗資訊也是上下文的一部分。問題在於 Agent 是否能從錯誤裡找到下一步。
11. Streaming、chunking 和最終投遞
模型生成結果後,OpenClaw 還要把回覆發回原渠道。這裡有兩個容易混淆的概念:
- Block streaming:把已完成的文本塊作為正常 channel message 提前發出。
- Preview streaming:在 Telegram、Discord、Slack 等支援的渠道上更新臨時預覽訊息。
官方 streaming 文件強調:今天的 channel message 不是直接 token delta 流。它更像“文本塊或預覽訊息的漸進更新”。
長回覆還要做 chunking。Chunking 會尊重平臺文本長度限制,並儘量不要切壞 Markdown,尤其是 fenced code。切分順序通常從最自然到最後兜底:
- paragraph。
- newline。
- sentence。
- whitespace。
- hard break。
如果長回覆在 Discord 或 Telegram 裡看起來很碎,先看 block streaming、chunk limits、coalescing 和 channel text limit,而不是先怪模型。
12. Silent reply:做了事但不打擾
OpenClaw 支援 silent reply。精確的 NO_REPLY / no_reply 表示不要發使用者可見文本。它適合內部 orchestration、群聊靜默、某些心跳或後臺事件。
但 silent reply 有邊界:
- direct conversation 預設不應悄悄吞掉所有回覆。
- 有媒體附件時,靜默文本可被去掉,但附件仍可能投遞。
- group / channel 和 internal orchestration 的預設策略不同。
使用者沒看到回覆,不一定代表 Agent 沒跑。要結合 logs、tasks、session transcript 判斷。
13. 常見故障怎麼定位
- 完全沒反應:優先查 Channel auth、Gateway 是否線上、DM/group policy、mention gating。
- 發給錯 Agent:優先查 bindings、accountId、peer、default agent。
- 上下文串臺:優先查 session key、thread/topic、dmScope、WebChat main session。
- 回覆重複:優先查 inbound dedupe、平臺重投遞、steer-backlog、block/preview 雙路徑。
- 使用者分三條導致三次回覆:優先查 inbound debounce 配置。
- Agent 很慢:優先查 context 大小、provider、工具耗時、session queue。
- 長回覆切得難看:優先查 chunk limit、block streaming、code fence、channel 限制。
- 群裡不該回復卻回覆:優先查 group allowlist、mentionPatterns、activation gating。
按階段定位,比調 prompt 更可靠。
14. 給 Agent 的實踐任務
如果你已經有 OpenClaw 環境,可以讓本地 Agent 幫你檢查訊息路徑:
请只读检查 OpenClaw 消息管道:
1. 查看 openclaw status 和 gateway status,确认 Gateway 是否在线。
2. 读取 openclaw.json,列出 messages.inbound、messages.queue、bindings、channels 的关键设置。
3. 不打印任何 token、botToken、secret、auth profile。
4. 解释一条 Telegram 或 Slack 消息会路由到哪个 Agent,以及 session key 大概如何形成。
5. 如果当前配置有群聊入口,检查 allowlist、mention gating 和 pairing 边界。沒有本地環境時,就讓 Agent 讀官方 messages、channel routing、queue、streaming 文件,按你的目標渠道生成一份排錯表。
15. 本章自檢
讀完這一章,你應該能回答:
- 一條訊息進入 OpenClaw 後,哪幾步不需要模型參與?
- Binding 路由為什麼必須是確定性的?
- session key 解決了哪兩個問題?
- dedupe、debounce、queue 分別解決什麼問題?
- Agent 答非所問時,為什麼要檢查 context 而不是隻改使用者 prompt?
- block streaming 和 preview streaming 有什麼區別?
16. 接下來去哪
03 · Agent 的大腦
繼續看模型如何在推理、工具呼叫、觀察結果和最終回覆之間迴圈。
01 · 給 AI 一個家
回到 OpenClaw 的整體心智模型,理解 Gateway、Agent、Workspace 和 Channel 的分工。
官方教程:Channels
對照官方配置口徑繼續看 channel、account、routing 和訊息入口。
17. 官方資料
- Messages:https://docs.openclaw.ai/concepts/messages
- Channel routing:https://docs.openclaw.ai/channels/channel-routing
- Command queue:https://docs.openclaw.ai/concepts/queue
- Streaming and chunking:https://docs.openclaw.ai/concepts/streaming