从 SSE 到 Streamable HTTP:AI 时代的协议演进之路

摘要:随着 AI 大模型应用的爆发,传统的 Server-Sent Events (SSE) 协议逐渐暴露出其局限性。2025年,Anthropic 在 MCP 协议中引入的 Streamable HTTP,正在重新定义实时通信的标准。本文将从发展历史、核心痛点、解决方案与技术原理三个维度,深度解析这场协议演进背后的技术逻辑。


一、发展历史:从 Web 标准化到 AI 原生

1.1 SSE 的诞生:HTML5 时代的推送方案

Server-Sent Events (SSE) 并非某家公司的独立发明,而是 W3C 万维网联盟在 HTML5 标准化进程中的产物

  • 2009-2012年:作为 HTML5 规范草案被提出,旨在解决早期 AJAX 轮询的性能瓶颈
  • 2012年 :正式成为 W3C 推荐标准,定义了 EventSource API
  • 设计目标:为浏览器提供一种轻量级的、基于 HTTP 的服务器单向推送机制

SSE 的出现,让网页能够实时接收股票行情、新闻推送、社交媒体更新等,成为 Web 实时化的重要基石。

1.2 Streamable HTTP 的崛起:MCP 协议的架构升级

Streamable HTTP 则是 AI 时代的产物 ,由 Anthropic 为其 Model Context Protocol (MCP) 专门设计:

时间节点 里程碑事件
2024年11月 Anthropic 开源 MCP 协议,初始版本采用 HTTP + SSE 作为远程传输方案
2025年3月 MCP 通过 PR #206 正式引入 Streamable HTTP,取代 HTTP+SSE 成为推荐传输机制
2025年11月 MCP 规范 2025-11-25 版本进一步巩固 Streamable HTTP 地位,并引入 OAuth 2.1 授权

从时间线可以看出,Streamable HTTP 并非要颠覆 SSE 作为通用 Web 标准,而是 针对 AI 大模型场景的特殊需求做出的架构演进


二、核心痛点:SSE 在 AI 时代的三大局限

2.1 连接管理困境

SSE 基于长连接机制,在 AI 应用中暴露出严重问题:

javascript 复制代码
// SSE 的典型痛点:连接不稳定
const eventSource = new EventSource('/ai-stream');

eventSource.onerror = (error) => {
  // 网络抖动、代理超时、负载均衡切换都会导致断开
  console.log('连接断开,需要手动重连...');
  // 复杂的重连逻辑、状态恢复、消息去重...
};
  • 浏览器并发限制:同一域名下最多 6 个 SSE 连接,多标签页场景下极易耗尽
  • 代理与防火墙:长连接常被企业级防火墙、CDN 视为异常而切断
  • Serverless 不友好:函数计算平台(如 AWS Lambda)不适合保持长连接

2.2 双向通信的"跛脚"设计

SSE 是严格的单向通道 (服务器→客户端),但 AI 场景需要全双工通信

复制代码
用户提问 → AI 思考 → 调用工具 → 返回结果 → 继续生成
   ↑          ↑         ↑          ↑
 客户端    客户端    服务器     服务器
  发送      接收      执行       推送

在 SSE 方案中,客户端发送数据必须另开 HTTP 请求,导致:

  • 架构复杂:需要维护两条通道(SSE 接收 + HTTP 发送)
  • 时序混乱:请求与响应难以精确关联
  • 状态分散:上下文需要在多个连接间同步

2.3 云原生架构的适配难题

特性 SSE 表现 云原生需求
无状态性 ❌ 必须保持连接状态 ✅ 每个请求独立处理,便于水平扩展
负载均衡 ❌ 会话粘性强 ✅ 任意节点可处理任意请求
容错恢复 ❌ 断线后难以恢复上下文 ✅ 通过会话 ID 快速恢复
CDN 支持 ❌ 边缘节点难以缓存长连接 ✅ 标准 HTTP 请求,边缘友好

三、解决方案:Streamable HTTP 的技术原理

Streamable HTTP 并非创造新协议,而是对 HTTP 已有能力的现代化封装,通过三大机制解决上述痛点。

3.1 核心机制:分块传输编码 (Chunked Transfer Encoding)

Streamable HTTP 利用 HTTP/1.1 原生支持的 Chunked Transfer-Encoding,实现"请求即流、响应即流":

http 复制代码
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Mcp-Session-Id: 550e8400-e29b-41d4-a716-446655440000

7f
{"jsonrpc":"2.0","result":{"content":"你好"}}
9d
{"jsonrpc":"2.0","result":{"content":"这是"}}
a2
{"jsonrpc":"2.0","result":{"content":"实时推送的消息"}}
0  ← 结束标记

关键特性

  • 即时性:数据一生成立即发送,无需等待完整响应
  • 双向性 :请求体同样支持流式上传(ReadableStream
  • 兼容性:所有现代 HTTP 客户端/服务器均支持

3.2 浏览器端的实时接收

通过 Fetch API + ReadableStream,浏览器可以逐块读取服务器推送:

javascript 复制代码
// Streamable HTTP 的浏览器实现
const response = await fetch('/mcp-endpoint', {
  method: 'POST',
  headers: { 
    'Content-Type': 'application/json',
    'Mcp-Session-Id': sessionId  // 会话恢复
  },
  body: JSON.stringify(request),
  duplex: 'half'  // 允许流式请求体
});

const reader = response.body.getReader();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  
  // 实时解码并更新 UI
  const chunk = new TextDecoder().decode(value);
  const message = JSON.parse(chunk);
  updateUI(message);  // 即时渲染,无需等待全部数据
}

对比 SSE 的 EventSource,Fetch API 提供了更细粒度的流控制

  • 支持 取消请求AbortController
  • 支持 读取进度监控
  • 支持 自定义请求头 (SSE 的 EventSource 无法自定义 headers)

3.3 会话管理:无状态架构的"状态恢复"方案

Streamable HTTP 通过 会话 ID 机制 解决无状态与上下文保持的矛盾:

javascript 复制代码
// 首次请求:建立会话
const initResponse = await fetch('/mcp', {
  method: 'POST',
  body: JSON.stringify({ method: 'initialize' })
});
const sessionId = initResponse.headers.get('Mcp-Session-Id');

// 后续请求:携带会话 ID,任意节点可恢复上下文
const streamResponse = await fetch('/mcp', {
  method: 'POST',
  headers: { 'Mcp-Session-Id': sessionId },
  body: JSON.stringify({ method: 'tools/call', ... })
});
// 即使连接到不同服务器节点,也能继续之前的对话

架构优势

  • 水平扩展:无需会话粘性(Session Affinity),任意节点可处理
  • 故障转移:连接断开后,新请求自动路由到健康节点
  • Serverless 友好:函数实例无需保持长连接,每次调用独立处理

3.4 双向流式的完整实现

MCP 的 Streamable HTTP 支持 两种模式 覆盖所有场景:

模式 HTTP 方法 适用场景 数据流向
流式请求-响应 POST 客户端需要发送数据 客户端流式上传 → 服务器流式返回
纯读取流 GET 仅接收服务器推送 服务器单向流式推送(类似 SSE)
javascript 复制代码
// 场景 1:AI 对话(双向流式)
const chatResponse = await fetch('/mcp', {
  method: 'POST',
  body: createStreamableBody(userInput)  // 流式上传
});
// 同时接收流式响应

// 场景 2:订阅通知(单向读取)
const notifyStream = await fetch('/mcp?session_id=xxx', {
  method: 'GET'
});
// 持续读取服务器推送

四、总结:协议演进的本质

从 SSE 到 Streamable HTTP,不是技术的颠覆,而是场景驱动下的架构回归

维度 SSE (2012) Streamable HTTP (2025)
设计目标 浏览器实时推送 AI 大模型双向流式通信
架构哲学 长连接、有状态 无状态、可扩展
云原生适配
浏览器 API EventSource fetch() + ReadableStream
协议归属 通用 Web 标准 MCP 专用传输层

Streamable HTTP 的核心洞察

不需要为实时通信发明新协议,只需要充分利用 HTTP 的流式能力,并用现代 API 封装成适合 AI 交互的模式。

对于开发者而言,这意味着:

  • ✅ 无需学习 WebSocket 的复杂性
  • ✅ 享受 HTTP 生态的成熟工具链(CDN、WAF、监控)
  • ✅ 天然支持 Serverless 和微服务架构

SSE 并未消亡,在简单的服务器推送场景(如股票行情、日志推送)中依然简洁高效。但在 AI 大模型时代,Streamable HTTP 正在成为实时通信的新范式


参考链接


本文首发于 CSDN,转载请注明出处。

相关推荐
冬奇Lab2 小时前
一天一个开源项目(第75篇):Hermes Agent - Nous Research 开源的自我进化 AI Agent
人工智能·开源·资讯
普密斯科技2 小时前
齿轮平面度与正反面智能检测方案:3D视觉技术破解精密制造品控难题
人工智能·计算机视觉·平面·3d·自动化·视觉检测
米猴设计师2 小时前
PS图案融合到褶皱布料上怎么弄?贴图教程
图像处理·人工智能·贴图·ps·nanobanana
123_不打狼2 小时前
基于UNET的语义分割
人工智能·语义分割
实在智能RPA2 小时前
Agent 如何处理流程中的异常情况?2026年AI Agent架构工程与自愈机制深度拆解
人工智能·ai·架构
十铭忘2 小时前
局部重绘3——FLUX-Fill的Lora训练
人工智能·深度学习·机器学习
碳基硅坊2 小时前
Dify v1.13.x 版本更新速览:从人机协作到架构升级
人工智能·dify
IT_陈寒3 小时前
SpringBoot自动配置把我都整不会了
前端·人工智能·后端
w_t_y_y3 小时前
python AI工程(二)python实现skill+cli
人工智能