这类问题我又碰上了一次。用 response_format 的 json_schema 加 strict true 抽取合同要素,schema 里字段全部 required。接口返回 200 且结构校验通过,但下游收到的 amount 是空字符串,当事人姓名偶尔是字符串 null。环境是 Python 3.11 加 openai 1.50,schema 里 amount 只写了 type 为 string。
第一反应是「业务侧的 pydantic 模型没设最小长度和取值约束」,验证下来不成立。
把日志和配置对完,能解释这个现象的基本就这几处。schema 只约束类型不约束内容,空字符串也算合法 string;模型对缺失值填了 null 字面量而不是真正的空值;抽取 prompt 没给出缺失时应该填什么。
给 schema 补上最小长度和枚举约束
python -c "import json;s=json.load(open('schema.json'));s['properties']['amount']['minLength']=1;print(json.dumps(s,ensure_ascii=False))"
业务侧再用 pydantic 严格模式解析一次
python -c "from pydantic import BaseModel,Field;print('strict model ready')"
接着对空值样本单独回放定位触发条件
python replay.py --input fails.jsonl --schema schema.json --out report.csv
等前面都确认过,再把缺失约定写进 prompt 后重跑同一批
python batch_extract.py --input contracts.csv --prompt extract_v3.txt
怎么算真的好了,看的是同一批现象。回放那 200 条样本,amount 为空的比例从 11% 降到 0,校验失败会抛出明确字段名而不是静默入库。
提醒一点。strict 只保证结构合法,语义合法要靠业务校验兜底;空字符串和字面量 null 最容易被直接写进数据库。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
