各家的 OpenAI 兼容到底兼容到什么程度:六个平台的兼容层对照

2026-08-25

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

「兼容 OpenAI」不是一个开关,它至少是四层深浅不同的东西:能不能只改 base_url 就发出第一个请求(这一层几乎所有平台都过得去)、官方点名兼容的端点有哪几个(这一层差别已经很大)、你原来传的参数会被忽略还是被拒绝(这一层差别更大)、平台自己的专有能力从哪个口子塞进来(各家给的出口不一样)。真正把人坑住的从来不是第一层。代码能跑、返回结构也对,但思考内容跑进了 content 字段的标签里,或者你精心调过的采样惩罚参数被静默丢弃——这些都发生在后三层。下面按这四层,把智谱 GLM、Kimi、阶跃星辰、MiniMax、Gemini、xAI 六家官方文档里明写的兼容边界摆出来。

第一层:改 base_url,这一层各家都过

这一层是各家宣传语最一致的地方,但写法上仍有值得留意的细节。

智谱在 OpenAI API 兼容文档里给的做法是保留 OpenAI SDK 的客户端类,把 api_key 换成智谱的密钥,再补一个 base_url 指向智谱开放平台的 paas/v4 路径。官方同时给了环境要求:Python 版本有下限,OpenAI SDK 版本不低于 1.0.0,并专门加了警示说旧版本可能存在兼容性问题(具体版本以官方文档当前版本为准)。

Kimi 的说法更直白,官方原文是「我们的 API 在请求/响应格式上兼容 OpenAI Chat Completions API」,并给出三条推论:可以直接用 OpenAI 官方的 Python / Node.js SDK;支持大多数兼容 OpenAI 的第三方工具和框架,文档里点名的有 LangChain、Dify、Coze;只需把 base_url 指向 Moonshot 的 /v1 路径即可切换。

阶跃星辰的迁移文档给得最细,除了 OpenAI Python SDK 和 TypeScript SDK 的前后对照,还额外给了 LangChain 与 LangChain.js 的改法——LangChain 那边要动的是 ChatOpenAI 初始化时的 openai_api_keyopenai_api_basemodel_name 三个参数,LangChain.js 那边则是 modelNameopenAIApiKeybasePath。同一件事在两个语言的封装里字段名不一样,这是照抄 Python 示例改 JS 代码时最常见的卡点。

MiniMax 走的是另一个路子:官方快速开始里不往 OpenAI() 构造函数里传参,而是让你导出 OPENAI_BASE_URLOPENAI_API_KEY 两个环境变量,然后直接 client = OpenAI()。这种写法对已有代码侵入最小,代价是配置藏在环境里,排查时得先确认进程真的读到了这两个变量。

Gemini 的兼容层入口是 generativelanguage.googleapis.com 下的 v1beta/openai/ 路径,鉴权用标准的 Authorization: Bearer 头;它的原生 REST 则用 x-goog-api-key 请求头,两者不是一回事。官方对迁移成本的表述是只需改 api_keybase_urlmodel 三处,但同一页官方还给了一句反向建议:如果你本来就没在用 OpenAI 库,推荐直接调 Gemini 原生 API,而不是绕兼容层。这句话很少有人转述,却是选型时最该听进去的一句。

xAI 的兼容入口是 api.x.ai/v1,官方在快速开始里同时给了 xAI 自家 SDK 与 OpenAI SDK 两套示例。

★ 这一层唯一的暗坑在智谱:GLM Coding Plan 的调用地址和开放平台不是同一个。官方切换模型文档里分了三条——Claude Code 这类走 Anthropic 兼容的用 api/anthropic 路径,Codex 用 api/v1 路径,其他 OpenAI 兼容工具用 api/coding/paas/v4 路径。拿开放平台那个 base_url 去配编程套餐,或者反过来,都属于配置对不上而不是能力不支持。

第二层:官方点名兼容的端点,各家清单差得很远

这一层是被忽略最多的。多数人默认「兼容 OpenAI」等于整套 API 都兼容,实际上各家官方点名的只是其中一部分。

阶跃星辰把清单列得最清楚,官方在迁移页直接罗列了与 OpenAI 兼容的接口:对话补全、上传文件、获取文件列表、获取文件信息、获取文件内容、删除文件、获取模型列表、查询单个模型信息、生成图片。清单以官方文档为准,但结构上可以看出:文件族和模型族齐了,图片生成也在内,而 embeddings、audio 这些 OpenAI 生态里常用的族并不在这份点名清单上。

Kimi 的 API 概述里给了一张端点一览表,除了 /v1/chat/completions/v1/models、以及一整族 /v1/files 接口之外,还有两个明显不属于 OpenAI 协议的端点:/v1/tokenizers/estimate-token-count 用来算 token,/v1/users/me/balance 用来查余额。这两个端点是 Kimi 自己扩出来的,OpenAI SDK 的方法映射里没有对应项,得自己发 HTTP 请求。反过来说,这也是兼容层的一个共性——平台会在 OpenAI 的路径空间里挂自己的东西,你的网关如果按 OpenAI 的端点白名单做转发,这些扩展端点会直接被挡掉。

MiniMax 的 OpenAI SDK 文档聚焦在 chat completions 上,同时另有 OpenAI 形态的模型列表与单模型查询接口文档。

Gemini 这边有一条结构性限制值得单独记:它的 Batch API 目前仅适用于 generateContent 这个原生 API(官方页首注意事项)。也就是说,兼容层和批量能力是两条不交叉的路——你不能既用 OpenAI SDK 的写法又走它的批量通道。类似地,Gemini 的 Interactions API 只支持隐式缓存,要用显式缓存必须改用 generateContent。缓存这一层各家的形态差异更大,展开在五家缓存机制的横向对照里。

结论:六家里真正被所有人点名兼容的只有对话补全这一个端点。凡是超出对话补全的能力——文件、批量、缓存管理、token 计数、余额查询——都要按平台单独查一遍,不能假设 OpenAI SDK 里有的方法这边就能用。

第三层:参数会被忽略,还是会被拒绝

这两种失败模式的排查难度天差地别。被拒绝会给你一个错误,被忽略则完全没有信号。

MiniMax 在 OpenAI SDK 文档末尾的注意事项里,把这件事写得最坦白:部分 OpenAI 参数会被忽略,官方举的例子是 presence_penaltyfrequency_penaltylogit_bias 这一类;n 参数仅支持值为 1;旧版的 function_call 已废弃,要改用 tools;而 temperature 超出其取值范围会返回错误。注意这几条的性质不一样——惩罚类参数是静默忽略,temperature 越界是显式报错。如果你的旧代码里带着一套调好的惩罚参数迁过来,接口不会拦你,你只会发现输出风格和以前对不上,然后去怀疑模型本身。

智谱这边有一条同类的说明:文档标注 temperature 的取值区间与 OpenAI 侧不一致,并专门写明 do_sample = False(即把 temperature 置零)这种用法在 OpenAI 调用中并不适用。很多把温度写死为零求确定性输出的代码,迁过来第一件要改的就是这里。具体区间以官方文档当前版本为准。

智谱同一页还有一句官方警示原文:「某些场景下智谱与 OpenAI 接口仍存在差异,但不影响整体兼容性」。这句话诚实,但它没有给出差异清单——也就是说,这一层没有一份可以照着核对的表,只能在自己的调用面上逐个参数确认。做迁移评估时,把这句话当成「需要自己排一遍」的信号,而不是「差异可以忽略」的安慰。站内那篇OpenAI 兼容层最常见的断点讲的是跨厂商的通用断点类型,可以和这一节对着看。

第四层:专有能力从哪个口子进来

各家的专有能力最终都要塞进 OpenAI SDK 那套固定签名里,主流出口是 extra_body,但塞进去之后的字段名和语义各不相同。

智谱的思考模式走 extra_body 里的 thinking 对象,官方示例是把 type 设为 enabled;流式读取时思考内容出现在 delta.reasoning_content,正文仍在 delta.content,两者要分开累积。

MiniMax 的口子更多。thinking 参数的 type 官方给的取值是 disabledadaptive;官方同时明确,对 M2.x 那一代模型 thinking 无法关闭,即使传了 disabled 也仍会保持开启——这是个典型的「参数收下了但不生效」的场景。另一个参数 reasoning_split 不控制思考开不开,只控制思考内容怎么返回:为 true 时通过 reasoning_contentreasoning_details 返回,为 false 时思考内容会保留在 content 字段里的 <think> 标签内。★ 这一条是兼容层里最阴的一个坑:你的代码完全按 OpenAI 的写法读 content,读到的却是带标签的混合内容,下游解析全乱,而接口从头到尾没报过错。MiniMax 还有一个 service_tier 参数控制请求准入档位,官方给的取值是 standardpriority,省略时用 standardpriority 计费高于标准档,具体比例见官方定价页。

Kimi 的说明里区分了两种扩展形态:thinking 参数要通过 SDK 的 extra_body 传递,而 partial 不是顶层请求参数,它是写在 messages 里 assistant 消息上的字段。这个区别很重要——如果你的网关把请求体按「顶层参数」和「消息数组」两块分别处理,partial 会被划到消息那一侧,透传逻辑得单独照顾。

Gemini 的做法是做映射而不是加字段:OpenAI 的 reasoning_effort 被映射到 Gemini 的 thinking_level(3.x 代)或 thinking_budget(2.5 代),档位是 minimal / low / medium / high 四档。官方明确 reasoning_effortthinking_levelthinking_budget 功能重叠,不能同时使用。要传 Gemini 专有字段则走 extra_body.google.thinking_config。另外官方写明 2.5 系列可以把 reasoning_effort 设为 none 来关闭思考,但 2.5 Pro 与 3 系列无法关闭推理。这一段的完整展开见Gemini 的 OpenAI 兼容层怎么用

兼容的是哪一代 OpenAI 协议:xAI 是个例外

前面五家的兼容层都以 Chat Completions 的形态给出,xAI 这边情况不同。

xAI 官方在 Chat Completions 文档顶部挂了警示:这是一个遗留端点,新功能会先落到 Responses API,并引导用户去看迁移对照。官方给的两者差异对照里,Chat Completions 侧是无状态的、必须自己重发完整历史、不返回推理内容、只有函数调用而没有原生的搜索/代码执行/MCP 这类工具、每次请求按完整历史计费;Responses 侧则有 previous_response_id 续接会话、服务端存储、加密推理内容、原生工具支持和对话历史的自动缓存。

参数映射官方也给了:messages 对应 inputmax_tokens 对应 max_output_tokens,另外新增了 previous_response_idstoreinclude 三个 Chat Completions 侧没有的参数。响应结构差异更大——Chat Completions 把内容放在 choices[0].message.content,Responses 放在 output 数组里的带类型条目中。

值得注意的是,OpenAI SDK 本身也能调 Responses:xAI 快速开始里给的 OpenAI SDK 示例用的就是 client.responses.create。所以在 xAI 这里,「用 OpenAI SDK」和「用 Chat Completions 形态」是两件可以分开的事。

这对做多厂商网关的人是个实打实的设计约束:如果你的内部抽象照着 Responses API 那套有状态模型设计,接国产平台时要自己补一层降级——把会话状态维护在自己这边,每次拼完整历史发出去。反过来,如果内部抽象是 Chat Completions 形态,接 xAI 时就是在用它明确标注为遗留的那条路。

多轮与工具调用:兼容层最容易出静默 bug 的地方

MiniMax 在 OpenAI SDK 页专门开了一节讲这件事:在多轮 Function Call 对话中,必须把完整的模型返回(即 assistant 消息,包含 tool_calls 字段)加回对话历史,以保持思维链的连续性。官方进一步说明,原生 OpenAI 形态下 content 字段会包含 <think> 标签内容,需要完整保留;启用 reasoning_split 后思考内容通过 reasoning_details 单独提供,同样需要完整保留。

很多历史管理代码只把 rolecontent 两个字段存下来,tool_callsreasoning_details 在存档时就丢了。这类代码在单轮场景下毫无问题,多轮工具调用时表现为模型行为逐渐跑偏,而且不会有任何报错。迁移检查清单里应该有专门一条:确认历史回传的是完整的 assistant 对象,不是你自己重新拼的精简版。站内的换厂商迁移检查清单可以拿来做这一步的底稿。

xAI 侧的对应事实是:Chat Completions 端点是无状态的,官方明确说不会带着你上一次请求的上下文来处理新请求,历史必须自己回传。

结构化输出:这一层各家最不齐

Kimi 的 response_format 文档把结构化输出的边界讲得比多数平台都细,几条机制值得记下来:

strict 设为 false 时,API 只保证输出是合法的 JSON 对象,不强制约束内部字段结构。也就是说 strict 不是「要不要开」的问题,而是两种强度完全不同的契约。

官方按模型区分了 schema 支持程度:较新的编码向模型对 anyOf / oneOf / $ref / additionalProperties 这类特性支持更完善,较早的模型在复杂 schema 下更容易触碰限制,官方对后者的建议是保持 schema 简单。

官方还给了一个静态校验工具用来自检 schema 兼容性,但同一页紧接着补了一句关键限定:即使 schema 含 anyOf / oneOf / $ref,API 也常能正常返回 200,且响应中不会出现 warning 字段——因此静态工具更适合做入口检查,实际兼容性以目标模型的在线调用结果为准。这句话的意思是,结构化输出这一层连「有没有出问题」的信号都不一定拿得到。

另外两条实用机制:schema 过于复杂或 prompt 与 schema 矛盾时,模型可能输出不完整的 JSON,表现为 finish_reason 为 length,官方建议检查这个字段并适当增大输出长度上限;以及是否设置 response_format 不会破坏前缀缓存,可以按请求粒度自由调整。

区域与合规:境外供应商要单独判一遍

Gemini 官方文档列出的可用国家/地区中不包含中国大陆,官方对不在支持区域者给出的替代路径是改用 Gemini Enterprise Agent Platform 中的 Gemini API。官方另有两条与区域无关的准入条件:最低年龄要求,以及需在 Google 账号中完成年龄验证。

所以在做兼容层抽象时,境外供应商这一档要按企业采购路径单独评估,国内业务优先走国内合规平台。这一层判断和技术兼容度是两件事,别混在一张表里比。

收尾:一份可以照着走的自测顺序

把「跑通了 hello world」当成「兼容」,是这件事上最贵的误判。建议按下面的顺序自测,顺序本身就是按坑的隐蔽程度从浅到深排的:

先确认 base_url 和密钥形态对上,注意同一家可能有多个入口(智谱的开放平台与编程套餐就是两个)。然后拿你实际用到的端点逐个对照官方点名的兼容清单,对话补全之外的一律不要假设。接着把你现有请求体里的每一个参数在目标平台文档里找一遍,重点分清哪些是被忽略、哪些是越界报错。再看专有能力的出口:思考内容是走独立字段还是混在 content 的标签里,这一条决定了你的解析代码要不要改。最后跑一轮多轮工具调用,检查历史回传是否保留了完整的 assistant 对象与推理字段。

这五步里,第三步和第四步不会给你任何报错信号,也正是返工成本最高的两步。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。