-
底层通信机制:HTTP/1.1 分块传输编码(Chunked Transfer Encoding) 在HTTP/1.1中,服务器可以通过设置响应头
Transfer-Encoding: chunked来启用分块传输。这意味着服务器不需要预先知道响应体的总长度,可以一边生成数据,一边将其分成多个“块”发送给客户端。每个块包含一个十六进制的长度标识和实际数据,最后以长度为0的块表示结束。这种机制允许服务端在未完成全部计算时就开始传输数据,非常适合AI生成类任务——因为生成过程是顺序的、耗时的,且输出具有前缀依赖性(即下一个token依赖前面的上下文)。 -
服务端实现:生成式模型的逐token输出 大多数现代AI语言模型(如Transformer架构)采用自回归方式生成文本,即每次预测一个token,并将其作为输入的一部分继续生成下一个token。这个过程本质上是串行的,因此天然适合流式输出。例如,在调用模型的generate()函数时,可以通过回调函数或生成器模式(generator)捕获每一个新生成的token,并立即通过HTTP响应流发送出去。
-
WebSocket 与 Server-Sent Events (SSE) 虽然分块传输可用于普通HTTP接口,但在实际AI应用中更常使用两种技术来实现流式返回:
- Server-Sent Events (SSE):基于HTTP长连接,服务器可以持续向客户端推送消息。它使用
text/event-stream的MIME类型,每条消息以data: ...开头,支持自动重连。SSE简单轻量,适用于单向服务器到客户端的流式输出,广泛用于AI聊天接口。 - WebSocket:提供全双工通信通道,适合需要双向交互的场景(如实时问答、中断生成)。但相比SSE更复杂,资源开销更大。
- Server-Sent Events (SSE):基于HTTP长连接,服务器可以持续向客户端推送消息。它使用
-
后端框架支持 现代Web框架普遍支持异步流式响应。例如:
- Python Flask/FastAPI 中可使用生成器函数配合
StreamingResponse - Node.js Express 中可通过
res.write()发送数据块 - Java Spring WebFlux 支持响应式流(Reactive Streams)
- Python Flask/FastAPI 中可使用生成器函数配合
-
前端如何接收? 前端通常使用
fetchAPI 或EventSource对象来接收流式数据。例如使用 fetch 时,可以从 response.body 获取 ReadableStream 并读取其内容:const response = await fetch('/api/generate', { method: 'POST' }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const text = decoder.decode(value); // 解析并显示增量文本 console.log(text); } -
性能与用户体验优化 流式返回不仅提升了感知速度(用户无需等待完整响应),还能降低内存压力(避免缓冲大量中间结果)。同时,结合 token级延迟优化(如 speculative decoding)、缓存机制(KV Cache复用)也能进一步提升吞吐效率。