把 OpenAPI 里的 schema 原样塞进 response_format,里面带 $ref 和 definitions,接口 400,原文 Invalid schema for response_format: $ref is not supported。

一开始怀疑是「definitions 里的定义需要内联展开」,查了一圈,方向不对。

排查方向其实有限,先把可能性排一排。结构化输出不支持 $ref 间接引用。也可能是allOf 与 anyOf 在严格模式下受限。

少数情况下是schema 里带了注解类字段。

动手时先看一眼 schema 顶层结构

python -c "import json;print(list(json.load(open('schema.json')).keys()))"

然后用工具检查严格模式兼容性

python schema_lint.py --in schema.json --strict

内联展开后再发一次最小请求

curl -s -o /dev/null -w '%{http_code}' https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d @req_schema.json

末了把展开后的版本固化成文件

python schema_lint.py --in schema.json --strict --out schema_flat.json

中间停过一次,把已经改的东西回滚干净,再重新来一遍。

同样的操作我在测试机上先走了一遍,线上只做验证过的部分。

这台环境是别人交接的,不少默认值被动过,只能一项项核。

别只看报错消失,验证要多做一步。请求返回 200,输出能被 pydantic 模型校验通过,不再出现 schema 不合法。

容易忽略的是,严格模式只认一个子集,$ref 和组合关键字都要提前展开,直接拿服务端 schema 用基本都会踩。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189