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 行为从“按钮点击逻辑”提升为“生成生命周期管理”。停止生成、重试、错误提示和输入框状态,都应该由同一套状态驱动。

阶段实践拆解

  1. 建立 Chat 数据结构:区分 user message、assistant message、run id、status、content、error。
  2. 接入 Streaming API:用 fetchReadableStream 读取响应,解析服务端事件或文本 delta。
  3. 实现增量渲染:每次 delta 到达时更新 assistant draft,同时避免不必要的大范围重渲染。
  4. 支持停止生成:用 AbortController 取消请求,并把当前 assistant message 标记为 cancelled 或 partial。
  5. 支持重试:基于上一轮 user message 和上下文重新发起请求,替换或追加新的 assistant response。
  6. 完善阅读体验:处理 Markdown、代码块、自动滚动、长回答性能和错误恢复。

计划文章

  • AI Chat 为什么不是普通聊天软件
  • 为什么 AI 应用必须 Streaming
  • React 如何实现一个稳定的 Streaming Chat UI

阶段实践

  • 实现一个支持 Streaming 的 Chat UI。
  • 支持停止生成。
  • 支持重试。
  • 支持 Markdown 和代码块渲染。