流式输出与引用展示
流式输出提升体感速度,但引用信息存在一个先后矛盾:引用编号只有在完整答案生成后才能确定,而正文是逐块吐出的。常见做法有两种:正文流式、引用卡片在结束时一次性补发;或者在流式块里保留编号占位符,结束时批量校验并回填。无论哪种方案,引用校验都只能事后执行,因此「发现越界引用后如何撤回或标注」必须纳入错误监控。
基本信息
| 典型协议 | SSE,内容类型 text/event-stream |
|---|---|
| 事件顺序 | token 若干,之后 citations,最后 done |
| 编号确定时机 | 完整答案生成完成之后 |
| 做法一 | 引用卡片在结束时统一补发 |
| 做法二 | 正文留编号占位,结束批量回填 |
| 已知风险 | 边流式边生成编号会与最终列表不一致 |
典型使用场景
- 对话式问答需要首字快速返回,降低等待感
- 长答案场景用户边读边等,体验优于整段输出
- 引用卡片需要在答案结束后统一渲染与排序
- 前端需区分正文流与元数据事件,分别处理
- 结束补发要求客户端正确响应收尾事件
服务端事件顺序
服务端事件顺序
event: token data: {"delta": "根据文档…"} # 正文增量
event: token data: {"delta": "… [1]。"}
event: citations data: {"list": [{"id": 1, "title": "…", "anchor": "…"}]}
event: done data: {} # 收尾标记
# 引用列表在最后一并下发,编号与正文对应关系此时才确定事件读法
| 事件 | 载荷 | 客户端处理 |
|---|---|---|
| token | 增量文本 | 追加渲染,避免整段重建 |
| citations | 引用列表 | 结束后统一渲染引用卡片 |
| done | 结束标记 | 关闭连接并触发收尾逻辑 |
| error | 错误信息 | 提示用户并提供重试入口 |
流式场景下引用校验只能事后执行:发现越界引用后要撤回或标注,这条处理路径必须纳入错误监控与告警,否则错误答案会留在会话里。
客户端必须处理收尾事件:只渲染 token 而忽略 citations 与 done,用户会看到有正文却没有出处的答案。