流式传输 + 分块
OpenClaw 有两个独立的”流式传输”层:- 块流式传输(渠道): 在助手生成内容时发送已完成的块。这些是普通的渠道消息(不是 token 增量)。
- 类 Token 流式传输(仅 Telegram): 在生成过程中用部分文本更新草稿气泡;最终消息在结束时发送。
块流式传输(渠道消息)
块流式传输在助手输出可用时以粗粒度块发送。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:分块器发出块后立即流式传输;在每个text_end时刷新。message_end:等待助手消息完成后,再刷新缓冲输出。
message_end 在缓冲文本超过 maxChars 时仍会使用分块器,因此可能在最后发出多个块。
分块算法(低/高边界)
块分块由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设置(包括按账户的配置)。 - 除非覆盖,Signal/Slack/Discord 的默认合并
minChars会提升至 1500。
块之间的仿真人节奏
当块流式传输启用时,你可以在块回复之间(第一个块之后)添加随机停顿。这让多气泡回复感觉更自然。- 配置:
agents.defaults.humanDelay(通过agents.list[].humanDelay按智能体覆盖)。 - 模式:
off(默认)、natural(800–2500ms)、custom(minMs/maxMs)。 - 仅适用于块回复,不适用于最终回复或工具摘要。
“流式发送块还是一次性发送全部”
对应关系:- 流式发送块:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(边生成边发送)。非 Telegram 渠道还需要设置*.blockStreaming: true。 - 结束时一次性发送:
blockStreamingBreak: "message_end"(刷新一次,如果内容很长可能产生多个块)。 - 不使用块流式传输:
blockStreamingDefault: "off"(仅最终回复)。
*.blockStreaming 显式设置为 true。Telegram 可以通过 channels.telegram.streamMode 进行草稿流式传输,无需块回复。
配置位置提醒:blockStreaming* 默认值位于 agents.defaults 下,而非根配置。
Telegram 草稿流式传输(类 Token)
Telegram 是唯一支持草稿流式传输的渠道:- 在带话题的私聊中使用 Bot API
sendMessageDraft。 channels.telegram.streamMode: "partial" | "block" | "off"。partial:用最新的流式文本更新草稿。block:以分块方式更新草稿(使用相同的分块器规则)。off:不进行草稿流式传输。
- 草稿分块配置(仅用于
streamMode: "block"):channels.telegram.draftChunk(默认值:minChars: 200,maxChars: 800)。 - 草稿流式传输与块流式传输是分离的;块回复默认关闭,仅在非 Telegram 渠道通过
*.blockStreaming: true启用。 - 最终回复仍然是普通消息。
/reasoning stream将推理过程写入草稿气泡(仅 Telegram)。
sendMessageDraft:Telegram 草稿气泡(不是真正的消息)。final reply:普通的 Telegram 消息发送。