AI 对话的流式输出详解——不止于SSE

常规的 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 等),灵活性高;
javascript 复制代码
// 简化版: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 请求,且没有结束事件的回调。
javascript 复制代码
// 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。

相关推荐
晴天168 分钟前
VSCodium 项目介绍
前端·javascript·vscode
世岩清上12 分钟前
展厅数字内容同质化严重,怎样打造专属叙事风格?
大数据·前端·javascript·人工智能·html·音视频·展厅改造
持敬chijing32 分钟前
Web前后端开发-JavaScript 入门教程
开发语言·前端·javascript
掰头战士37 分钟前
AgentLoop: 从 while(true) 到生产级循环
typescript·llm·agent
leoZ23137 分钟前
2026-09-10-静态扫描连错三次-用运行环境当裁判
前端·javascript·vue.js·人工智能·opencv·机器学习·数据挖掘
张忠琳38 分钟前
【deepseek-harness】DeepSeek Harness Agent Loop 模块深度架构分析之二
ai·agent·deepseek·harness·dsh
Albart57538 分钟前
大模型无限循环输出、重复生成文本:参数层面规避幻觉输出实战
大模型·llm·vllm·大模型推理·幻觉·重复输出
Maxkim41 分钟前
我把一个"会自己查资料"的 AI 助手塞进了浏览器侧边栏,开源了
前端·javascript
mONESY1 小时前
LangChain 结构化输出进阶:with_structured_output 做了什么,以及它为什么流不起来
javascript
玉宇夕落1 小时前
llm模块二 结构化输出 LangChain 结构化输出完全指南:从 JSON 解析到 withStructuredOutput
langchain·llm