MCP / AI Agent 场景 为什么现在很多框架从 SSE 转向 Streamable HTTP
1. 结论先行
在 MCP / AI Agent 场景里,很多框架从 SSE 转向 Streamable HTTP,核心原因不是 SSE 不能用,而是:
随着 Agent 交互从“单纯吐文本”升级为“多阶段、多类型、可恢复、可协商”的复杂协议,
SSE作为一种固定事件流格式开始显得过窄,而Streamable HTTP更适合作为统一传输层。
更直白地说:
2. 先看背景:MCP / AI Agent 到底改变了什么
2.1 早期 LLM streaming 的本质很简单
早期大模型接口的 streaming,本质上往往只有一件事:
- 用户发请求
- 模型逐 token 或逐 chunk 输出文本
- 服务端持续推给客户端
这种模式下,SSE 非常贴切:
- 服务端单向输出
- 文本天然适配
- 浏览器可直接消费
- 实现和调试都简单
所以很多早期模型 API、前端 Demo、聊天界面都大量采用 SSE。
2.2 Agent 场景把“输出”变成了“会话协议”
到了 Agent 阶段,请求/响应不再只是“生成一段文字”,而是变成:
这意味着传输层承载的不再只是“文本流”,而是 协议消息流 。
而协议消息流通常有这些特征:
- 消息类型多
- 内容结构复杂
- 顺序要求严格
- 需要错误语义
- 可能需要 resume / retry
- 需要兼容浏览器、服务端、CLI、代理层
这就是很多框架转向 Streamable HTTP 的直接背景。
3. 为什么 SSE 在 Agent 场景里开始显得不够用
这里的“不够用”通常不是绝对不能实现,而是 实现成本、协议表达力和工程兼容性越来越差 。
3.1 SSE 天然偏向“服务端事件推送”,不擅长承载复杂协议
SSE 设计初衷是:
- 服务端持续推送事件
- 客户端订阅并消费
它适合:
messageprogressdone
这类事件模型。
但在 Agent / MCP 场景中,消息可能变成:
虽然这些也能硬塞进 SSE 的 event: + data: 里,但随着消息类型和字段复杂度增长,SSE 就逐渐退化成:
- 外层是 SSE
- 内层真正协议还是自定义 JSON
这时 SSE 提供的价值就越来越少,反而成了额外包裹层。
3.2 SSE 过于绑定文本事件格式
SSE 的消息边界与字段语义是固定的,例如:
event:data:id:retry:
这带来两个问题:
-
真正业务语义只能塞进
data
也就是你最后还是要定义自己的 JSON envelope。 -
协议演进不够自然
一旦想支持更复杂的 chunk 语义、分片、对象边界、嵌套内容块,就会越来越像“借 SSE 外壳承载另一套协议”。
对于现代 Agent 框架来说,它们更想直接定义:
- 每个 chunk 的 schema
- chunk 之间的关系
- 哪些块可增量,哪些块必须完整
- 如何结束
- 如何恢复
这类需求下,Streamable HTTP 更自然,因为它只要求“HTTP 上能持续读写”,不强加事件格式。
3.3 浏览器友好,但非浏览器生态不一定最优
SSE 一个很大优势是浏览器里有 EventSource。但 MCP / Agent 的调用方并不只在浏览器:
这些客户端很多并不会把 EventSource 当作最佳抽象,反而更常见的是:
fetch- 原生 HTTP client
- ReadableStream
- async iterator
- chunk reader
对这类调用方,Streamable HTTP 往往比 SSE 更统一:
- 同一个请求方式
- 同一套认证头
- 同一套 HTTP 中间件
- 同一种 body 流读取模型
因此从“全栈兼容性”看,很多框架更愿意把 fetch + streaming body 作为基础面。
3.4 SSE 对请求控制能力较弱
在浏览器里,EventSource 的请求能力相对有限,典型限制包括:
- 自定义请求方法不灵活
- 请求 body 支持弱
- 请求控制能力不如
fetch - 中间层处理和高级控制不够统一
而 Agent / MCP 请求常常并不是简单 GET 订阅,它可能需要:
这种情况下,fetch 发 POST 再读取响应流,比 EventSource 模型更顺手。Streamable HTTP 正好与这种用法天然一致。
3.5 SSE 的“单向”心智模型不适合多阶段 Agent 交互
虽然很多 Agent 框架的单次响应依然是服务端到客户端单向流,但整个系统交互往往是:
- 客户端发起请求
- 服务端开始流式返回
- 客户端可能取消
- 客户端随后提交 tool result
- 服务端继续后续阶段
- 中间可能 resume
这不一定要求 WebSocket,但确实说明:
- 系统需要的是 围绕 HTTP 的可编排会话交互
- 而不是单纯的“订阅一个事件流”
Streamable HTTP 更容易和普通 HTTP 端点统一建模,例如:
POST /responses- 返回流式 body
POST /responses/{id}/cancelPOST /responses/{id}/tool_resultGET /responses/{id}
这类 API 设计比“所有东西都挂在 SSE 流里”更清晰。
4. 为什么 Streamable HTTP 更适合 MCP / Agent
4.1 它把“传输层”和“消息协议层”解耦了
这是最核心的一点。
使用 Streamable HTTP 时,框架通常会采用这样的分层:
- 传输层:HTTP + streaming body
- 消息层:JSON chunk / NDJSON / framed message / typed event object
- 业务层:tool call、delta、checkpoint、final output
这样做好处很大:
- HTTP 只负责传输
- 协议格式可独立演进
- SDK 可对 chunk 做高层封装
- 不必被 SSE 语法限制
换句话说,框架从 “SSE is the protocol” 转成 “HTTP streaming is the transport, protocol is ours”。
这正是 Agent 框架成熟的标志。
4.2 更适合结构化输出和多模态内容
现代 Agent 输出的不只是文本,还可能包含:
如果继续用 SSE,常见做法是:
event: messagedata: {复杂 JSON}
本质上已经是“用文本事件包 JSON 事件对象”。
而 Streamable HTTP 可以更直接地表达:
- 一块就是一个 JSON object
- 每行一个对象
- 或按 framing 协议输出对象序列
这对 SDK 解析、类型系统建模、错误处理都更友好。
4.3 更适合服务间调用、网关和代理透传
MCP / Agent 往往会经过多层链路:
- client SDK
- API gateway
- agent runtime
- tool router
- model provider adapter
- observability / tracing 中间件
在这类链路里,大家通常都已经围绕普通 HTTP request/response 做了很多基础设施:
Streamable HTTP 更容易直接复用这些设施。
尤其在服务间调用中,统一成“一个普通 POST + 流式响应 body”通常比“专门处理 SSE 事件语法”更简单。
4.4 更利于 SDK 抽象一致化
Agent 框架通常希望 SDK 层提供类似这样的统一接口:
或者:
如果底层是 Streamable HTTP,SDK 可以:
- 在 JavaScript 中映射为
ReadableStream - 在 Python 中映射为 iterator / async generator
- 在 Go 中映射为 decoder loop
- 在 Java 中映射为 reactive stream / input stream
这比依赖 SSE 的浏览器式模型更便于跨语言统一。
4.5 更适合“一个 API,多种返回模式”
很多现代框架希望同一个接口支持:
- 非流式返回
- 流式返回
- JSON 模式
- 结构化模式
Streamable HTTP 更容易做到接口统一:
- 同一个 endpoint
- 同一个请求 schema
- 通过参数或 header 决定是否 stream
例如:
stream=false:返回完整 JSONstream=true:返回分块 JSON stream
这在 SDK、文档、版本演进上都更整洁。
而 SSE 往往暗示一种特定响应类型:text/event-stream。一旦协议要兼容更多模式,SSE 的外形就没那么优雅了。
5. 放到 MCP 语境里看,转向更明显
5.1 MCP 关注的是“模型与工具/上下文之间的标准交互”
MCP 的重点不是“浏览器怎么收事件”,而是:
- 模型怎么发现工具
- 怎么调用工具
- 怎么交换结构化上下文
- 怎么保持协议兼容
- 怎么跨宿主、跨语言、跨运行时工作
因此它天然更看重:
- 协议清晰
- 传输可替换
- 客户端多样性
- 工程一致性
在这个方向上,SSE 更像一种可选包装;Streamable HTTP 更像一种更中立的承载层。
5.2 MCP / Agent 场景中,消息往往不是“给人看”,而是“给程序消费”
SSE 非常适合把人类可理解的事件流推给前端界面,例如:
- “正在思考”
- “正在调用工具”
- “已完成”
但 MCP 更多时候传的是给程序消费的结构化协议消息。
程序消费更关注:
- schema 稳定性
- 可类型化
- 可校验
- 可版本化
- 可恢复
这些维度上,Streamable HTTP + structured chunks 通常比 SSE + data JSON 更规范。
5.3 MCP 生态强调“宿主无关”
MCP 连接的宿主可能是:
- 桌面应用
- 编辑器
- 本地 Agent runtime
- 云端编排器
- CLI
- 后端服务
既然宿主并不局限在浏览器,使用浏览器色彩更浓的 SSE 作为默认主通道,就不一定是最优选择。采用更中性的 Streamable HTTP,能降低生态绑定。
6. 一个非常直观的对比
6.1 用 SSE 做 Agent streaming,通常长这样
外层:
event: message data: {"type":"tool_call_started","tool":"search"}
再来一条:
event: message data: {"type":"tool_call_delta","delta":"..."}
再来一条:
event: done data: {"type":"final","output_text":"..."}
你会发现:
- 真正协议在 JSON 里
- SSE 只是承担“分条发出去”的作用
6.2 用 Streamable HTTP 做 Agent streaming,通常会变成
{"type":"tool_call_started","tool":"search"} {"type":"tool_call_delta","delta":"..."} {"type":"final","output_text":"..."}
或者别的 framing 形式。
这样做的好处是:
- 少一层 SSE 包装
- 协议对象更直接
- SDK 更容易映射为类型对象
- 服务间透传更简单
所以很多框架的真实思路是:
如果最终还是要定义一套自己的 chunk schema,那不如直接使用更通用的 Streamable HTTP 来承载。
7. 这并不意味着 SSE 过时了
这里需要特别区分: “默认主通道发生变化” ,不等于 “SSE 没价值” 。
SSE 仍然非常适合这些场景:
- 浏览器前端直接接模型输出
- 快速实现聊天打字机效果
- 简单进度流
- 轻量后台任务通知
- 人类可读的事件输出
所以实际工程里常见的是:
- 底层核心协议使用
Streamable HTTP - 面向 Web UI 再适配成
SSE - 或同时支持两种模式
也就是说,很多框架不是完全“抛弃 SSE”,而是把它从“协议核心”降级成“前端友好的适配层”。
8. 转向背后的工程动机,可归纳为 6 点
8.1 从“文本流”升级到“协议流”
Agent 不只是输出字,而是在交换状态、指令和结构化事件。
8.2 从“浏览器优先”升级到“多宿主优先”
调用方不只是网页,还包括 IDE、CLI、服务端和运行时。
8.3 从“事件展示”升级到“程序消费”
消费方更需要 typed chunks,而不是仅适合展示的 event text。
8.4 从“固定格式”升级到“协议可演进”
框架需要更自由地定义 chunk schema、错误语义和恢复机制。
8.5 从“单接口 streaming”升级到“完整会话编排”
需要与 cancel、resume、tool result submit、checkpoint 等 API 协同。
8.6 从“前端实现便利”升级到“全链路工程一致性”
网关、代理、SDK、多语言客户端都更容易围绕普通 HTTP 流构建。
9. 一句话总结两代思路
可以把它概括成下面这组变化:
- SSE 时代 :重点是“把模型输出实时显示出来”
- Streamable HTTP 时代 :重点是“把 Agent 协议稳定、统一、可扩展地传输出来”
前者偏 UI streaming,后者偏 protocol streaming。
10. 最终总结
在 MCP / AI Agent 场景里,很多框架从 SSE 转向 Streamable HTTP,本质上是因为系统复杂度上升后,框架需要的已经不只是“服务器持续推事件”,而是:
- 一种更中立的 HTTP 流式承载层
- 一套可演进的结构化消息协议
- 更好的跨语言、跨宿主兼容性
- 更自然的服务间调用和 SDK 抽象
- 更方便承载 tool call、delta、state、error、resume 等 Agent 原语
所以这不是简单的“谁性能更高”,而是 协议分层与工程适配方式发生了变化 :
SSE更像前一阶段 AI 产品中非常实用的流式展示方案Streamable HTTP更适合当前 MCP / Agent 体系下,把复杂交互当作正式协议来建设
更多推荐




所有评论(0)