openai 兼容格式的 api,多家中转混着接时先核对这五处

接入与开发

面向同时接入多家中转服务的开发者,把兼容格式的请求结构拆成几处可逐项核对的地方,减少换站后参数错位。

一家跑通了三家,第四家开始返回奇怪的东西。多数时候不是对方坏,是各家对「兼容」的理解差了一点:字段名一样,嵌套多一层;收下了,又悄悄忽略。这篇给一份照着核对的清单,从请求体的形状开始,到响应里哪几个字段你在写代码时根本不该依赖,逐项过一遍。

一家跑通了三家,第四家开始返回奇怪的东西。多数时候不是对方坏,是各家对「兼容」的理解差了一点:字段名一样,嵌套多一层;收下了,又悄悄忽略。你调了半天代码,最后发现对方压根没读那个参数。

这篇给一份照着核对的清单。从请求体的形状开始,到响应里哪几个字段你在写代码时根本不该依赖,逐项过一遍。换站前后按顺序验一遍,能省掉不少来回猜。

「兼容」说的是一层皮,不是整套协议

先说清楚这个词实际指什么。所谓 openai 兼容格式的 api,通常只保证三件事:鉴权头的写法、路径的命名、messages 数组的结构。这三件对齐了,你换个 base_url 就能跑通最小请求。超出这三样的部分,全靠各家自己自觉。

麻烦就在「自觉」上。服务端多收了一个字段,不等于它认了这个字段——很可能解析时直接跳过,HTTP 照样返回 200。你以为参数生效了,其实输出跟没传一样。这种静默丢弃是接入多家中转最常见的坑,而且不报错,最难查。

  • 鉴权头:多数站认 Bearer 那一套,但个别站对头的名字和拼写有自己的脾气,先拿最小请求试
  • 路径命名:有的站把版本段写死在 base_url 里,有的要你自己拼,拼错直接 404
  • messages 数组:role 和 content 的嵌套层级各家基本一致,这是兼容的地基
  • 其余一切:采样参数、工具调用、流式细节,都属于「各家自己看着办」的范围

请求体那几格,先按这几个位置核对

请求体是最容易错位的地方。下面这张表把常出问题的字段和该放的位置对一遍,填错格子是接入多家时最常见的低级错误。

字段/配置该放哪常见错法
model请求体顶层塞进 messages 或自造对象里
messages请求体顶层数组role 用了 system、user、assistant 之外的值
temperature、max_tokens请求体顶层嵌进一个自定义的 params 对象
流式开关请求体顶层放在 query 参数里,各家支持度不一
工具调用字段请求体顶层结构抄了另一家的写法,字段名差一个字母

核对方法不复杂。先单跑一条最简请求,把这些可选字段全去掉,只留 model 和一条 user 消息,确认通了。再一项一项加回来,每加一项跑一次。哪一步开始不对,问题就锁定在那个字段上。

还有个笨办法特别管用:把自己实际发出去的 JSON 原样打日志。很多人读文档读十遍,不如看一遍自己真正发出去的东西——经常一眼就看到某个字段名拼错了,或者多套了一层。

响应里哪些字段不该写进业务逻辑

请求发对了,响应也不能全信。有几类字段看起来有用,但换一家站就变样,写进业务逻辑里迟早出事。

usage 计数
各家算法不一,做内部估算可以,拿去跟用户对账容易扯皮
id、created 这类标识
换站就变,别让它们进入去重键或缓存键
system_fingerprint
有的站根本不返回,有的返回固定值,别拿它做任何判断
流式分块
节奏和结尾结构差异最大,解析器要能容忍空块和异常结束

流式这块单独说一句。别假设一定有收尾块,也别假设每个块都带内容。写解析器时把「收到空块」和「连接提前结束」都当成正常路径处理,比事后补丁省事。

拿不准某站的实际返回长什么样,先去站内的探针页看它怎么对比请求和响应,再自己抓一次真实响应存下来当基线。以后换站,拿新响应跟基线对一遍,差异一目了然。

换一家站前后,按这个顺序验

  1. 最小请求探通只发 model 加一条 user 消息,不带任何可选参数。验两件事:通不通,返回结构对不对。这一步不过,后面都别谈。
  2. 字段逐个加回把业务里真正用到的字段一项项加回去,每加一项跑一次。出问题时能直接定位到是哪个字段,不用大海捞针。
  3. 最后调并发和超时格式全对了再压并发。顺序颠倒的话,限流报错会被你误判成格式问题,白查半天。
  4. 存一份响应基线把通过验证的完整请求和响应各存一份。下次换站或对方改接口,拿新结果跟基线对,差异直接看出来。

这套顺序的价值在于把问题隔离开。格式问题、限流问题、鉴权问题混在一起查,是最耗时间的。先通最小请求,再逐项加字段,最后才碰并发,每一步只验一件事。

下一步想知道某家中转站的实际兼容表现,别只看它自己的说明。去站内的中转站检测页看探针怎么对比请求和响应,再自己抓一次真实响应,比读十篇介绍都实在。

常见问题

兼容格式的 API 是不是等于照着 OpenAI 文档写就一定没问题?

不是。兼容覆盖的是最外层的形状,具体某个采样参数、某个工具调用字段各家支持程度不同。写代码时把可选参数当成可能被忽略来处理,比假设它一定生效安全得多。

同一套代码接多家中转,怎么少改?

把请求体构造收在一个函数里,字段用白名单管理,换站时只改白名单和 base url,业务代码不碰。遇到某家不认某个字段,在白名单里剔掉就行。

请求通了但结果不符合预期,先查哪?

先打日志看实际发出去的 JSON,确认字段位置对不对;再确认这个字段在该站是否真被处理。顺序反了容易把字段没生效误判成模型能力问题。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。