飞书流式回复配置指南
概述
默认情况下,飞书机器人会等待 AI 任务完全完成后才发送完整消息(static 模式)。开启流式回复后,机器人会在 AI 生成内容的同时,以打字机动画的形式实时推送内容给用户,大幅提升交互体验。
配置方法
方式一:编辑配置文件
编辑 ~/.openclaw/openclaw.json,在 plugins.entries.feishu.config 下添加配置:
{
"plugins": {
"entries": {
"feishu": {
"config": {
"streaming": true,
"replyMode": "streaming"
}
}
}
}
}
方式二:命令行设置
# 开启流式总开关(必须)
openclaw config set plugins.entries.feishu.config.streaming true --json
# 设置回复模式(可选,默认 auto)
openclaw config set plugins.entries.feishu.config.replyMode "streaming"
# 重启生效
openclaw gateway restart
配置字段说明
`streaming`(必须)
布尔总开关,仅设为 true 时允许流式回复,未设置或 false 一律走 static 模式。
`replyMode`(可选)
控制具体哪些场景使用流式回复,支持字符串和对象两种形式。
字符串形式:
| 值 | 行为 |
|---|---|
| `auto`(默认) | 私聊使用流式,群聊使用静态 |
| `streaming` | 所有场景均使用流式 |
| `static` | 所有场景均使用静态 |
对象形式(按场景分别配置):
{
"replyMode": {
"default": "auto",
"group": "streaming",
"direct": "static"
}
}
优先级:replyMode.{scene} > replyMode.default > replyMode(字符串) > "auto"
流式回复的工作原理
整体流程
收到用户消息
→ dispatchToAgent()
→ createFeishuReplyDispatcher()
→ StreamingCardController(状态机)
→ SDK 回调: onPartialReply / onReasoningStream / deliver / onIdle
→ 通过 CardKit API 增量更新卡片内容
核心步骤
1. 创建初始卡片 — 发送一张带 loading 动画的"思考中..."卡片(streaming_mode: true)
2. 流式更新 — AI 每产出一段 token,onPartialReply() 累积文本,经 FlushController 节流后调用 streamCardContent() 增量推送,飞书自动 diff 并以打字机动画渲染
3. 完成关闭 — 所有流完成后,onIdle() 关闭流式模式,执行最终卡片更新(添加操作按钮、footer 指标等)
两条更新路径
| 路径 | 方式 | 说明 |
|---|---|---|
| 主路径 | CardKit v2 原生流式 | 通过 `cardkit.v1.cardElement.content()` API 增量推送,支持打字机动画 |
| 回退路径 | IM Message PATCH | CardKit 失败时,通过 `im.message.patch()` 整体替换卡片 JSON |
节流与防抖
FlushController 负责管理更新频率:
- 可配置的节流间隔(CardKit 和 IM patch 使用不同间隔)
- 防止触发 API 速率限制
- 智能批量合并快速更新
- 长时间空闲后恢复时,短暂批量推送以展示有意义的文本量
关键源码文件
| 文件 | 作用 |
|---|---|
| `src/card/streaming-card-controller.ts` | 流式核心控制器(状态机、生命周期管理) |
| `src/card/reply-dispatcher.ts` | 创建带流式回调的 dispatcher |
| `src/card/reply-mode.ts` | 回复模式解析逻辑 |
| `src/card/cardkit.ts` | CardKit 流式 API 封装 |
| `src/card/flush-controller.ts` | 节流更新调度 |
| `src/card/builder.ts` | 卡片 JSON 构建与样式优化 |
| `src/messaging/outbound/send.ts` | 核心消息/卡片发送函数 |
| `src/messaging/inbound/dispatch.ts` | 消息路由与 agent 分发 |