流式传输 + 分块
OpenClaw 有两个独立的”流式传输”层:- 块流式传输(频道): 在助手写入时发出已完成的块。这些是普通的频道消息(不是令牌增量)。
- 令牌式流式传输(仅限 Telegram): 在生成时用部分文本更新草稿气泡;最终消息在结束时发送。
块流式传输(频道消息)
块流式传输在助手输出可用时以粗略的块发送。text_delta/事件:模型流事件(对于非流式模型可能稀疏)。分块器:EmbeddedBlockChunker应用最小/最大边界 + 中断偏好。频道发送:实际的出站消息(块回复)。
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:等待助手消息完成,然后刷新缓冲的输出。
maxChars,message_end 仍然使用分块器,因此它可以在结束时发出多个块。
分块算法(低/高边界)
块分块由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覆盖每个 Agent)。 - 模式:
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 草稿流式传输(令牌式)
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 草稿气泡(不是真正的消息)。最终回复:普通 Telegram 消息发送。