报错是这么冒出来的。抽取服务把模型返回的 JSON 交给 pydantic 校验,v1 下 amount 传 “128.50” 能自动转 float,升到 v2 后报 Input should be a valid number,三成抽取结果被判成失败。
中间走过弯路,把「模型返回的金额带千分位逗号,float 解析直接失败」当成主因,改完现象没变。
把日志和配置对完,能解释这个现象的基本就这几处。v2 改成单遍校验,隐式类型转换的范围收紧。少数情况下是开了 strict 之后完全不做转换。
不容易想到的是,字段声明成 float 而实际是带单位的字符串。
定位是哪个字段失败
python -c "from pydantic import BaseModel,ValidationError;print(BaseModel.model_validate)"
再往下在字段上加前置转换
python -c "from pydantic import field_validator;print(field_validator)"
接着用 BeforeValidator 清洗千分位与单位
python -c "from pydantic import BeforeValidator;print(BeforeValidator)"
拿历史样本做一次回归
python validate_batch.py --dir samples --report
恢复的判定其实很直接。历史样本的校验通过率从 70% 回到 99%,真正非数字的样本仍被拦住,失败原因能定位到具体字段。
放宽校验会掩盖模型输出格式变差的信号,转换层单独记一条日志,别让脏数据静默通过。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
