接入第三方大模型,「OpenAI 兼容」这四个字,最近把我坑得不轻。
最近给部门的 ChatBI 接一个新模型,绕了好几个弯才发现,问题跟 API key、网络都没关系,而是藏在「兼容」两个字背后的一层平台改动里。整个过程记下来,挺值得的。
先说说发生了什么
ChatBI 是我们部门的 BI 分析产品。你用大白话问一句,它去理解问题、挑数据集、写 SQL、跑查询,最后把结果整理成图表或表格给你。
这套流程里,模型光会聊天没用。它得一步一步吐出后端能解析的东西——选了哪张表、SQL 长什么样、字段对应关系是什么。中间任何一步让它自由发挥,后面就接不上了。
所以 ChatBI 接新模型时有个「测试连接」按钮。这名字有点误导,它测的不是 API key 通不通,而是这个模型能不能按 ChatBI 的规矩干活。我这次接的是火山引擎 Ark Coding Plan 的 OpenAI 兼容入口,模型选 GLM-5.2,点下测试——翻车:
当前模型不支持 ChatBI 所需的结构化输出能力(
response_format=json_object)。请更换支持json_schema或json_object的模型后重试。
测试连接到底在测什么
我翻了下后端代码。这个按钮不是发一句「你好」看模型回不回,它会逼着模型做几件事:先试严格的 json_schema,再试带工具调用的结构化输出,都不行才退回 json_object。
换句话说,普通聊天能跑通,跟 ChatBI 能用,根本是两回事。它要的是「让模型按固定格式吐 JSON」,不是「让模型陪你聊」。
先把配置问题排掉
带着这个判断,我用 curl 自己复现。先发一个最普通的、不带任何 response_format 的请求——HTTP 200,GLM-5.2 正常回话。base_url、key、模型名,统统没问题。
然后我把嫌疑对象加上:
"response_format": { "type": "json_object" }火山回了 400,原样贴出来:
{ "error": { "code": "InvalidParameter", "message": "The parameter `response_format.type` specified in the request are not valid: `json_object` is not supported by this model. Request id: 0217823740999218c80d243bafb90575ac6ccce9142197dbcaca6", "param": "response_format.type", "type": "BadRequest" }}注意看 message 和 param 两个字段:它不是说「不认识 response_format 这个参数」,而是「认识,但 json_object 这个值当前模型不支持」。方向完全不一样,我当时就是顺着这条往下想的。
差点就信了「模型不行」
到这一步,一个现成的结论摆在面前:GLM-5.2 不支持结构化输出,换模型,收工。
说实话我差点就信了。但总觉得哪里不对——GLM-5.2 是主流大模型,结构化输出几乎是各家标配,不至于连 json_object 都不支持吧?要么是火山这边有特殊限制,要么……是我下结论下早了。
排查这种事最怕第一个看起来合情合理的解释,它刚好能解释现象,又刚好把你带偏。
绕开火山,直连官方
既然怀疑是火山这一层的问题,最直接的验证就是——别走它,直连源头。
我拿 GLM-5.2 的官方接口重跑了一遍同样的结构化请求,response_format=json_object 直接通过,啥事没有。
那问题就清楚了:模型本身没问题,锅在火山这一层。
又试了两个模型,规律一模一样
为确认这不是 GLM-5.2 的个例,我又拉了另外两个模型做对照:
| 模型 | 官方直连 | 火山引擎(OpenAI 兼容入口) |
|---|---|---|
| GLM-5.2 | 正常 | json_object 不支持 |
| DeepSeek v4 | 正常 | 同样的报错又来了 |
| MiniMax M3 | 正常 | 正常 |
对照很有意思:GLM-5.2 和 DeepSeek v4 一进火山就翻车,报错一模一样;可 MiniMax M3 在火山里跑得好好的。也就是说,火山不是一刀切把结构化输出全掐了,而是只对部分模型做了调整。
真正的根因
把这些拼起来,结论基本钉死了:
IMPORTANT不是模型不支持结构化输出,也不是协议本身的问题。是火山引擎的中转层对部分模型做了改动,把 OpenAI 兼容入口下的
response_format结构化输出给掐了。模型官方接口本来都支持,进了火山这道门,部分能力就被改了。
还有个细节也指向同一个方向。火山 Coding Plan 其实同时开了 Anthropic 协议入口,那边没有 response_format 这回事,结构化输出靠 tools + input_schema 的 Tool Use。我换这个入口再测 GLM-5.2,模型照样乖乖吐结构化 JSON。所以不是结构化能力被彻底砍了,只是 OpenAI 入口这条具体路径被改了。
对 ChatBI 的影响,以及怎么办
麻烦的地方在于,ChatBI 现在只实现了 OpenAI 这一套 provider,能力检测死死绑在 json_schema / json_object 上。结果就是:哪怕模型本身支持、官方直连也正常,只要走的是被改过的火山入口,就过不了测试,用不了。
要吃下这类模型,大概三条路:
| 方案 | 做法 | 优点 | 代价 |
|---|---|---|---|
| ① 守着 OpenAI 结构化输出 | 只放行能通过 response_format 的模型/入口 | 不用改架构 | 把火山里这类被改过的模型挡在门外 |
| ② 加一个 Anthropic provider | 支持 Messages API + input_schema + tool_use | 能绕过限制,schema 约束还在 | 要改配置结构、加测试链路、适配 Agent SDK |
| ③ 弱 JSON 模式 | 不传 response_format,靠 prompt + 后端解析重试 | 改动最小 | 不稳定,BI 场景不敢用 |
方向上 ② 最对,工作量也最大;① 是当下的保底。
几句闲话
最后说几句感受,不一定对:
「OpenAI 兼容」这四个字,水比想象的深。兼容往往只管到普通对话那层,response_format、tool_choice 这些高级参数被默默裁掉是常有的事,别拿文档里的「兼容」当全功能。
接 Agent 类产品,「能聊天」只是入场券。真正卡门槛的是工具调用和结构化输出,这两项不行,模型再聪明也用不上。
怀疑某一层有问题,就绕开它直连源头验证一次。这次要不是直连了官方,我大概已经把「GLM-5.2 不支持结构化输出」当成结论写进文档了。
报错的措辞值得逐字看。「不认识这个参数」和「这个值模型不支持」,是两条岔路,走错就一直在死胡同里打转。
结论
这次的根因跟 API key、配置都没关系,也不是模型不行。是火山引擎对部分模型做了改动,掐掉了 OpenAI 兼容入口下的结构化输出。好在它还留着 Anthropic 那扇门,tool_use 这条路能走通。后面要让 ChatBI 正式支持这类模型,方向是加一个 Anthropic provider,而不是去放开 OpenAI 那边的测试。
希望这篇能让你下次接第三方模型时,少绕一个弯。