事情本身不复杂,线索都在日志里。用 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 比手写可靠得多。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189