跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonNode.jsAI大前端

流式输出技术解析:后端生成与前端渲染

流式输出原理及前后端实现方案。后端通过 SSE 技术和 HTTP 分块传输实现数据实时推送,涵盖 FastAPI 与 Node.js 代码示例及 Nginx 配置要点。前端采用 Fetch+ReadableStream 或 EventSource 处理流数据,重点解决了 Markdown 渲染性能优化及数据截断缓冲问题,适用于 AI 大模型对话场景。

邪神洛基发布于 2026/4/6更新于 2026/7/849 浏览

什么是流式输出,后端怎么生成,前端怎么渲染

流式输出(Streaming Output) 就像是在看视频直播,内容是一边产生一边传输给你的,而不是像下载电影那样,必须等整个文件下完才能开始看。

在 AI 领域(比如 ChatGPT),流式输出表现为文字一个接一个地'蹦'出来,而不是转半天圈圈后突然甩出一大段话。


什么是流式输出,有什么特点

1. 它是怎么实现的?

流式输出的核心技术通常是 SSE (Server-Sent Events,服务器发送事件)。

在传统的 HTTP 请求中,模式是'一问一答':客户端发请求,服务器处理完全部逻辑,打成一个大包发回客户端。而在流式输出中,过程如下:

  1. 建立持久连接:客户端发送一个请求,并在 HTTP 头部声明 Accept: text/event-stream。
  2. 分块传输:服务器每生成一个字(或一个 Token),就立即将其封装成一个小数据块发送出去。
  3. 保持连接:直到内容生成完毕,服务器才会发送一个特殊的结束标志(如 [DONE]),随后关闭连接。

2. 流式输出的特点
特点说明
低首字节延迟 (TTFB)用户能瞬间看到反馈,大大缓解了等待焦虑。
实时性适合长文本生成。如果是普通模式,生成 1000 字可能需要 20 秒,流式模式下第 1 秒就开始显示。
单向通讯不同于 WebSocket 的双向奔跑,SSE 主要是服务器向客户端'单向投喂'数据。
资源占用因为要长时间维持一个 HTTP 连接,对服务器的并发处理能力有一定要求。

3. 为什么 AI 必须用它?

大语言模型(LLM)的推理过程是自回归的。简单来说,它每生成一个词,都要基于前面所有的词重新算一遍概率。

P(w_{t+1} | w_1, w_2, ..., w_t)

这个过程本身就很耗时。如果等 2000 个 Token 全部算完再给用户,用户可能以为网页卡死了。流式输出完美契合了模型'一个一个词往外蹦'的运行逻辑。


后端怎么实现

在后端实现流式输出,本质上是打破'处理完全部逻辑再返回'的传统模式,改为利用 HTTP 分块传输(Chunked Transfer Encoding) 持续向客户端推送数据。

最常见的方法是使用 SSE (Server-Sent Events)。下面我以 Python (FastAPI) 和 Node.js (Express) 为例展示核心逻辑。


1. Python 实现 (以 FastAPI 为例)

FastAPI 内置了 StreamingResponse,非常适合配合大模型的生成器(Generator)使用。

from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()


  ():
      ():
         i  ():
             
     StreamingResponse(generate(), media_type=)
@app.get("/stream")
async
def
stream
async
def
generate
for
in
range
10
yield
f"data: {i}\n\n"
return
"text/event-stream"

2. Node.js 实现 (以 Express 为例)

在 Node.js 中,通过手动设置 HTTP 响应头并使用 res.write() 来持续发送数据。

const express = require('express');
const app = express();

app.get('/stream', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  let count = 0;
  const interval = setInterval(() => {
    res.write(`data: ${count++}\n\n`);
  }, 1000);
  req.on('close', () => clearInterval(interval));
});

3. 实现的关键要素

要确保后端流式输出成功,必须满足以下几个条件:

  • 正确的 Content-Type: 必须设置为 text/event-stream。
  • 禁用缓冲 (Buffering):
    • 如果你使用了 Nginx 等反向代理,它可能会默认缓存后端的数据,攒够一波再发给前端。
    • 解决方法: 在 Nginx 配置中设置 proxy_buffering off;,或者让后端返回 X-Accel-Buffering: no 响应头。
  • 特定的数据格式:
    • 每条消息必须以 data: 开头。
    • 每条消息必须以两个换行符 \n\n 结尾。

4. 进阶:如何对接大模型 (LLM)

如果你是在调用 OpenAI 或 Anthropic 的 API,它们通常提供 stream=True 参数。你的后端实际上充当了一个中转站(Proxy):

  1. 后端调用 AI API(开启流式)。
  2. 后端迭代接收 AI 返回的每一个 Chunk。
  3. 后端立刻将这个 Chunk 转发给前端。

前端怎么实现

在前端捕获流式数据,主要有两种主流方案:传统的 EventSource 和现代的 fetch + ReadableStream。

由于现在的 AI 接口(如 OpenAI)大多使用 POST 请求,方案二 (fetch) 是目前最通用的做法。


方案一:使用 fetch 结合 ReadableStream (推荐)

fetch API 本身支持流式读取。通过 response.body,你可以获取一个读取器(Reader),逐块解析数据。

const response = await fetch('/api/stream', { method: 'POST' });
const reader = response.body.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(new TextDecoder().decode(value));
}

方案二:使用 EventSource (仅限 GET)

如果你的后端接口支持 GET 请求,EventSource 是最简单的原生实现,它会自动处理重连和心跳。


核心难点:如何优雅地'渲染'?

在处理 AI 流式输出时,你可能会遇到以下两个坑:

  1. Markdown 渲染:数据是一点点出来的,如果你每出一个字就渲染一次 Markdown,性能会炸掉。
    • 对策:使用带缓存的渲染库(如 markdown-it),并限制渲染频率(如 100ms 刷新一次)。
  2. 数据截断:有时候一个 Unicode 字符或者一个 JSON 字符串会被拆分到两个不同的 Data Chunk 中。
    • 对策:在前端维护一个缓冲区(Buffer),将接收到的 value 累加,直到匹配到完整的 \n\n 再进行解析。

目录

  1. 什么是流式输出,后端怎么生成,前端怎么渲染
  2. 什么是流式输出,有什么特点
  3. 1. 它是怎么实现的?
  4. 2. 流式输出的特点
  5. 3. 为什么 AI 必须用它?
  6. 后端怎么实现
  7. 1. Python 实现 (以 FastAPI 为例)
  8. 2. Node.js 实现 (以 Express 为例)
  9. 3. 实现的关键要素
  10. 4. 进阶:如何对接大模型 (LLM)
  11. 前端怎么实现
  12. 方案一:使用 fetch 结合 ReadableStream (推荐)
  13. 方案二:使用 EventSource (仅限 GET)
  14. 核心难点:如何优雅地“渲染”?
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 本地化部署 GraphRAG+LangChain+Ollama 驱动 LLaMa 3.1 集成 Neo4j 实战
  • ToDesk 推出 ToClaw:AI 助手可执行电脑操作
  • Spring Boot 企业员工薪酬管理系统设计与实现
  • MCPHost:命令行下利用 MCP 协议与大模型交互的实践
  • Spring Boot 实战:前端匹配界面与后端 WebSocket 通信实现
  • Prometheus 监控盲区解决方案:使用 Pushgateway 可视化临时任务
  • 医疗 AI 场景下朴素贝叶斯算法深度解析
  • C++ 异常处理机制与自定义异常体系
  • MCP Python SDK 核心概念与实战指南
  • MAVROS 安装指南、基础概念与 ROS C++ 仿真实战
  • CoPaw:协同个人智能体工作台介绍与体验
  • Python 核心面试题解析:模块、装饰器与异步编程
  • WebRTC 直播流前端播放方案:原生与封装库对比
  • 基于 Django 框架搭建 WebAPI 项目
  • 数据库连接池配置策略:高并发下的性能优化实践
  • Apache SkyWalking 主流中间件集成实战:Spring Cloud、Dubbo、RocketMQ
  • Visual Studio 关闭 GitHub Copilot AI 代码提示方法
  • OpenClaw 在 Mac 上本地化部署及接入飞书教程
  • 红黑树原理、规则及 C++ 代码实现
  • C++ 核心概念与面试知识点梳理

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online