更新日期:2026 年 8 月 7 日
覆盖范围:OpenAI、Anthropic、Google Gemini 的模型调用、工具调用、多模态、文件、批处理、实时交互与推理服务协议。本文不展开账号、计费、权限、微调管理等控制面 API。
大模型接口正在经历一次明显的范式迁移:早期 API 只是"输入一组消息,返回一段文本";现在的 API 则要表达推理过程中的消息、工具调用、文件引用、音视频流、异步任务和持久化状态。
因此,所谓"大模型协议"其实至少包含四层:
- 模型调用协议:如何描述文本、多模态内容、角色和生成参数;
- Agent 编排协议:如何表达工具调用、工具结果、状态延续和长任务;
- 资源协议:如何管理文件、向量库、缓存、批任务等外部资源;
- 传输协议:使用普通 HTTP、SSE、WebSocket、WebRTC、SIP 还是 gRPC。
如果把这四层混为一谈,就容易产生诸如"文件上传接口能直接让模型理解 PDF"或"SSE 是统一的大模型响应格式"这样的误解。文件接口只负责保存资源,SSE 也只规定事件如何传输;真正的语义仍由上层模型协议定义。
一张表看懂三家的核心设计
| 维度 | OpenAI | Anthropic | Google Gemini |
|---|---|---|---|
| 经典模型接口 | /v1/chat/completions |
/v1/messages |
models.generateContent |
| 新一代 Agent 原语 | /v1/responses |
Claude Managed Agents | interactions |
| 基本数据单元 | Message;Responses 中为 Item + Content Part | Message + Content Block | Content + Part |
| System 指令 | Chat 中是 system/developer 消息;Responses 推荐 instructions |
顶层 system,不放入普通消息序列 |
顶层 systemInstruction |
| 多候选输出 | Chat 的 choices[] |
通常返回单一 Message | candidates[] |
| 工具调用 | function_call/其他 typed output item;内置工具可由服务端执行 |
tool_use 与 tool_result 内容块;区分 client tool、server tool |
functionCall 与 functionResponse Part;另有内置工具 |
| 会话状态 | Chat 通常由客户端维护;Responses 可用 previous_response_id 或 Conversation |
Messages 默认由客户端回传历史;Managed Agents 提供持久 Session | generateContent 通常由客户端维护;Interactions/Live 提供服务端状态 |
| 实时协议 | Realtime:WebRTC、WebSocket、SIP | Messages 主要使用 HTTP/SSE;无完全对位的原生实时语音主接口 | Live API:有状态 WebSocket 双向流 |
| 文件设计 | File 是通用资源,再被 Responses、Batch、Evals、Fine-tuning 等引用 | Files API 上传一次、多次引用;当前仍带 Beta 语义 | File 是项目资源,以 fileData/URI 作为 Part 引用 |
| Embedding | 原生 /v1/embeddings |
Anthropic 当前不提供自有 Embedding 模型 | embedContent、batchEmbedContents |
| 协议气质 | 统一输出项、服务端工具、状态化编排 | 显式内容块、严格轮次、客户端控制强 | 多模态 Part、Google Resource 风格、候选与安全元数据完整 |
OpenAI 官方把 Responses 定位为直接模型调用、工具、多模态及有状态交互的主要入口,同时把 Realtime 单独用于低延迟音频会话。Google 的 API 总览则已经将 Interactions 列为推荐的 Agent 工作流原语,同时保留 generateContent、SSE 流式接口、Live、Batch 和 Embedding 等专用入口。Anthropic 仍以 Messages 作为精细控制模型调用的核心,并另外提供 Managed Agents 作为托管式 Agent Runtime。参考:OpenAI API Overview、Gemini API Reference、Claude API Overview。
一、OpenAI:从"消息响应"转向"类型化输出项"
1. Chat Completions:兼容面最广的消息协议
POST /v1/chat/completions 的中心对象是 messages[]。应用每次提交所需历史,模型在 choices[] 中返回 assistant message。
json
{
"model": "gpt-5.6",
"messages": [
{"role": "developer", "content": "回答简洁、准确。"},
{"role": "user", "content": "解释什么是向量数据库。"}
],
"stream": false
}
json
{
"id": "chatcmpl_...",
"object": "chat.completion",
"created": 1786000000,
"model": "gpt-5.6",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "向量数据库用于存储和检索高维向量......"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 32,
"total_tokens": 56
}
}
它的独特价值不在于能力最先进,而在于生态兼容性最好。大量开源推理服务、网关和国产模型都实现了"OpenAI-compatible Chat Completions"。它适合普通问答、已有应用迁移和客户端自己维护 Agent Loop 的场景。
它的结构性局限是:所有模型行为最终都要塞进 message 和 choices。当输出同时包含推理项、多个工具调用、图像结果、引用和异步状态时,消息模型会越来越勉强。
2. Responses API:面向 Agent 的统一执行原语
POST /v1/responses 不再假定输出只是"一条 assistant 消息",而是返回有序的 output[]。每一项都带 type,可能是消息、函数调用、Web Search 调用、文件检索、图像生成或其他工具结果。
json
{
"model": "gpt-5.6",
"instructions": "你是企业技术调研助手,结论必须给出来源。",
"input": "检索并总结量子纠错的近期进展。",
"tools": [
{"type": "web_search"}
],
"store": true
}
json
{
"id": "resp_...",
"object": "response",
"status": "completed",
"model": "gpt-5.6",
"output": [
{
"type": "web_search_call",
"id": "ws_...",
"status": "completed"
},
{
"type": "message",
"id": "msg_...",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "近期进展主要集中在......",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 40,
"output_tokens": 120,
"total_tokens": 160
}
}
Responses 的四个关键设计是:
- Item 化:工具调用、工具输出和最终消息都是一等对象,而不是附着在文本上的特殊字段;
- 输入多态 :
input可以是字符串,也可以是由消息和内容 Part 组成的数组; - 状态延续 :可通过
previous_response_id延续上次执行,也可使用 Conversation 资源; - 服务端工具:Web Search、File Search、Code Interpreter、Remote MCP、Image Generation 等可由平台执行。
一个容易踩坑的地方是:如果客户端手动管理历史,不能只保存 output 中的 message;推理项和工具项也可能是后续调用所必需的。简单延续优先使用 previous_response_id。官方说明见 Responses API 和 OpenAI SDK 多轮会话说明。
3. 自定义函数调用:call_id 是闭环主键
第一轮请求声明工具:
json
{
"model": "gpt-5.6",
"input": "北京现在多少度?",
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "查询指定城市天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"],
"additionalProperties": false
},
"strict": true
}
]
}
模型可能返回:
json
{
"output": [
{
"type": "function_call",
"name": "get_weather",
"arguments": "{\"city\":\"北京\"}",
"call_id": "call_abc123"
}
]
}
应用执行函数后,用同一 call_id 回填:
json
{
"model": "gpt-5.6",
"previous_response_id": "resp_previous",
"input": [
{
"type": "function_call_output",
"call_id": "call_abc123",
"output": "{\"temperature_c\":31,\"condition\":\"晴\"}"
}
]
}
这里的核心不是 JSON Schema 本身,而是调用与结果之间有明确关联标识,因此并行工具调用也能正确归并。
4. Files:资源上传不等于文件理解
当前通用上传示例应使用合法的 purpose,例如 user_data:
bash
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F "purpose=user_data" \
-F "file=@document.pdf"
json
{
"id": "file_abc123",
"object": "file",
"bytes": 524288,
"created_at": 1786000000,
"filename": "document.pdf",
"purpose": "user_data",
"status": "processed"
}
purpose=search 不是当前 OpenAI Files API 的合法通用值。官方当前列出的用途包括 assistants、batch、fine-tune、vision、user_data 和 evals。上传后还必须在具体请求中通过文件 ID 引用,或者先放入向量存储供 File Search 使用。参考:OpenAI Files Upload。
5. Realtime:从请求---响应变成长连接事件系统
OpenAI Realtime API 支持 WebRTC、WebSocket 和 SIP。会话保持连接,客户端持续发送音频或文本事件,服务端持续返回转写、语音、工具调用和状态事件。它不是在普通 JSON 请求上增加 stream=true,而是另一种会话生命周期。
json
{
"type": "session.update",
"session": {
"instructions": "你是一名中文语音助手。",
"audio": {
"input": {"turn_detection": {"type": "server_vad"}},
"output": {"voice": "alloy"}
},
"tools": []
}
}
服务端不会只返回一个最终 Response,而会产生一系列事件,例如音频增量、文本增量、工具调用参数增量和 response.done。浏览器或移动端更适合 WebRTC;服务端到服务端通常使用 WebSocket;电话网络接入则使用 SIP。参考:OpenAI Realtime and Audio。
6. 专用能力接口
| 能力 | 典型接口 | 设计特点 |
|---|---|---|
| Embedding | POST /v1/embeddings |
输入字符串或数组,输出 data[].embedding 浮点向量 |
| 图像 | Images API;也可经 Responses 工具调用 | Images 更适合直接生成/编辑;Responses 更适合将图像生成嵌入 Agent 流程 |
| 音频 | Transcription、Speech 等请求式接口 | 适合音频文件或有明确边界的任务 |
| Moderation | POST /v1/moderations |
分类结果而非生成文本 |
| Batch | POST /v1/batches |
用 JSONL 描述多条异步请求,按 custom_id 关联结果 |
OpenAI 的 Batch 不是"在一次同步请求里传数组",而是文件驱动的异步作业:上传 JSONL、创建 Batch、轮询状态、下载结果。官方说明其拥有独立的速率池,并面向非实时任务。参考:OpenAI Batch API、Embeddings、Images and Vision。
二、Anthropic:用严格的 Content Block 保持 Agent Loop 可解释
1. Messages API:顶层 system 与消息历史明确分工
Anthropic 的核心接口是 POST /v1/messages。system 位于顶层;messages 中主要使用 user 和 assistant。返回内容始终是 content[],即使只有一段文字也不会退化为裸字符串。
json
{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"system": "你是严格的数据抽取助手。",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "提取姓名:My name is Alice."}
]
}
]
}
json
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5",
"content": [
{"type": "text", "text": "Alice"}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 24,
"output_tokens": 5
}
}
这种设计的优势是:文本、图片、文档、工具调用、工具结果、思考块等都以内容块表达,解析器不需要根据多个旁路字段猜测响应类型。
2. 工具调用:tool_use 与 tool_result 必须严格相邻
模型调用客户端工具时返回:
json
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_01A",
"name": "get_weather",
"input": {"city": "北京"}
}
],
"stop_reason": "tool_use"
}
客户端执行后,下一条 user message 回填:
json
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A",
"content": "31°C,晴",
"is_error": false
}
]
}
Anthropic 对顺序约束更严格:工具结果必须紧跟对应的 assistant 工具调用,tool_result 还必须位于该 user content 数组的前部。严格性增加了网关转换难度,却能减少历史被拼接错位。参考:Handle Tool Calls。
Anthropic 还明确区分两类工具:
- Client tools:模型决定调用,业务应用执行并回填结果;
- Server tools:Web Search、Web Fetch、Code Execution 等由 Anthropic 执行,结果仍作为类型化内容块进入事件流。
3. Messages 默认无状态,Managed Agents 才是托管运行时
Messages API 适合应用自己控制历史、工具循环、权限审批和存储。Claude Managed Agents 则提供预置 Agent Harness、环境、持久 Session、事件历史、内置工具、MCP、压缩和长任务执行,更接近"托管 Agent Runtime"。两者不是新版/旧版替代关系,而是控制粒度不同:
| 选择 | 更适合 |
|---|---|
| Messages API | 自建网关、自定义 Agent Loop、严格控制每次模型请求 |
| Managed Agents | 长时间自主任务、文件与终端操作、希望减少基础设施建设 |
参考:Claude Managed Agents Overview。
4. Files、Batch、缓存与 Embedding 的取舍
Anthropic Files API 采用"一次上传、多次通过 file_id 引用"的模式,并特别提醒文件是 workspace 级资源,不天然按终端用户或会话隔离。因此 SaaS 平台必须在自己的数据库中维护用户与 file_id 的授权映射,不能信任客户端直接提交的文件 ID。当前 Files API 仍要求 Beta 能力标识。参考:Claude Files API。
Message Batches 直接复用 Messages 的请求参数,并增加 custom_id 关联每项结果:
json
{
"requests": [
{
"custom_id": "task-001",
"params": {
"model": "claude-sonnet-5",
"max_tokens": 256,
"messages": [{"role": "user", "content": "总结这段文本......"}]
}
}
]
}
Prompt Caching 则围绕"稳定前缀"设计,可自动管理,也可在内容块上设置显式缓存断点。这一点对长 system prompt、工具定义和大文档复用非常重要。
一个显著差异是:Anthropic 当前不提供自有 Embedding 模型接口 ,其官方文档推荐使用外部 Embedding 提供方。因此,"兼容 Claude 协议"不能被理解为覆盖向量化能力。参考:Claude Embeddings、Prompt Caching。
三、Google Gemini:Content/Part 是原生多模态抽象
1. generateContent:多模态不是附件,而是 Part
Gemini 的核心结构是 contents[] -> parts[]。文字、内联二进制、文件 URI、函数调用和函数结果都可以成为 Part。
json
{
"systemInstruction": {
"parts": [{"text": "你是数据分析师。"}]
},
"contents": [
{
"role": "user",
"parts": [
{"text": "分析这张图表。"},
{
"inlineData": {
"mimeType": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUg..."
}
}
]
}
],
"generationConfig": {
"temperature": 0.2,
"responseMimeType": "application/json"
}
}
json
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{"text": "{\"trend\":\"upward\",\"quarter\":\"Q3\"}"}
]
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": []
}
],
"usageMetadata": {
"promptTokenCount": 310,
"candidatesTokenCount": 45,
"totalTokenCount": 355
}
}
Gemini 的独特之处有三点:
- 多模态同构:文本、图片、音频、视频、文件和函数都在 Part 层统一表达;
- 候选优先 :返回
candidates[],安全评级、引用与 grounding metadata 通常跟随候选; - 资源风格明显 :模型名、文件名、缓存名常采用
models/...、files/...、cachedContents/...的资源路径。
字段在 REST JSON 中通常是 camelCase;不同 SDK 可能映射为 snake_case。不要把 SDK 对象字段直接当作线上的原始 JSON。完整结构见 Gemini generateContent。
2. 函数调用:调用与结果仍然是 Part
模型输出:
json
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": {"city": "北京"}
}
}
]
}
}
]
}
应用回填:
json
{
"contents": [
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "get_weather",
"response": {"temperature_c": 31, "condition": "晴"}
}
}
]
}
]
}
与 OpenAI 的显式 call_id 相比,Gemini 的基本示例更强调函数名称和对话中的 Part 顺序。因此,在一个回合内允许多个同名并发调用时,网关应保留供应商返回的完整关联字段和顺序,不能只抽取 name + args。
3. Interactions:Google 也进入服务端状态与 Agent 原语阶段
Google 当前把 Interactions 列为推荐的标准原语,用于 Agent 工作流、服务端状态、多模态多轮对话;generateContent 仍适合一次性和由客户端维护历史的调用。
这与 OpenAI 的演进非常相似:
| 传统原语 | 新原语 | 本质变化 |
|---|---|---|
| Chat Completions | Responses | Message → 类型化执行 Item |
generateContent |
Interactions | 单次内容生成 → 有状态交互与 Agent 工作流 |
Interactions 当前同时存在稳定版和 Beta 版文档,具体字段与能力应以实际使用的 API 版本为准。参考:Gemini Interactions API。
4. Live API:以 WebSocket 传输双向实时事件
Gemini Live API 是有状态 WebSocket API。连接后的首个 setup 消息声明模型、生成参数、system instruction 和 tools;之后客户端在同一连接上发送文本、音频、视频或工具结果,服务端返回文本、音频或函数调用。
json
{
"setup": {
"model": "models/gemini-live-model",
"generationConfig": {
"responseModalities": ["AUDIO"]
},
"systemInstruction": {
"parts": [{"text": "使用中文回答。"}]
},
"tools": []
}
}
连接建立后,客户端消息必须属于 setup、clientContent、realtimeInput 或 toolResponse 等事件类型之一。它和 OpenAI Realtime 都属于状态化双向协议,但 Google 的底层公开主路径是 WebSocket,而 OpenAI 还把 WebRTC 与 SIP 作为一等连接方式。参考:Gemini Live API。
5. Files、缓存、Embedding 与 Batch
Gemini Files API 用于将媒体独立于 prompt 上传,从而跨请求复用;上传后通常以文件 URI 和 MIME 类型组成 fileData Part。Context Caching 则将重复使用的内容、system instruction 或 tools 保存成 cachedContents 资源,调用时引用缓存资源名。
Gemini 同时提供:
embedContent:单项向量化;batchEmbedContents:一次请求中同步生成多项向量;asyncBatchEmbedContent:异步批量向量任务;batchGenerateContent:异步批量内容生成;countTokens:在正式推理前计算输入 Token。
这反映了 Google API 常见的同步 RPC、批量 RPC、Long-Running Operation 和 Resource 并存模式。参考:Gemini Files、Gemini Embeddings、Gemini Batch API、Gemini Context Caching。
四、SSE、WebSocket、WebRTC 和 gRPC 到底有什么区别
1. SSE:单向输出流,不是统一业务 Schema
SSE 基于 HTTP 长连接,服务端以 event: 和 data: 不断推送事件。它适合"请求一次、持续返回",实现简单,也容易穿过普通网关。
text
event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"Hello"}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_..."}}
不同厂商的事件名、结束条件和 JSON 结构并不相同:
- OpenAI Responses 使用细粒度的类型化事件;
- Chat Completions 常见
choices[].delta,旧式兼容实现常以data: [DONE]结束; - Claude Messages 使用
message_start、content_block_delta、message_delta、message_stop等事件; - Gemini
streamGenerateContent通过 SSE 发送候选结果增量。
因此网关不能只实现一个"读取 data: 并拼接 content"的解析器。至少要按 provider + endpoint + event.type 建立状态机。Claude 的事件规范见 Streaming Messages。
2. WebSocket:真正的双向持续通信
WebSocket 允许客户端和服务端随时互发事件,适合语音打断、音视频帧、动态工具结果和会话控制。代价是连接状态、心跳、重连、背压和并发治理更复杂。
3. WebRTC:浏览器实时媒体优先
WebRTC 不只是另一种 JSON 流,它内置了实时媒体传输、抖动处理、网络适配等能力。适合浏览器和移动端语音助手,但服务端业务事件往往仍需 Data Channel 或配套控制通道。
4. gRPC:内部推理服务的强类型高性能协议
gRPC + Protobuf 更常见于 Triton、KServe 等推理基础设施,而不是面向终端开发者的云模型通用协议。
protobuf
syntax = "proto3";
package inference;
service GRPCInferenceService {
rpc ModelInfer(ModelInferRequest) returns (ModelInferResponse);
rpc ModelStreamInfer(stream ModelInferRequest)
returns (stream ModelStreamInferResponse);
}
message ModelInferRequest {
string model_name = 1;
repeated InferInputTensor inputs = 2;
}
原稿中的 prompt + temperature + text_chunk 更像自定义 LLM RPC,并不是 Triton 标准协议。Triton 实际基于 KServe 推理协议,输入输出以张量和模型元数据为中心,并扩展共享内存、序列、调度、模型仓库和统计接口。参考:NVIDIA Triton HTTP/REST and gRPC Protocol。
| 传输 | 方向 | 最适合 | 主要代价 |
|---|---|---|---|
| HTTP JSON | 一问一答 | 普通生成、Embedding、管理接口 | 首字延迟体验一般 |
| SSE | 服务端单向连续推送 | 文本生成、工具参数增量 | 客户端不能在同连接自由反向发事件 |
| WebSocket | 全双工 | 实时音视频、打断、动态会话 | 状态和连接治理复杂 |
| WebRTC | 全双工媒体优先 | 浏览器/移动端语音 Agent | 信令、媒体与企业网络适配复杂 |
| gRPC | 一元或双向流 | 数据中心内部推理、张量服务 | 浏览器与公网兼容性较弱 |
五、三家协议最本质的区别
1. OpenAI:把一次模型运行拆成可组合的输出项
Responses 的重点不是换了路径,而是把"模型运行过程中产生的对象"全部类型化。它最适合平台直接承担工具编排和状态管理,也最容易承载新的 Agent 能力。
2. Anthropic:让每一步 Agent Loop 都显式、可回放
Claude Messages 对 system、tool use、tool result 和内容顺序要求严格,应用需要写更多编排代码,但请求轨迹更清晰。Managed Agents 则为不想自建循环的用户提供另一条路径。
3. Gemini:从一开始就把多模态作为内容结构,而不是附件扩展
Content/Part 对图片、音频、视频和文件十分自然;候选、安全信息与 grounding metadata 也更有 Google API 的结构化风格。Interactions 的出现进一步补上了 Agent 和服务端状态抽象。
六、企业统一网关应该如何抽象
最危险的做法,是定义一个超大的"厂商字段并集",然后声称完全兼容。字段能转发,不代表语义能无损映射。更稳妥的设计是分成三层:
#mermaid-svg-Kii0zy0i9mhHFCt3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Kii0zy0i9mhHFCt3 .error-icon{fill:#552222;}#mermaid-svg-Kii0zy0i9mhHFCt3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Kii0zy0i9mhHFCt3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .marker.cross{stroke:#333333;}#mermaid-svg-Kii0zy0i9mhHFCt3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Kii0zy0i9mhHFCt3 p{margin:0;}#mermaid-svg-Kii0zy0i9mhHFCt3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster-label text{fill:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster-label span{color:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster-label span p{background-color:transparent;}#mermaid-svg-Kii0zy0i9mhHFCt3 .label text,#mermaid-svg-Kii0zy0i9mhHFCt3 span{fill:#333;color:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .node rect,#mermaid-svg-Kii0zy0i9mhHFCt3 .node circle,#mermaid-svg-Kii0zy0i9mhHFCt3 .node ellipse,#mermaid-svg-Kii0zy0i9mhHFCt3 .node polygon,#mermaid-svg-Kii0zy0i9mhHFCt3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .rough-node .label text,#mermaid-svg-Kii0zy0i9mhHFCt3 .node .label text,#mermaid-svg-Kii0zy0i9mhHFCt3 .image-shape .label,#mermaid-svg-Kii0zy0i9mhHFCt3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Kii0zy0i9mhHFCt3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .rough-node .label,#mermaid-svg-Kii0zy0i9mhHFCt3 .node .label,#mermaid-svg-Kii0zy0i9mhHFCt3 .image-shape .label,#mermaid-svg-Kii0zy0i9mhHFCt3 .icon-shape .label{text-align:center;}#mermaid-svg-Kii0zy0i9mhHFCt3 .node.clickable{cursor:pointer;}#mermaid-svg-Kii0zy0i9mhHFCt3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .arrowheadPath{fill:#333333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kii0zy0i9mhHFCt3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Kii0zy0i9mhHFCt3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kii0zy0i9mhHFCt3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster text{fill:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 .cluster span{color:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Kii0zy0i9mhHFCt3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Kii0zy0i9mhHFCt3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Kii0zy0i9mhHFCt3 .icon-shape,#mermaid-svg-Kii0zy0i9mhHFCt3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kii0zy0i9mhHFCt3 .icon-shape p,#mermaid-svg-Kii0zy0i9mhHFCt3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Kii0zy0i9mhHFCt3 .icon-shape .label rect,#mermaid-svg-Kii0zy0i9mhHFCt3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kii0zy0i9mhHFCt3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Kii0zy0i9mhHFCt3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Kii0zy0i9mhHFCt3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 统一业务请求
规范化语义层
OpenAI Adapter
Anthropic Adapter
Gemini Adapter
原生响应与事件
统一观测与计费
建议统一的只是稳定语义:
json
{
"model": "logical-model-name",
"instructions": "...",
"turns": [
{
"role": "user",
"parts": [
{"type": "text", "text": "..."},
{"type": "image_ref", "uri": "...", "mime_type": "image/png"}
]
}
],
"tools": [],
"response_format": {"type": "text"},
"stream": true,
"state": {"mode": "provider_managed", "continuation_id": null},
"provider_options": {}
}
其中 provider_options 必须保留,用于承载无法跨厂商等价的能力。以下信息尤其不能在转换时丢失:
- 原始 content block / item / part 类型与顺序;
- 工具调用关联 ID、名称、参数及执行方;
- reasoning/thinking 的可回传项及加密状态;
- 引用、grounding、安全判定和拒绝原因;
- 缓存读写 Token、推理 Token、工具费用等细分 usage;
- 流式事件的原始类型、序号和完成状态;
- provider request ID、模型实际版本和错误对象。
不能假装完全等价的能力
| 能力 | 为什么难以无损转换 |
|---|---|
| 服务端内置工具 | 工具集合、计费、引用格式和数据保留策略不同 |
| 推理/思考项 | 可见性、签名、加密回传和跨轮复用规则不同 |
| 多候选生成 | Gemini 原生候选结构与多数单结果 API 不对称 |
| 实时语音 | 事件模型、音频编码、VAD、打断和连接协议不同 |
| 文件检索 | 文件资源、向量库、workspace/project 隔离模型不同 |
| 安全元数据 | 分类体系、拦截阶段和返回字段不同 |
| 状态化续接 | previous_response_id、Session、Interaction 的生命周期不同 |
网关若只需要"文本问答兼容",OpenAI-compatible Chat Completions 足够;若要支持 Agent、多模态和实时能力,就应该把"兼容程度"分级:
- L1 文本兼容:文本输入输出、常见采样参数;
- L2 多模态兼容:图片、音频、文件引用;
- L3 工具兼容:函数调用、并行调用、错误回填;
- L4 状态兼容:会话续接、推理项、压缩与缓存;
- L5 事件兼容:SSE/WebSocket 的完整事件语义与实时控制。
七、选型结论
- 普通聊天、最大生态兼容:优先 Chat Completions;
- 新建 OpenAI Agent 或复杂工具链:优先 Responses;
- 希望完全掌控工具循环与历史:Claude Messages 很清晰;
- 希望使用托管长任务 Agent:比较 OpenAI Responses/Agent 能力、Claude Managed Agents 与 Gemini Interactions 的运行时边界;
- 原生图片、音频、视频混合输入:Gemini 的 Content/Part 表达最自然,但并不意味着其他两家能力较弱;
- 低延迟语音:使用 OpenAI Realtime 或 Gemini Live,不要用 SSE 文本接口硬模拟;
- 大规模离线任务:使用各家的 Batch,而不是自己用同步接口堆高并发;
- 私有推理集群:外部保持 HTTP/OpenAI-compatible 便于接入,内部可用 KServe/Triton gRPC 获取强类型和高吞吐。
真正值得统一的,不是某一家厂商的 JSON 长相,而是消息、内容块、工具调用、状态、事件和资源之间的语义关系。未来的大模型网关也不再只是"改一下 model 字段再转发",而会逐步演变成一套协议编译器:既提供统一入口,又诚实保留各厂商不可互换的能力。
注:文中响应 ID、Token 数及部分模型输出均为说明结构而构造;模型名称和 Beta 接口会持续变化,生产接入时应以对应 API 版本的官方 Schema 为准。