Skip to main content

串流 + 分塊

OpenClaw 有兩個獨立的串流層:
  • 區塊串流(頻道): 在助理撰寫時發送完成的區塊。這些是正常的頻道訊息(不是 token delta)。
  • 預覽串流(Telegram/Discord/Slack): 在生成時更新暫時的預覽訊息
目前沒有真正的 token delta 串流到頻道訊息。預覽串流基於訊息(傳送 + 編輯/附加)。

區塊串流(頻道訊息)

區塊串流在助理輸出可用時以粗粒度區塊傳送。
Model output
  └─ text_delta/events
       ├─ (blockStreamingBreak=text_end)
       │    └─ chunker emits blocks as buffer grows
       └─ (blockStreamingBreak=message_end)
            └─ chunker flushes at message_end
                   └─ channel send (block replies)
說明:
  • text_delta/events:模型串流事件(非串流模型可能稀疏)。
  • chunkerEmbeddedBlockChunker 套用最小/最大邊界 + 分割偏好。
  • 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)。
  • 頻道分塊模式:*.chunkModelength 預設,newline 在長度分塊前以空行(段落邊界)分割)。
  • Discord 軟性上限:channels.discord.maxLinesPerMessage(預設 17)分割高回覆以避免 UI 截斷。
邊界語義:
  • text_end:chunker 發送時立即串流區塊;在每個 text_end 時清空。
  • message_end:等待助理訊息完成,然後清空緩衝輸出。
message_end 若緩衝文字超過 maxChars 仍使用 chunker,因此可在結束時發送多個區塊。

分塊演算法(低/高邊界)

區塊分塊由 EmbeddedBlockChunker 實作:
  • 低邊界: 在緩衝區 >= minChars 前不發送(除非強制)。
  • 高邊界: 偏好在 maxChars 前分割;若強制,在 maxChars 處分割。
  • 分割偏好: paragraphnewlinesentencewhitespace → 硬分割。
  • 程式碼圍欄: 永不在圍欄內分割;在 maxChars 強制時,關閉 + 重新開啟圍欄以保持 Markdown 有效。
maxChars 被夾在頻道 textChunkLimit,因此無法超過每頻道上限。

合併(合併串流區塊)

啟用區塊串流時,OpenClaw 可以在傳送前合併連續的區塊。 這在仍提供漸進式輸出的同時減少「單行訊息轟炸」。
  • 合併等待閒置間隔idleMs)後清空。
  • 緩衝區以 maxChars 為上限,超過時清空。
  • minChars 防止微小片段傳送,直到積累足夠文字 (最終清空始終傳送剩餘文字)。
  • 連接符源自 blockStreamingChunk.breakPreferenceparagraph\n\nnewline\nsentence → 空格)。
  • 可透過 *.blockStreamingCoalesce 設定頻道覆蓋(包括每帳號設定)。
  • 預設合併 minChars 對 Signal/Slack/Discord 提升至 1500,除非被覆蓋。

區塊間的人性化節奏

啟用區塊串流時,可以在區塊回覆之間添加隨機暫停(在第一個區塊之後)。這讓多泡泡回覆感覺更自然。
  • 設定:agents.defaults.humanDelay(透過 agents.list[].humanDelay 按 agent 覆蓋)。
  • 模式:off(預設)、natural(800-2500ms)、customminMs/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:生成期間的進度/狀態預覽,完成時顯示最終答案。

頻道對應

頻道offpartialblockprogress
Telegram對應 partial
Discord對應 partial
Slack
僅 Slack:
  • channels.slack.nativeStreamingstreaming=partial 時切換 Slack 原生串流 API 呼叫(預設:true)。
舊版 key 遷移:
  • Telegram:streamMode + 布林值 streaming 自動遷移至 streaming enum。
  • Discord:streamMode + 布林值 streaming 自動遷移至 streaming enum。
  • Slack:streamMode 自動遷移至 streaming enum;布林值 streaming 自動遷移至 nativeStreaming

執行時行為

Telegram:
  • 在 DM 和群組/主題中使用 sendMessage + editMessageText 預覽更新。
  • 當 Telegram 區塊串流明確啟用時跳過預覽串流(以避免雙重串流)。
  • /reasoning stream 可將推理寫入預覽。
Discord:
  • 使用傳送 + 編輯預覽訊息。
  • block 模式使用草稿分塊(draftChunk)。
  • 當 Discord 區塊串流明確啟用時跳過預覽串流。
Slack:
  • partial 可在可用時使用 Slack 原生串流(chat.startStream/append/stop)。
  • block 使用附加式草稿預覽。
  • progress 使用狀態預覽文字,然後顯示最終答案。