快速结论:这个报错通常出现在用 Pydantic BaseModel 给 Structured Outputs / Batch API 生成 response_format 时,to_strict_json_schema 输出里带了 $defs 和 $ref,看起来不像期望的扁平 schema。优先排查的是:这些键其实是被支持的,问题往往在于 schema 包装方式或 Batch 请求体写法,而不是要手工删掉 $defs/$ref。
适用环境:Issue 已确认的是 OpenAI Python SDK(openai/openai-python)。Issue 中未提供操作系统、Python 版本、CUDA、显卡或具体依赖版本,不要自行补齐。
最快修复方案:暂无确认的一步修复方案。Issue 中验证过的处理方向是:对 Batch Chat Completions,把 type_to_response_format_param(YourModel) 放进每个 JSONL 请求的 body.response_format;这是导入私有 helper 的 workaround,不是公开接口。
注意事项:from openai.lib._parsing._completions import type_to_response_format_param 属于私有 helper,后续版本可能变动,不建议长期依赖。官方维护者明确说明 $defs 和 $ref 是受支持的,不需要移除。公开接口方式可参考 #2656 中 Pydantic schema-export 的做法并使用 Chat Completions 的 json_schema 包装;支持公开 helper 的 #2695 和 #2993 仍在推进中,目前尚未合并。
问题场景
用户使用 OpenAI Python SDK 时,希望从 Pydantic BaseModel 直接生成符合 Structured Outputs 要求的 JSON Schema,用于 response_format。典型场景是无法像普通接口那样直接传 Pydantic 实例,例如 Batch API 的 JSONL 请求里只能放 JSON 对象,因此需要先把模型导出成 schema。用户尝试 to_strict_json_schema 后,发现输出包含 $defs 和 $refs,怀疑这不符合要求。
报错原文
BaseModel to jsonschema for Structured Outputs
I tried with `to_strict_json_schema` but it doesn't work as expected, it puts keys like $defs and $refs.
原因分析
可能原因一:对 Structured Outputs 的 schema 支持范围理解有偏差。维护者已明确说明 $defs 和 $ref 是受支持的,因此它们并不需要被删除,也不一定是失败的直接原因。
可能原因二:Batch API 不会自动帮你把 Pydantic 模型转换好。Batch 使用底层端点的请求参数,所以需要你提前把每个请求的 body.response_format 填成正确的 schema 参数结构。
可能原因三:调用的辅助函数不是公开接口,或者包装层级不对。Issue 中给出的 type_to_response_format_param 属于私有模块,行为可能在版本间变化;公开接口应参考 Pydantic schema-export 的方式并配合 Chat Completions 的 json_schema 包装。
环境排查
- 确认使用的 OpenAI Python SDK 版本,以及该版本中
type_to_response_format_param是否存在(这是私有模块,不是稳定公开 API)。 - 确认运行场景:是普通 Chat Completions 请求,还是 Batch API 的 JSONL 文件。
- 检查传给
response_format的结构是否符合当前端点要求,尤其是 Chat Completions 下需要的json_schema包装。 - 检查 Batch JSONL 中是否把 schema 放进了每个请求的
body.response_format,而不是放在文件顶层。 - 如果 schema 较大或包含嵌套模型,确认是否出现
$defs/$ref,但不要因为它们出现就直接判断为错误。
解决步骤
- 先确认你的 schema 输出里出现
$defs和$ref不是问题本身。官方文档说明这些定义是被支持的,不需要手工移除。 - 如果是 Batch Chat Completions,对每个请求单独生成
response_format,放到 JSONL 的body.response_format字段中。Issue 中验证过的写法是使用type_to_response_format_param(YourModel)。 - 如果不想依赖私有 helper,可优先尝试公开接口方向:参考 #2656 中 Pydantic schema-export 的指导,使用 Chat Completions 的
json_schema包装来构造response_format。 - 把最小可复现的 schema 和实际 API 返回的错误一起提交。维护者在关闭该 issue 时明确要求:如果仍然失败,请提供 minimal schema 和 API error。
- 如果你在 Responses API 场景,Issue 中还提到过
from openai.resources.responses.responses import _type_to_text_format_param,同样属于私有 helper workaround,使用前先确认版本中是否存在。
验证方法
用一个小型 Pydantic 模型生成 response_format,发起一次实际请求(或 Batch 请求),确认 API 不再返回 schema 相关错误并返回符合模型结构的输出。如果仍失败,保留最小 schema 和完整 API error 作为后续排查依据。注意:验证点不是“输出里没有 $defs”,因为 $defs/$ref 本身是被支持的。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


