从 OpenAI 迁到国产模型平台:一份可执行的迁移检查清单
数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。
几乎每一家平台的迁移文档都写着同一句话:换掉 api_key,加上 base_url,其他代码不用动。这句话在”第一个请求能返回 200”这个层面上是真的,在”线上跑一周不出事”这个层面上是不够的。真正会咬人的是四类东西:被兼容层静默忽略掉的参数(调了等于没调,不报错)、思考内容的取法各家都不一样(迁过去之后 reasoning_content 拿不到,或者混在 content 里没剥出来)、结构化输出的 JSON Schema 不一定能原样搬过去、错误码体系是各家自己一套,你原来那套只判 HTTP 状态码的重试逻辑会把”欠费”当成”限流”一直退避重试。下面按真实改造顺序走一遍,每一项都注明出处,核不到的地方我会直接说官方文档没写。
第一步:先弄清楚兼容层到底覆盖了哪些端点
“兼容 OpenAI”是个范围很宽的说法,各家的口径明显不同,迁移前先把这件事问清楚,能省掉后面一半的返工。
智谱在模型迁移文档里给的是最宽的表述:「OpenAI SDK 为我们提供了一个开箱即用的调用工具,对此,我们在后端兼容了 OpenAI 的所有 Endpoint,提供了便捷的迁移方式,仅需更换 api_key 与 base_url,就可以使用我们的模型。」而它另一份 OpenAI API 兼容文档里又挂了一条警告:「某些场景下智谱与 OpenAI 接口仍存在差异,但不影响整体兼容性。」这两句话分别出自模型迁移页和 OpenAI API 兼容页,放一起读才是完整的意思——端点这一层是齐的,字段那一层未必。
阶跃星辰给的是另一种口径:不说”全部兼容”,而是直接列出与 OpenAI 兼容的接口清单,包括 Chat Completion、文件的上传/列表/信息/内容/删除、模型列表与单个模型查询、生成图片。这种写法对迁移方其实更友好——清单之外的能力,你就该假定要走它自己的接口。
Kimi 的说法是请求/响应格式上兼容 OpenAI Chat Completions API,并明确点名支持 LangChain、Dify、Coze 这类兼容 OpenAI 的第三方工具与框架。MiniMax 的表述是”新增了对 OpenAI API 格式的支持”,落点也在 Chat Completions。
xAI 这边要特别注意方向:它同样支持用 OpenAI SDK 指向自家端点,但官方在 Chat Completions 页顶挂了警告,说明这是一个 legacy 端点,新功能会先到 Responses API,并给了迁移指引。也就是说你从 OpenAI 的 Chat Completions 迁过去,落地的是一个官方标注为遗留的接口。关于端点层面的通用差异,站内另有一篇各家 OpenAI 兼容端点的覆盖范围对照可以配合看。
第二步:base_url 与鉴权,比想象中容易踩
改 base_url 本身没难度,难在三件配套的事。
一是环境变量名各家不同。智谱文档建议把 Key 写进环境变量而不是硬编码;Kimi 的示例读 MOONSHOT_API_KEY;MiniMax 干脆建议直接覆盖 OpenAI SDK 认的 OPENAI_BASE_URL 与 OPENAI_API_KEY 两个环境变量,这样连客户端初始化代码都不用改。这三种风格如果混在同一个仓库里,后面接第二家、第三家的时候会很难维护。
二是鉴权头。Kimi 与 xAI 的文档里都是标准的 Authorization: Bearer 形式;Gemini 的兼容层同样用 Authorization: Bearer 加它的 API Key,但它的原生 REST 接口用的是 x-goog-api-key 请求头——同一家两条路两种写法,封装的时候别按一种写死。
三是 Key 本身的归属:Kimi 官方错误页里明确写了平台 Key 隔离——中国站与国际站的账户、余额和 API Key 完全独立,混用会返回 401。迁移期间你手上很可能同时有好几把 Key,401 排查的第一步应该是确认”这把 Key 属于哪个站”,而不是去怀疑请求头拼错了。
顺便,各家文档对 SDK 版本都提了要求:智谱和 Kimi 都写明 OpenAI SDK 版本不低于 1.0.0,Python 需要 3.7.1 以上,Kimi 另外要求 Node.js 版本足够新。智谱还额外加了一句警告,说旧版本可能存在兼容性问题。这条在老项目上迁移时经常成为第一个卡点。
第三步:model 参数不是改个字符串那么简单
模型名当然要换,但要连带确认两件事。
一是模型名写错的报错形态。智谱的错误码体系里,模型不存在有独立的业务码,同时还有一条”当前模型不支持某种调用方式”的错误——也就是说模型名对了、端点也对了,组合起来仍然可能不被支持。Kimi 那边模型不存在与账号无权访问该模型是同一个 resource_not_found_error,文档提示要同时检查 model 参数拼写和账号等级,这两个原因返回一样,光看报错分不出来。
二是要不要走兼容层这件事本身。Gemini 的态度值得单独拎出来:官方一方面说从 OpenAI 库切过来只需改三行(api_key、base_url、model),另一方面明确建议如果你尚未使用 OpenAI 库,推荐直接调用它的原生 API 而不是走兼容层。这个建议其实适用于所有平台——兼容层的价值在于保住存量代码,新写的代码走原生接口能拿到更完整的能力。
第四步:把会被静默忽略的参数挑出来
这一步值得多花点时间,因为出问题时不报错。
MiniMax 在 OpenAI SDK 文档末尾的警告里写得非常直白:部分 OpenAI 参数(如 presence_penalty、frequency_penalty、logit_bias 等)会被忽略;n 参数仅支持值为 1;旧版的 function_call 已废弃,请改用 tools。前两条属于”你传了,它收下了,然后什么也没发生”,如果你原来的服务靠 frequency_penalty 压重复、靠 n 一次拿多个候选再排序,迁过去之后这部分逻辑会安静地失效。
采样参数的取值区间也要逐个核。智谱在参数说明下挂了一条注记,明确规定了自己的 temperature 取值区间(具体区间见官方参数说明),并注明用 temperature 设为 0 来求确定性输出的那种写法,在它的 OpenAI 调用里并不适用——这对做评测、做回归测试的团队影响很大,因为”温度归零求可复现”是很常见的做法。至于 OpenAI 侧的取值范围与它是不是真的对不上,本文不做比较,请你自己拿两边的官方参数文档对照一遍再决定要不要改代码。MiniMax 则是另一种处理:文档写明 temperature 超出它规定的范围会返回错误,区间与推荐值以官方文档当前版本为准。一个静默失效、一个直接报错,迁移时都得改,但排查难度完全不同:前者要靠人肉比对参数表才能发现,后者第一个请求就会把问题顶出来。
实操建议:迁移前先把你代码里所有传给 chat.completions.create 的参数列一张表,逐个去目标平台文档里搜。搜不到的,就当它不生效,把依赖它的业务逻辑先降级掉。
第五步:思考内容的取法,每家都不一样
如果你迁的是带推理能力的场景,这一节是重灾区。
智谱走的是 extra_body 传 thinking 对象,流式响应里从 delta.reasoning_content 取思考内容、从 delta.content 取正文,两个字段要分别处理。Kimi 的 thinking 参数同样需要通过 SDK 的 extra_body 传递,它的文档还专门提醒:思考模型在返回 content 的同时可能还会返回 reasoning_content,做结构化输出时只能解析 choices[0].message.content,不要拿整个响应对象去反序列化。
MiniMax 的设计更需要注意,因为 reasoning_split 这个开关直接决定了输出形态:文档写明它为 false 时,原生 Chat Completions 响应会把思考内容保留在 content 字段中的 <think>...</think> 标签里;为 true 时,思考内容才会通过 reasoning_content 和 reasoning_details 返回。官方的参数表和 schema 里都没有给这个开关标注默认值,所以迁移时别去猜它默认开还是默认关,在请求里显式传一个值,默认形态以官方文档当前版本为准。这件事的后果很具体:如果你直接把 content 当正文渲染给用户,又恰好落在不拆分的那一侧,思考过程就会一起显示出去。另外要分清两个开关的分工——thinking 控制的是开不开思考(官方写明对 M2.x 系列 thinking 无法关闭,即使传 disabled 也仍会保持开启),reasoning_split 只控制返回形态、不会开启或关闭思考,两者是正交的,这一点文档里说得很清楚。
Gemini 的兼容层做了参数映射:OpenAI 的 reasoning_effort 映射到它的 thinking_level 或 thinking_budget,官方同时写明这两组功能重叠、不能同时使用;想传它的专有字段要走 extra_body 下的 google.thinking_config。xAI 那边则是能力上的差异——官方对照表里写明 legacy 的 Chat Completions API 不返回 reasoning content,要拿到带加密推理内容的完整支持得走 Responses API。
第六步:多轮工具调用的历史怎么拼
工具调用的参数格式各家都对齐了 OpenAI 的 tools,但”把模型返回塞回历史”这一步的要求不一样。
MiniMax 单独立了一节讲这件事:在多轮 Function Call 对话中,必须把完整的模型返回(即 assistant 消息,含 tool_calls 字段)加回对话历史,以保持思维链的连续性;并且 content 字段里的 <think> 标签内容需要完整保留,开了 reasoning_split 之后 reasoning_details 同样需要完整保留。很多现成的封装为了省 token,会在回填历史时把 assistant 消息裁成只剩 content 或只剩 tool_calls,这种写法迁过去就会破坏它要求的连续性。
xAI 的对照表则提示了另一个方向的差异:Chat Completions 是无状态的,多轮必须每次重发完整历史,且每次按全量历史计费;Responses API 支持用 previous_response_id 续接,并会自动缓存会话历史。同样一段多轮代码,接在哪个端点上,成本结构完全不同。
第七步:结构化输出的 schema 未必能原样搬
这一项的风险在于它不会自己暴露:本地测一两个简单 schema 通常都能过。
Kimi 的 response_format 支持 json_object(只保证是合法 JSON 对象)和 json_schema(按 Schema 约束字段)两种模式,这和 OpenAI 的形态是对得上的。但它的文档明确写了两件 OpenAI 那边没有的事:一是把 strict 设为 true 时,你的 schema 需要符合它自己的 MFJS(Moonshot Flavored JSON Schema)规范,官方提供了 walle 命令行工具做静态自检;二是不同模型对 JSON Schema 特性的支持程度存在差异,复杂 schema 下 $ref、oneOf 这类特性的表现并不一致,文档建议在业务层做二次校验。
更麻烦的一句在文档后面:即使 schema 包含 anyOf / oneOf / $ref,API 也常能正常返回 200,且响应中不会出现 warning 字段。翻译成迁移语言就是——schema 不完全兼容时,你不会收到任何告警信号,只会偶尔拿到字段对不上的输出。所以这一项必须用真实业务 schema 跑覆盖,不能只测样例。
第八步:错误处理这一层基本要重写
各家的错误结构根本不是一套东西,这里最能体现”兼容”只兼容到请求格式为止。
智谱是双层结构:外层是 HTTP 状态码,响应体里还有一个业务错误码,给出更具体的描述。它的对照表里有一条特别值得警惕——账户欠费返回的 HTTP 状态码是 429。如果你的重试封装看到 429 就按限流做指数退避,那么账户欠费的时候,它会安静地退避重试到超时为止,而不是立刻把问题暴露出来。
Kimi 的错误对象带的是 error.type 字符串,同一个 429 下面至少分了几种完全不同的语义:节点过载、账户欠费停用、token 额度不足、组织级并发限制、组织级 RPM/TPM/TPD 限制。它的排障建议里明确写着,节点过载这一类由服务端容量导致,充值或提升等级并不能直接消除,只能按 Retry-After 退避重试。这几种情况混在一个状态码里,不看 error.type 是分不开的。
Gemini 的错误对象用的是 code(机器可读的 snake_case)加 message 两个字段,rate_limit_exceeded 与 quota_exceeded 都是 429 但处置完全相反——前者退避重试有用,后者是每日配额耗尽,退避多少次都没用。它还有一条结构性差异:标准请求把错误放在 HTTP 状态码加响应体里,流式请求则是通过 SSE 流发送 event_type: "error" 事件。只判 HTTP 状态码的客户端会漏掉流式过程中发生的错误。这一格的细节可以看Gemini OpenAI 兼容层的具体形态。
结论很直接:迁移时不要指望复用原来的错误分支,按目标平台的错误文档重写一遍映射层,把”该重试”、“该报警”、“该停机”三类分开。
第九步:用量字段与账单口径要重新对一遍
usage 这个字段名各家都有,但里面装的东西不一样。
xAI 的 Chat Completions 响应示例里,usage 除了常规的三个计数,还有 prompt_tokens_details,里面细分了文本、音频、图片和 cached_tokens。MiniMax 需要在流式调用里显式设置 stream_options.include_usage 才会在流中返回 token 用量——不设的话流式请求拿不到用量,对账会缺一块。Gemini 的缓存命中量要看响应里的 usage.total_cached_tokens,而且它的计费依据比多数平台多一项:官方 FAQ 列出的四项是输入 token 数、输出 token 数、缓存的 token 数,以及缓存 token 的存储时长——存储本身单独计价,这在国产平台里不常见,做长上下文缓存方案时容易漏算。
同样要注意的是输出侧的口径:Gemini 定价页表头明写输出价格包含思考 token。迁移后如果你只按”看得见的正文长度”估成本,估算会系统性偏低。具体单价一律去各家官方定价页看,本文不列。
第十步:限流与配额得单独申请,别假设自动对齐
限流不会跟着你的代码一起迁过来。
阶跃星辰的迁移文档里给了一条很实用的路径:测试完成后可以联系官方客服,由官方提供与 OpenAI 对标的 TPM / RPM 限制,帮助无缝迁移调用。也就是说初始限额和你在 OpenAI 那边的额度没有任何关系,需要主动去谈。
Gemini 有一条容易被想当然的规则:限流按项目(project)应用,不是按 API 密钥应用——很多团队迁移时习惯多申请几把 Key 来分摊压力,在这个模型下完全无效。它的维度是 RPM / TPM / RPD,超出任何一个即触发,不是综合评估;RPD 在太平洋时间午夜重置,不是本地时间。Kimi 那边的限流则是组织级的,并发、RPM、TPM、TPD 各有各的错误提示。
第十一步:境外平台的可用性,按官方口径处理
如果你的候选里包含境外平台,这一条必须先过。
Gemini 官方的可用区域列表里不包含中国大陆,官方对不在支持区域的用户给出的路径是改用 Gemini Enterprise Agent Platform 中的 Gemini API;另外还有两条与区域无关的准入条件:最低年龄要求,以及需要在 Google 账号中完成年龄验证。对国内团队来说,可选的合规做法是走企业采购路径,或者直接选用国内平台——本文前面列的智谱、Kimi、MiniMax、阶跃星辰都提供 OpenAI 兼容形态,迁移改动量基本一致。除此之外的任何路径本站不讨论。
收尾:三条别省掉的动作
按上面十一步走完,最后留三条提醒。
第一,别在同一个发布里既换平台又换模型代际。参数默认值、思考行为、schema 支持度这三件事会同时变,出了问题分不清是平台差异还是模型差异。
第二,兼容层不是终点。智谱明确说部分功能需要通过它的官方 SDK 调用,Gemini 建议新代码直接用原生 API,xAI 把 Chat Completions 标成了 legacy。合理的做法是:用兼容层完成第一阶段的平迁,把服务跑起来,然后把真正吃能力的那几条链路逐步换到原生接口。
第三,留回滚开关。把 base_url、Key、model 三项做成配置,灰度期间保留一键切回的能力,比事后回滚代码快得多。如果你要同时接多家,建议先读一遍站内的换厂商迁移通用清单和智谱 OpenAI 兼容的能力边界,把差异集中封在一层适配器里,别让它们渗进业务代码。