串流 + 分塊
OpenClaw 有兩個獨立的串流層:- 區塊串流(頻道): 在助理撰寫時發送完成的區塊。這些是正常的頻道訊息(不是 token delta)。
- 預覽串流(Telegram/Discord/Slack): 在生成時更新暫時的預覽訊息。
區塊串流(頻道訊息)
區塊串流在助理輸出可用時以粗粒度區塊傳送。text_delta/events:模型串流事件(非串流模型可能稀疏)。chunker:EmbeddedBlockChunker套用最小/最大邊界 + 分割偏好。channel send:實際的出站訊息(區塊回覆)。
agents.defaults.blockStreamingDefault:"on"/"off"(預設關閉)。- 頻道覆蓋:
*.blockStreaming(及每帳號變體)強制每個頻道"on"/"off"。 agents.defaults.blockStreamingBreak:"text_end"或"message_end"。agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }。agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(傳送前合併串流區塊)。- 頻道硬性上限:
*.textChunkLimit(例如channels.whatsapp.textChunkLimit)。 - 頻道分塊模式:
*.chunkMode(length預設,newline在長度分塊前以空行(段落邊界)分割)。 - Discord 軟性上限:
channels.discord.maxLinesPerMessage(預設 17)分割高回覆以避免 UI 截斷。
text_end:chunker 發送時立即串流區塊;在每個text_end時清空。message_end:等待助理訊息完成,然後清空緩衝輸出。
message_end 若緩衝文字超過 maxChars 仍使用 chunker,因此可在結束時發送多個區塊。
分塊演算法(低/高邊界)
區塊分塊由EmbeddedBlockChunker 實作:
- 低邊界: 在緩衝區 >=
minChars前不發送(除非強制)。 - 高邊界: 偏好在
maxChars前分割;若強制,在maxChars處分割。 - 分割偏好:
paragraph→newline→sentence→whitespace→ 硬分割。 - 程式碼圍欄: 永不在圍欄內分割;在
maxChars強制時,關閉 + 重新開啟圍欄以保持 Markdown 有效。
maxChars 被夾在頻道 textChunkLimit,因此無法超過每頻道上限。
合併(合併串流區塊)
啟用區塊串流時,OpenClaw 可以在傳送前合併連續的區塊。 這在仍提供漸進式輸出的同時減少「單行訊息轟炸」。- 合併等待閒置間隔(
idleMs)後清空。 - 緩衝區以
maxChars為上限,超過時清空。 minChars防止微小片段傳送,直到積累足夠文字 (最終清空始終傳送剩餘文字)。- 連接符源自
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ 空格)。 - 可透過
*.blockStreamingCoalesce設定頻道覆蓋(包括每帳號設定)。 - 預設合併
minChars對 Signal/Slack/Discord 提升至 1500,除非被覆蓋。
區塊間的人性化節奏
啟用區塊串流時,可以在區塊回覆之間添加隨機暫停(在第一個區塊之後)。這讓多泡泡回覆感覺更自然。- 設定:
agents.defaults.humanDelay(透過agents.list[].humanDelay按 agent 覆蓋)。 - 模式:
off(預設)、natural(800-2500ms)、custom(minMs/maxMs)。 - 僅適用於區塊回覆,不適用於最終回覆或工具摘要。
「串流區塊或全部」
對應關係:- 串流區塊:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(隨時發送)。非 Telegram 頻道也需要*.blockStreaming: true。 - 全部在結束時串流:
blockStreamingBreak: "message_end"(清空一次,若很長可能有多個區塊)。 - 無區塊串流:
blockStreamingDefault: "off"(僅最終回覆)。
*.blockStreaming 明確設為 true。頻道可以串流即時預覽
(channels.<channel>.streaming)而不使用區塊回覆。
設定位置提醒:blockStreaming* 預設值位於
agents.defaults 下,不在根設定中。
預覽串流模式
標準 key:channels.<channel>.streaming
模式:
off:停用預覽串流。partial:單一預覽,以最新文字替換。block:以分塊/附加步驟更新預覽。progress:生成期間的進度/狀態預覽,完成時顯示最終答案。
頻道對應
| 頻道 | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | 對應 partial |
| Discord | ✅ | ✅ | ✅ | 對應 partial |
| Slack | ✅ | ✅ | ✅ | ✅ |
channels.slack.nativeStreaming在streaming=partial時切換 Slack 原生串流 API 呼叫(預設:true)。
- Telegram:
streamMode+ 布林值streaming自動遷移至streamingenum。 - Discord:
streamMode+ 布林值streaming自動遷移至streamingenum。 - Slack:
streamMode自動遷移至streamingenum;布林值streaming自動遷移至nativeStreaming。
執行時行為
Telegram:- 在 DM 和群組/主題中使用
sendMessage+editMessageText預覽更新。 - 當 Telegram 區塊串流明確啟用時跳過預覽串流(以避免雙重串流)。
/reasoning stream可將推理寫入預覽。
- 使用傳送 + 編輯預覽訊息。
block模式使用草稿分塊(draftChunk)。- 當 Discord 區塊串流明確啟用時跳過預覽串流。
partial可在可用時使用 Slack 原生串流(chat.startStream/append/stop)。block使用附加式草稿預覽。progress使用狀態預覽文字,然後顯示最終答案。