OpenAI嵌套schema报additionalProperties缺失,检查SDK与$ref
沿错误context检查最终schema,区分旧SDK内联引用遗漏与手写对象限制,并核对1.59.8正式修复。
使用Pydantic嵌套模型请求Structured Outputs,API返回400:
In context=('properties', 'largest_star'),
'additionalProperties' is required to be supplied and to be false.
顶层schema已经写了 additionalProperties: false,不代表每个嵌套对象都有它。先按错误中的context定位最终发送的schema,再判断是手写结构缺字段,还是旧SDK展开引用时遗漏。
已核对的旧版故障发生在openai Python 1.59.7,使用带 Field(description=...) 的嵌套模型与AzureOpenAI解析接口。正式1.59.8于2025年1月17日修正了这条引用展开路径。没有核定该旧配置的实际Azure API版本,不能把它扩大成所有Azure或所有现行模型的故障。
检查发出去的对象,而非只看模型定义
Structured Outputs要求对象限制为声明过的字段,相关对象schema需要 additionalProperties: false。这个约束不仅在顶层,也涉及属性里的对象、数组元素以及引用定义或联合类型中的对象。
例如,一个包含嵌套星体对象的schema,内层也需要限制额外字段:
{
"type": "object",
"properties": {
"largest_star": {
"type": "object",
"properties": {
"name": {"type": "string"}
},
"required": ["name"],
"additionalProperties": false
}
},
"required": ["largest_star"],
"additionalProperties": false
}
这里只说明对象层次,不是一份可直接发送的完整API请求。Chat Completions、Responses和Azure请求的外层格式、模型及API版本要按实际调用核对。required、可空字段与其他schema关键字也需要符合接口支持的子集。
Pydantic在本地拒绝额外字段,与服务端收到的JSON Schema是两个环节。只查看 model_json_schema() 也可能漏掉SDK之后的转换。应检查脱敏后的最终schema及完整context,不输出原始业务数据、密钥或整份用户提示词。
1.59.7的问题在引用展开之后
旧处理函数先递归约束已有对象,再处理同时带 $ref 与description等属性的节点。引用被展开成内联对象后,没有再次执行严格schema处理,于是某些新出现的对象缺少限制。
1.59.8在这次展开后重新递归处理,正式包的对应源码与回归用例包含这项修正。核对过的正式3.28.0实现仍有这一逻辑,但这不能保证任何自定义schema都合格。
如果实际运行版本是匹配的旧包,选择相容且包含修复的正式版本,再比较新旧最终schema。开发机升级不等于服务进程升级,虚拟环境、镜像与锁文件需要一起核对。不要直接修改安装目录的私有函数,也不必为了躲开这个旧缺陷删除所有字段说明。
手写schema仍需自己维护契约
SDK的处理只会在对象缺少 additionalProperties 时补上false,不会自动把显式true改成false。自定义生成器已经输出true,或者后续封装又重写了schema时,仍会失败。
不要把 strict 关闭后当成同等修复,这会改变对输出的约束。修正对象结构后,仍需检查接口是否接受以及接收端是否能处理预期字段。模型响应中的拒绝、截断或内容解析问题,要与请求阶段的400分开;可对照JSON语法与字段验证。
若这项调用来自批处理,先按Batch的custom_id逐项对账保留失败项,不要反复提交整个批次。最终schema中的报错路径已经具备正确约束,并且实际允许的验证请求通过,才能确认当前故障恢复;仅看到本地Pydantic对象能创建还不够。


