Streaming 与 AI Chat 前端工程
这个主题会回到前端主场:如何实现一个稳定、可中断、可重试、体验自然的 AI Chat UI。
AI Chat 不是把消息列表渲染出来这么简单。模型回答是逐步生成的,请求可能持续几十秒,用户也会在生成中途停止、重试、切换页面或继续输入。这个阶段的重点,是把“等待一个完整响应”改造成“管理一次正在发生的生成过程”。
学习目标
完成这个主题后,你应该能够:
- 解释为什么 AI Chat 需要 Streaming,而不是等完整响应返回后再渲染。
- 理解 SSE、ReadableStream、chunk、delta、done event 在前端链路中的位置。
- 设计 message、run、assistant draft、error、cancelled 等状态。
- 在 React 中实现增量渲染、停止生成、重试和失败恢复。
- 处理 Markdown、代码块、滚动、输入禁用和并发请求等体验细节。
关键概念
Streaming 指服务端把模型生成过程拆成一小段一小段传给前端。前端不再等待最终文本,而是在 token 或 delta 到达时持续更新 UI。
SSE 是常见的单向事件流协议,适合“服务端持续推送,客户端只接收”的模型输出场景。它比 WebSocket 更简单,也更符合大多数 Chat Completion 的响应形态。
ReadableStream 是浏览器层面对流式数据的读取接口。它让前端可以用 reader.read() 消费 chunk,并逐步解析事件。
AI Message 状态 不是普通聊天消息状态。普通消息通常只有发送中、成功、失败;AI 消息还需要表达“正在生成”“被中断”“可重试”“部分完成”“工具调用中”等过程状态。
Streaming 状态机
这张状态机图帮助你把 UI 行为从“按钮点击逻辑”提升为“生成生命周期管理”。停止生成、重试、错误提示和输入框状态,都应该由同一套状态驱动。
阶段实践拆解
- 建立 Chat 数据结构:区分 user message、assistant message、run id、status、content、error。
- 接入 Streaming API:用
fetch和ReadableStream读取响应,解析服务端事件或文本 delta。 - 实现增量渲染:每次 delta 到达时更新 assistant draft,同时避免不必要的大范围重渲染。
- 支持停止生成:用
AbortController取消请求,并把当前 assistant message 标记为 cancelled 或 partial。 - 支持重试:基于上一轮 user message 和上下文重新发起请求,替换或追加新的 assistant response。
- 完善阅读体验:处理 Markdown、代码块、自动滚动、长回答性能和错误恢复。
计划文章
- AI Chat 为什么不是普通聊天软件
- 为什么 AI 应用必须 Streaming
- React 如何实现一个稳定的 Streaming Chat UI
阶段实践
- 实现一个支持 Streaming 的 Chat UI。
- 支持停止生成。
- 支持重试。
- 支持 Markdown 和代码块渲染。