协议转换与流式传输
Sub2API 的协议兼容不是字段改名,而是需要维护角色、内容块、工具调用、thinking、usage 和事件状态的双向转换。
三类主要协议
Anthropic Messages
核心结构:
systemmessages[].role/content- content block:text、image、tool_use、tool_result、thinking 等
tools与tool_choicemax_tokensstream
OpenAI Responses
核心结构:
instructionsinputitems。- output items 与 content parts。
- function tools、image generation、web search。
previous_response_id。store、service tier、reasoning。
Gemini generateContent
核心结构:
- system instruction。
contents[].role/parts。- function declarations/calls/responses。
- generation config、safety settings。
- thinking 与 usage metadata。
转换必须处理什么
| 语义 | 转换难点 |
|---|---|
| system/instructions | 位置和覆盖规则不同 |
| assistant history | role 名和 item 结构不同 |
| 图片 | URL、base64、mime type 和大小限制 |
| 工具调用 | call ID、参数 JSON、并行调用 |
| 工具结果 | 与原 call 的关联和 role |
| thinking/reasoning | 字段、签名、是否可见 |
| prompt cache | 平台支持与计费分类 |
| stop reason | 枚举值不同 |
| usage | 输入、输出、缓存和图像 Token 口径 |
转换不支持某字段时,必须明确拒绝、丢弃或降级,不能无声改变语义。
Messages → OpenAI Responses
典型步骤:
- 解析 Claude system 和 message content blocks。
- 转换为 instructions 与 input items。
- 把工具定义转换为 Responses function tools。
- 映射模型名和 reasoning 参数。
- 注入必要的 Codex metadata 或模板。
- 上游返回后,把 Responses events 转回 Anthropic SSE。
如果配置了 forced Codex instructions template,必须显式包含 ExistingInstructions 才会保留客户端 system 内容。
Chat Completions 桥接
传统 Chat Completions 的 messages、functions/tools 与 Responses input/output 不完全等价。桥接需要处理:
- developer/system/user/assistant/tool role。
max_tokens与max_completion_tokens。- reasoning 和 verbosity。
- stream chunk 与 finish reason。
客户端依赖非常具体的 chunk 顺序时,应单独做兼容测试。
SSE 事件
SSE 响应是:
event: <type>
data: <json>转换器需要维护增量状态,例如:
- 当前 message/response ID。
- 当前 output item 和 content block index。
- tool call 参数字符串的增量拼接。
- usage 和 stop reason。
- 是否已经向客户端写出首个有效事件。
一旦已经写出内容,HTTP status 无法再改变,后续错误只能编码为协议允许的流式错误事件或直接断流。
Keepalive
等待用户/账号槽位或上游长时间无数据时,服务可以发送 keepalive,防止客户端和代理认为连接空闲。
需要协调三层时间:
- 应用 stream keepalive interval。
- 应用 stream data interval timeout。
- 反向代理/CDN idle timeout。
代理 timeout 必须大于应用允许的最长空闲间隔。
Responses WebSocket
OpenAI WS 支持比普通 HTTP 更复杂:
- 连接按账号池化。
- OAuth 与 API Key 可以使用不同开关和因子。
- previous response 可能要求复用上下文连接。
store=false影响连接隔离策略。- ingress 可以选择 ctx pool、passthrough 或 HTTP bridge。
- 失败后可以回退 HTTP/SSE。
多实例下 WS 连接是实例本地状态。负载均衡器如果在同一会话中随机切换实例,Redis 可以提供账号提示,但不能迁移已经建立的 WebSocket 连接。
HTTP/2 与 H2C
- 客户端到 Sub2API 可以启用 H2C。
- Sub2API 到上游也有 OpenAI HTTP/2 配置与 HTTP/1 fallback。
- 代理不支持 HTTP/2、CONNECT 或长连接时可能触发自动 fallback。
H2C 不应直接暴露公网,通常由反向代理在 TLS 后转发。
响应头过滤
上游响应可能包含敏感、冲突或不适合下游的 Header。系统有默认 allowlist 和 force remove,并允许配置额外放行。
不要直接透传所有上游 Header,尤其是:
Set-Cookie。- 上游内部 trace/debug 信息。
- hop-by-hop headers。
- 会暴露上游身份或基础设施的信息。
大请求与图片
包含 base64 图片的请求会显著放大:
- 反向代理请求体。
- Go 解析内存。
- 协议转换复制。
- 日志与错误体风险。
同时设置 CDN、Nginx/Caddy、server 和 gateway 限制,并优先使用 URL 或对象存储而不是超大 base64。
兼容性测试矩阵
每个新平台/模型至少测试:
- 非流式文本。
- SSE 文本。
- system/developer instruction。
- 单工具和并行工具调用。
- 多轮 tool result。
- thinking/reasoning。
- 图片输入。
- 取消请求和客户端断开。
- 上游 4xx/5xx。
- usage 与 stop reason。