事情本身不复杂,线索都在日志里。用 OpenAI structured outputs 的 json_schema,strict 设了 true,但 schema 里的 object 没写 additionalProperties: false,返回多出 confidence 字段,Pydantic 校验报 extra_forbidden。
第一反应是「required 没列全字段,模型自行补全」,验证下来不成立。
排查方向其实有限,先把可能性排一排。strict 模式要求每个 object 显式声明 additionalProperties 为 false。还有一种是嵌套 object 只在外层写了约束。
还有一种情况,Pydantic 设了 extra=forbid 但生成的 schema 没同步。
上来先把实际下发的 schema 打印出来核对
python -c "import json;print(json.dumps(json.load(open('schema.json')),ensure_ascii=False)[:300])"
给每个 object 补上 additionalProperties: false
python -c "import json;s=json.load(open('schema.json'));s['additionalProperties']=False;print(json.dumps(s)[:120])"
再往下用 SDK 的 parse 接口直接拿 Pydantic 对象
python -c "from openai import OpenAI;c=OpenAI();print(hasattr(c.beta.chat.completions,'parse'))"
等前面都确认过,再对 200 条返回逐个做模型校验
python -c "from pydantic import BaseModel;print(BaseModel.model_config)"
当时还开着另一个排查窗口,两边日志对照着看才定位到。
同一份数据我导出了两份,一份留底,一份拿来试。
怎么算真的好了,看的是同一批现象。返回体里不再出现 schema 之外的字段,Pydantic 校验 200 条全部通过,日志里 extra_forbidden 归零。
提醒一点。strict 不是全局开关,它要求每个嵌套 object 都自洽,用 SDK 从 Pydantic 模型生成 schema 比手写可靠得多。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
