DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

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对象能创建还不够。