Feat: 飞书渠道应整合多轮回复为单条流式卡片消息
Author: yrxevaCreated Aug 27, 2026Updated Sep 7, 2026
问题描述
飞书渠道中,用户发送一条消息后,agent 可能回复 n 条消息(工具提示、进度消息、最终回复等),用户体验较差。希望整合为 一条流式卡片消息,保持 用户发一条消息 → agent 回复一条消息 的对应关系。
当前行为
以飞书渠道为例,当 agent 处理用户请求时:
- 流式输出阶段:通过
send_delta()使用 CardKit 流式卡片(已有实现) - 工具调用阶段:通过
send()发送独立的进度/工具提示消息 - 最终回复阶段:再次通过
send()发送最终内容
导致用户在飞书中看到多条分离的消息。
期望行为
- 用户发一条消息 → agent 回复一条消息
- 所有输出(流式文本、工具提示、进度信息)都应内联到同一条流式卡片中
- 保持现有流式卡片的逐字更新体验
技术分析
从代码看,飞书 channel 已有 send_delta() 实现 CardKit 流式卡片:
nanobot/channels/feishu/runtime.py中_FeishuStreamBuf和send_delta()已支持流式更新- 但
send()方法仍会独立发送消息(工具提示、媒体、最终回复等)
关键问题在 ChannelManager._send_once()(nanobot/channels/manager.py):
StreamDeltaEvent/StreamEndEvent→ 调用send_delta()(流式卡片)- 其他事件(ProgressEvent、普通 OutboundMessage)→ 调用
send()(独立消息)
建议方案
优先方案:在
send_delta()中捕获所有非流式输出,内联到流式卡片- 当有活跃流式卡片时,工具提示/进度消息通过
send_delta()追加到同一卡片 - 最终回复也追加到同一卡片,而非重新调用
send()
- 当有活跃流式卡片时,工具提示/进度消息通过
备选方案:在
ChannelManager层面做路由决策- 检测目标 channel 是否支持流式卡片
- 若支持,将所有输出统一走
send_delta()路径
配置开关:新增
feishu.stream_card.merge_non_stream配置项,控制是否将非流式消息合并到流式卡片
影响范围
- 主要影响飞书渠道(已实现流式卡片)
- 类似实现可扩展到 Discord、Telegram 等支持富文本/卡片的渠道
- 不影响不支持流式的渠道(纯文本渠道保持现有行为)
相关 Component
Channel (Feishu), Channel Manager
附加说明
- 现有
feishu_stream_card插件仅提供启动/关闭通知功能,不解决多消息整合问题 - 飞书 CardKit streaming_mode 已能支持持续更新,技术上可行
Source: HKUDS/nanobot