合同抽取要求返回 parties 数组,实测 8% 的返回外面多包了一层 data,下游 pydantic 校验直接失败,重跑相同的输入才偶尔正常。
把日志和配置对完,能解释这个现象的基本就这几处。提示词示例只有一层,模型按自己习惯补包装;用了 json_object 模式但没有 schema 约束结构;模型把之前工具返回的结构当成模板来模仿;解析层只做 json.loads,没有结构兜底。
动手时先用 json_schema 强约束结构
python -c "print({'response_format':{'type':'json_schema','json_schema':{'name':'c','strict':True,'schema':{'type':'object','required':['parties']}}}})"
解析时剥掉多余的一层
python -c "import json;d=json.loads('{\"data\":{\"parties\":[]}}');print(d.get('data',d).get('parties'))"
随后加 pydantic 模型做严格校验
python -c "from pydantic import BaseModel;class C(BaseModel):parties:list;print(C(parties=[]))"
末了用真实样本回归成功率
python -c "print(round(196/200,3))"
白天有业务在跑,能验证的部分都压到了晚上做。
当时还开着另一个排查窗口,两边日志对照着看才定位到。
改完先别撤,确认这几项。200 条样本的解析成功率达到 100%,多余包裹被兜底剥掉,校验失败时原始返回能落盘复查。
strict 能省掉大部分兜底,但 schema 里可选字段一多模型仍会补结构,解析层别省。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
