让聊天界面鲜活起来:从流式回复到实时反馈
§1 流式回复让等待变成可见进展
让聊天界面显得鲜活,不是让按钮不停闪动,而是让用户知道:消息已经送达,回答正在形成,自己随时可以打断。与其等待整段答案突然出现,不如让内容随着生成逐步显示。
这就是流式回复。模型把输出拆成称为词元的小片段,服务端陆续发送,界面持续接收。词元不一定对应一个汉字或一个完整词,因此不要把每个网络片段当成一句话。
§2 发送之后,先给出明确的状态
用户点击发送后,应立即看到自己的消息,以及“正在准备回复”的提示。收到首段文字后,再切换为“正在回复”。结束时撤下状态提示,让完整回答自然留在对话中。
- – 等待阶段显示简短提示,避免空白气泡让人误以为没有发送成功。
- – 生成阶段保留停止按钮,让用户可以中断跑偏或过长的回答。
- – 失败阶段保留原始问题,并提供明确的重试入口。
§3 用事件流把回复接到界面
常见做法是使用服务器发送事件(SSE),让服务器持续向客户端发送更新。浏览器也可以通过流式读取请求响应来消费这些事件,不必每收到一句话就重新请求。
需要注意,网络分块与事件边界并不一致。前端应先缓存尚未完整的数据,再按协议解析事件,把新增内容追加到当前回答。不要直接把每块原始数据都展示给用户。
§4 文字持续出现,也要允许用户阅读
流式显示不等于逐字播放动画。可以短暂合并相邻片段,减少频繁刷新,让文字平稳出现。对于尚未闭合的代码块或列表,也应避免反复改变布局。
当用户停留在底部时,界面可以跟随新内容滚动;一旦用户向上翻阅,就应暂停自动滚动,并显示“有新内容”的提示。屏幕阅读器也不宜逐词播报,可以按句子或段落更新。
§5 停止与断线都应有清楚的结果
点击停止后,不仅要停止文字动画,还应尝试取消实际请求。已经收到的内容可以保留,并标记为“已停止”。取消能否立即生效,以及如何计费,仍取决于接口规则。
断线时不要把半段回答伪装成完整答案,也不要直接拼接一次重新生成的内容。告诉用户连接已中断,再由用户选择重试,比悄悄重复请求更可靠。
§6 用流式接口验证完整聊天体验
如果希望减少接入工作,可以考虑 Fluxio。它是优先支持流式传输、按词元计费的人工智能接口中转服务,可通过一个密钥接入多种模型,例如 Claude Sonnet 5.5,并兼容 OpenAI 软件开发工具包。密钥应保存在自己的服务端,而不是暴露在浏览器里。
上线前,重点测试首段文字多久出现、长回复是否卡顿、停止是否有效,以及断线后能否恢复操作。鲜活感来自及时且诚实的反馈,而不是假装永远没有延迟。
欢迎注册 Fluxio,试试流式聊天。