流式输出与分块
Streaming(流式输出)让用户在 Agent 生成回复时实时看到内容,而非等待完整回复。Chunking(分块)将流式内容按适当大小分割以适配不同渠道。
流式输出基础
核心机制
LLM 以 Token 为单位逐步生成回复。OpenClaw 将这些 Token 增量(Delta)实时传递给用户,实现"打字机"效果。
LLM 生成: [你] [好] [!] [我] [是] [你] [的] [AI] [助] [手] [。]
│ │ │ │ │ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
用户看到: 你好!我是你的AI助手。 ← 逐字出现流式事件类型
OpenClaw 通过 WebSocket 推送三类流式事件:
typescript
// 1. 工具事件 — Agent 正在执行工具
{
stream: 'tool',
name: 'web_search',
status: 'running', // running | completed | failed
input: { query: 'OpenClaw docs' }
}
// 2. 文本增量 — Assistant 回复的实时内容
{
stream: 'text',
delta: '你好!', // 本次增量内容
accumulated: '你好!我是' // 累积内容(可选)
}
// 3. 结束标记 — 回复生成完成
{
stream: 'end',
totalTokens: 156,
finishReason: 'stop'
}分块逻辑(Chunking)
不同渠道对消息有不同的大小和频率限制。Chunking 将连续的流式内容按规则分割:
yaml
chunking:
enabled: true
maxChunkSize: 1000 # 每块最大字符数
flushInterval: 500 # 刷新间隔(毫秒)
splitOn: ["\n\n", "\n", ". ", " "] # 分割优先级分块流程:
LLM Token Stream
│
▼
┌─────────────┐
│ Buffer │ ← 累积 Token
│ 缓冲区 │
└──────┬──────┘
│
├── 达到 maxChunkSize? → 发送并清空缓冲
├── 达到 flushInterval? → 发送并清空缓冲
└── 遇到分割点? → 在分割点处发送智能分割
分块优先在段落边界(\n\n)、换行符(\n)或句号处分割,避免在单词或中文字符中间断开。
blockStreamingDefault
某些渠道不支持或不适合流式输出。使用 blockStreamingDefault 禁用:
yaml
# 全局禁用流式输出
blockStreamingDefault: true
# 按渠道配置
overrides:
whatsapp:
blockStreamingDefault: true # WhatsApp 不支持流式
telegram:
blockStreamingDefault: false # Telegram 支持编辑消息
web:
blockStreamingDefault: false # Web UI 完整支持流式禁用流式后,Agent 会等待完整回复生成后一次性发送。
渠道特定行为
markdown
- ✅ 完整流式支持
- Token 级增量更新
- 支持 Markdown 实时渲染
- 代码块语法高亮markdown
- ✅ 通过编辑消息实现流式
- 每 500ms 更新一次消息内容
- 频繁编辑受 API 速率限制
- 最终消息保留完整格式markdown
- ❌ 不支持流式输出
- 等待完整回复后发送
- 长回复自动分割为多条消息
- 使用 Typing Indicator 提示处理中markdown
- ✅ 通过编辑消息实现流式
- 支持嵌入(Embed)格式
- 2000 字符限制需注意分割缓冲管理
缓冲区(Buffer)控制流式输出的平滑度:
yaml
streaming:
bufferSize: 50 # 缓冲 Token 数
minFlushSize: 10 # 最小刷新大小(字符)
maxBufferTime: 1000 # 最大缓冲时间(毫秒)缓冲策略:
| 参数 | 作用 | 权衡 |
|---|---|---|
bufferSize | 每次发送前累积的 Token 数 | 大 → 更流畅,小 → 更实时 |
minFlushSize | 最少积累多少字符才发送 | 避免过于频繁的小更新 |
maxBufferTime | 缓冲超时强制发送 | 防止长时间无输出 |
错误处理
流式过程中的错误处理:
typescript
// 流式错误事件
{
stream: 'error',
code: 'STREAM_INTERRUPTED',
message: 'Model connection lost',
partial: '已生成的部分内容...'
}中断恢复
流式中断时,已发送的部分内容会保留。Agent 不会自动重试流式输出,但会将错误状态通知用户。
🇨🇳 中国用户须知
- 国内网络环境下,流式输出可能因延迟较高而不够流畅
- 建议增大
bufferSize和flushInterval以减少卡顿感 - 使用国产模型时,流式输出通常延迟更低
下一步
- 了解 输入状态指示
- 查看 Markdown 格式化 了解输出渲染
- 探索 消息格式 了解消息处理
