外观
各厂商流式(Streaming)协议机制对比
调研/复核日期:2026-07-29 本文聚焦传输与事件层;请求/响应数据模型见 openai-anthropic-sse.md。
1. OpenAI HTTP/SSE
Chat Completions(/v1/chat/completions)
设置 stream: true 后返回 SSE。每条消息通常只有 data: {...}\n\n,不使用具名 event:;流以 data: [DONE]\n\n 结束。payload 是 chat.completion.chunk:首块通常带 delta.role,后续是 delta.content,最终 choice 带 finish_reason。
工具调用位于 delta.tool_calls[]。每项用 index 区分可能交错的并行调用,function.arguments 是字符串片段,必须按 choice/tool index 聚合后再解析 JSON。设置 stream_options.include_usage=true 后,[DONE] 前增加一个 choices: []、携带完整 usage 的 chunk;若连接中断,该最终 usage chunk 可能收不到。
Responses API(/v1/responses)
Responses 使用 typed semantic events,每个事件有独立 type 和单调递增的 sequence_number。典型成功顺序是:
response.created → response.in_progress → response.output_item.added → response.content_part.added → response.output_text.delta → 对应 *.done → response.output_item.done → response.completed。
response.completed 内含最终 Response 和 usage。函数参数通过 response.function_call_arguments.delta / .done 增量传输,作用域按 output item/call ID。失败或截断时终态可为 response.failed、response.incomplete,另有流级 error。成功必须由 typed terminal event 判定,不能仅凭连接关闭。官方 Python SDK 的通用 SSE parser 会识别 [DONE],但这不是 Responses 业务成功事件,endpoint-specific client 不应依赖它判定结果。
2. Anthropic Messages SSE
Anthropic 同时发送 event: 和 data:,没有 [DONE] 哨兵。标准顺序:
message_start → 每个 block 的 content_block_start → 多个 content_block_delta → content_block_stop → message_delta → message_stop。
ping 可在任意位置保活,error 可在 HTTP 200 建连后中途出现(如 overloaded_error)。Delta 类型包括:
text_delta:文本增量。input_json_delta:工具参数的partial_json字符串,完整聚合后才能解析。citations_delta:引用信息增量。thinking_delta/signature_delta:扩展推理与签名增量。
message_delta.usage 是累计值而非单个 delta 的消耗。Anthropic 允许新增事件类型,client 应对未知事件做前向兼容。工具调用示例:
text
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01","name":"get_weather","input":{}}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location\":\"Shanghai\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"tool_use"},"usage":{"output_tokens":89}}
event: message_stop
data: {"type":"message_stop"}3. Google Gemini HTTP 流式
REST 调用 streamGenerateContent?alt=sse 时返回 SSE,每个 data: payload 是局部 GenerateContentResponse,结构仍为 candidates[].content.parts[] 和 usageMetadata。SDK 会封装 transport 细节。此前关于“不加 alt=sse 一定返回分块 JSON 数组”的结论缺少本轮可复核的一手证据,不能作为跨版本保证;裸 HTTP client 应显式请求并校验 response Content-Type。
4. AWS Bedrock EventStream
InvokeModelWithResponseStream 和 ConverseStream 使用 application/vnd.amazon.eventstream,不是 SSE。Amazon EventStream wire spec 明确定义:
- 12 字节 prelude:4 字节 total length、4 字节 headers length、4 字节 prelude CRC32。
- typed headers 与 payload(Bedrock payload 通常是 JSON)。
- 末尾 4 字节 message CRC32;整数为 network byte order,双方必须校验两个 CRC。
ConverseStream 通常是 messageStart → contentBlockStart/Delta/Stop → messageStop → metadata。internalServerException、throttlingException、modelStreamErrorException 等可作为流内 event message 出现。Bedrock 会把 Anthropic 等模型映射到自己的 schema,所以经 Bedrock 调用 Claude 不会返回原生 Anthropic SSE。
5. 双向实时协议
OpenAI Responses WebSocket mode:与 Realtime API 不同。client 在持久 socket 上发送 response.create,server 返回与 HTTP/SSE 基本相同的 typed response events;用 previous_response_id 串联轮次,适合多轮 tool loop 并减少重复连接开销。
OpenAI Realtime API:双向事件协议可运行在 WebSocket;浏览器/移动端通常优先使用 WebRTC,另有 SIP 接入。client 可持续发送音频、conversation item 和 response.create,也可中途打断。单次 response 的终态事件是 response.done,其中 response status 可为 completed/cancelled/failed/incomplete;它不是 Responses API 的 response.completed。
Gemini Live API:WebSocket 连接使用 BidiGenerateContent。首条 client message 必须是 setup;后续使用 clientContent、realtimeInput、toolResponse 等。server 返回 setupComplete、serverContent、toolCall 等,serverContent.turnComplete 表示一轮结束。session resumption 和 context-window compression 属于 Live 的会话能力,不能从普通 streamGenerateContent 推断。
6. 对比表
| API | 传输/帧 | 方向 | 应用层终态 |
|---|---|---|---|
| OpenAI Chat Completions | HTTP SSE,通用 chunk | 单向 | choice finish_reason,随后 [DONE] |
| OpenAI Responses | HTTP SSE,typed events | 单向 | response.completed / failed / incomplete |
| Anthropic Messages | HTTP SSE,event + data | 单向 | message_stop,无 [DONE] |
Gemini streamGenerateContent | HTTP SSE(alt=sse) | 单向 | 最终 response 后流关闭 |
| AWS Bedrock ConverseStream | 二进制 Amazon EventStream | 单向 | messageStop / metadata 后关闭 |
| OpenAI Responses WS | WebSocket typed events | 双向、多 response | 每次 response 使用 Responses 终态事件 |
| OpenAI Realtime | WebSocket/WebRTC | 双向 | 每次 response 为 response.done |
| Gemini Live | WebSocket | 双向 | 每轮 turnComplete: true |
置信度与实现注意
- Bedrock 布局已直接对照 Amazon EventStream wire specification,属于强证据;parser 仍需覆盖 CRC 错误、未知 header type 与 size limit。
- OpenAI 事件名已对照官方文档和官方 SDK 生成类型;Responses 与 Realtime 的同名/近似事件必须按 endpoint 分开解析。
- 流式 HTTP 已返回 200 后仍可能在流内报错。重试前要判断输出是否已部分展示、工具是否已执行,避免重复副作用。
- 增量 UTF-8 文本、JSON arguments、base64 audio 都可能跨帧边界,不能逐帧独立解码成完整业务对象。
引用清单
- OpenAI streaming responses
- OpenAI Responses streaming events
- OpenAI Responses WebSocket mode
- OpenAI Realtime reference
- Anthropic streaming Messages
- Gemini generateContent API
- Gemini Live API
- AWS ConverseStream
- Amazon EventStream wire format
关联
MCP 和 A2A 都可在部分 HTTP operation 的响应中使用 SSE,但普通请求也可直接返回 JSON,A2A 还有 gRPC binding。MCP 2026-07-28 已移除 Last-Event-ID 续传,不能把旧版重连语义套到当前版;详见 mcp-protocol.md、a2a-protocol.md。