常规的 HTTP 请求采用“一问一答”的同步交互模式。但实际场景中,“一问多答”(客户端单次请求,服务端分批次返回响应)甚至全双工交互(客户端与服务端双向实时通信)的需求长期存在。

一、主流的流式输出技术

在 HTML5 普及初期,最常见的解决方案是 Websocket。Websocket 基于 TCP 协议,实现了客户端与服务端的全双工通信,适用于需要高频交互的场景(如在线聊天、实时监控)。
但 LLM 普及后,行业几乎清一色选择了 SSE(Server-Sent Events)。核心原因在于,LLM 的回答过程本身就是:“逐字生成返回”,恰好匹配 SSE“一问多答”的特性,无需 Websocket 那样的双向连接,降低了开发和资源消耗。

二、原理:基于 HTTP 的流式传输

SSE 的本质是基于 HTTP 协议的流式传输,依托 ReadableStream 实现。ReadableStream 允许服务端将响应数据拆分为多个“chunk”,分批次发送给客户端,客户端无需等待完整响应,即可逐块接收并渲染,这也是 AI 对话“边思考边输出”效果的核心实现方式。

2.1 HTTP 1.1 中的流式传输

在 HTTP 1.1 协议中,服务端会在响应头中添加 Transfer-Encoding: chunked 字段,用于标记当前响应为“流式返回”。
客户端(如浏览器)识别到该字段后,会按照逐块读取服务端推送的数据;当服务端完成所有数据推送后,会返回一个空 chunk,告知客户端“流已结束”。

2.2 HTTP 2 中的流式传输

HTTP 2 中禁用了 Transfer-Encoding: chunked 字段,通过 header 中的 Content-Length 字段识别流式返回:若该字段为空,说明响应为流式返回(服务端无法提前确定总响应长度);

三、常见的流式 Content-Type 类型及说明

不同的 Content-Type 对应不同的流式场景:
  • text/event-stream:SSE 标准流式类型,也是主流大模型采用的类型;
  • application/*json:泛 JSON 流式类型,其中 * 代表不同的扩展标识(如 KIMI 对话使用 application/connect+json,其他场景常用 application/x-ndjson、application/json),核心特点是“每一个数据块都是一个完整的 JSON 对象”,适用于需要结构化数据的流式场景;
  • application/octet-stream:通用二进制流式类型(如文件分片下载);
  • video/、audio/、image/*:媒体类天然流式类型,如视频、音频、图片的渐进式加载;
  • multipart/x-mixed-replace:多用于实时图像流场景(如摄像头监控、实时截图),可实现“替换式”流式推送,新数据块会覆盖旧数据块。

四、客户端 API

针对 SSE 流式输出,客户端(主要是浏览器)有两种常用的读取方式:
  1. ReadableStream API:通用的流式读取 API,支持所有 HTTP 流式类型(包括 text/event-stream、application/*json 等),灵活性高;
// 简化版:ReadableStream 读取 HTTP 1.1 流式数据(适配AI对话场景)
const streamChat = async () => {
    const response = await fetch('https://your-llm-api.com/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ prompt: '请解释SSE的原理', history: [] })
    });

    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let fullContent = '';

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      const chunk = decoder.decode(value, { stream: true });
      fullContent += chunk;
      document.getElementById('chat-container').innerText = fullContent;
    }

    console.log('流式传输结束,完整内容:', fullContent);
};
  1. EventSource API:浏览器对 SSE(text/event-stream 类型)的原生封装,使用简单,无需手动解析流数据,会自动将服务端推送的内容封装为message 事件。但存在明显局限——仅支持 GET 请求,且没有结束事件的回调。
// EventSource 仅支持 GET 请求,服务端需返回 Content-Type: text/event-stream
const eventSource = new EventSource('https://your-llm-api.com/chat?prompt=请解释SSE的原理');

// 监听服务端推送的消息(流式数据)
eventSource.onmessage = (e) => {
  // e.data 即为服务端推送的单个数据块
  console.log('流式接收数据:', e.data);
  document.getElementById('chat-container').innerText += e.data;
};

五、总结

AI 对话的流式输出,核心是通过 SSE 基于 HTTP 流式传输实现,本质是利用 ReadableStream 将 LLM 生成的内容分批次推送至客户端。
与常规 HTTP 请求相比,SSE 完美匹配 LLM “一问多答”的响应模式。其中,text/event-stream 作为 SSE 标准类型,是主流大模型的首选,而 ReadableStream API 和 EventSource API 则是客户端处理流式数据的工具 API。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐