网页端 AI 对话的“打字机”式输出效果,为什么首选 SSE 协议?
文章目录
问题:
网页端 AI 对话的“打字机”效果,为什么首选 SSE 协议?
“像 ChatGPT 那样,AI 生成的文字一个字一个字地蹦出来(流式输出),底层是用什么协议实现的?”
为什么使用 SSE,不用 WebSocket?为什么不用 HTTP 轮询?如果用 HTTP/2 的多路复用做轮询呢?
这篇博文,我们就来彻底拆解这个经典的架构选型问题,看透各种通信协议的本质。
核心需求剖析:AI 流式输出到底需要什么?
在做技术选型前,先看业务场景。AI 生成回答的特点是:
- 耗时较长:大模型推理需要时间,不能让用户看着白屏干等。
- 增量生成:AI 是逐字/逐句生成内容的。
- 单向传输:用户提问完之后,剩下的时间全是服务器在向客户端单向发数据,客户端只需要安静地接收和渲染。
因此,这个场景的终极诉求是:建立一条轻量级的连接,让服务器能够单向、实时、低开销地把增量数据推给客户端。
方案列举:为什么不选其他方案?
1. HTTP/1.1 轮询 (Polling)
- 通信模型:客户端主动问(Pull)→ 服务器被动答。
- 做法:客户端每隔 1 秒发一个 HTTP 请求问:“AI 吐出新字了吗?”
- 缺陷:
- 开销极大:每次请求都要经历完整的 HTTP 头部解析,哪怕没有新数据。
- 延迟与浪费:如果轮询间隔长,文字显示会卡顿(延迟);如果间隔短,会产生大量返回空的无效请求,白白消耗服务器资源。
2. HTTP/2 轮询
面试官可能会问:“HTTP/2 有多路复用(Multiplexing),一个 TCP 连接能并发多个请求,开销很小了,用 HTTP/2 轮询不行吗?”
这涉及到 HTTP2 协议的特性,尽管确实以后多路复用,但是模式还是轮询:
- 关键点:HTTP/2 的多路复用解决的是“网络传输层的拥堵(队头阻塞)”问题,但它没有改变“轮询”这种业务交互模式的本质!
- 只要我们还在“轮询”,依然是客户端在主动“拉(Pull)”数据。AI 如果还没生成出下一个字,服务器依然只能给你回一个空响应。多路复用只是让“无效询问”跑得更快、更省连接了而已,但“无效询问”本身依然存在
- 我们要的是“有数据就推”,而不是“不停地去问”。
3. WebSocket (WS)
- 通信模型:双向全双工(Push + Pull)。
- 做法:建立一条长连接,客户端和服务器可以随时互相发消息。
- 为什么不选它:
- 过度设计:AI 输出场景中,用户发完 Prompt 后,就是单向的“服务器 → 客户端”传输。WebSocket 强大的“客户端随时推”的能力在这里完全闲置。
- 握手与维护成本高:WebSocket 需要先发 HTTP 请求进行
Upgrade协议升级。而且它是独立于 HTTP 的有状态协议,服务端需要维护复杂的连接状态、心跳检测、断线重连逻辑,架构变重。
实际选择:SSE (Server-Sent Events)
SSE 简直就是为了 AI 流式输出量身定制的协议。
- 通信模型:单向推送(服务端推送)。客户端发起一次请求,服务器保持连接不断开,并源源不断地以
text/event-stream格式向客户端推送文本流。 - 核心优势:
- 极度轻量(HTTP 原生):它就是一次普通的 HTTP 请求,不需要像 WebSocket 那样升级协议。
- 模型完美契合:服务器生成一个字,就推一个字。没有轮询的延迟,也没有无效请求。
- 开发成本极低:浏览器原生支持
EventSourceAPI,甚至自带断线自动重连机制,前端几行代码就能搞定。
小结
“面对 AI 流式输出场景,选择 SSE 是因为它的通信模型最契合。
轮询(包含 HTTP/2 轮询)的本质是客户端主动‘拉’,不仅有轮询间隔带来的延迟,还会产生大量由于 AI 未生成完毕导致的无效请求。HTTP/2 的多路复用只能降低网络层开销,但无法弥补‘拉’模式的逻辑缺陷。
WebSocket 虽然能做到实时推送,但它是全双工通信,对于只需单向传输的 AI 场景属于过度设计,且协议升级和状态维护成本较高。
SSE 基于纯粹的 HTTP 协议,一次连接、单向推流,完美契合 AI 逐字生成的特点。在实际工程中,为了支持大文本的 POST 请求,我们通常会采用
fetchAPI 结合流式读取(ReadableStream)来实现类似 SSE 的效果,达到性能与体验的最优解。”
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)