数据合同印章闸门拦下字符串类型的数量字段
9

10 月

Python jsonschema:给模型输出加一道可执行的数据合同

模型返回 {"quantity":"3"},字符串看起来像数字,但下游库存接口可能只接收整数。Python 的 jsonschema 可以在请求外部系统之前拦住这类结构错误。本文给出安装、完整校验脚本及正反例,不调用模型,不把字段合规误称为事实正确。

jsonschema 放行整数数量、拦截字符串数量的校验示意图
字段合规只说明结构正确,不代表内容事实正确

这个库负责什么,不负责什么?

python-jsonschema实现 JSON Schema 校验,适合数据提取、模型结构化输出以及工具参数入口。它读取你定义的合同,并判断对象是否符合约束;不会根据商品名推断合理数量,也不会批准退款或修改权限。

从国产模型场景选型进入具体开发后,结构合同有助于让不同候选经过同一道闸门。但合同本身要由业务确定,不能让待测模型临时生成自己的合格标准。

从哪里下载,系统与许可门槛是什么?

官方下载是 PyPI 的 jsonschema 页面,源码与许可证见官方仓库。项目采用 MIT 许可,分发时应保留对应许可证要求;应用中的数据、其他依赖和远程模型服务不自动继承该许可。包本身不要求模型账号。

本教程选择 Python 3.12 作为练习环境,不声称它是所有版本的最低要求。macOS/Linux 用 python3,Windows 用 py -3.12 建环境;如果没有该解释器,先安装受支持的 Python。正式升级前重新核对目标版本的 Requires-Python,不要默认旧系统也能安装最新版。

怎样安装到隔离环境?

在新建练习目录运行对应平台的一组命令。虚拟环境避免污染系统 Python;后续执行显式使用环境内解释器,不依赖终端是否激活。安装需要联网,但下面的本地字面量校验不需要模型 API。

python3 -m venv .venv
.venv/bin/python -m pip install jsonschema
.venv/bin/python -m pip freeze

Windows PowerShell 对应命令:

py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install jsonschema
.\.venv\Scripts\python.exe -m pip freeze

记录实际安装版本,团队验证通过后锁定依赖。不要把“成功下载包”当成“已经验证业务合同”;团队 AI 配置管理也需要配合样本与版本记录才能复现。

最小校验脚本应该怎样写?

将下面完整代码作为 validate_output.py 执行。它显式选择 Draft 2020-12,先检查 Schema 自身,再列出数据错误。正例应没有错误;字符串数量、零数量和额外字段分别触发失败。这里描述的是预期行为,本篇未运行该脚本。

from jsonschema import Draft202012Validator

schema = {
    "type": "object",
    "required": ["item", "quantity"],
    "properties": {
        "item": {"type": "string", "minLength": 1},
        "quantity": {"type": "integer", "minimum": 1},
    },
    "additionalProperties": False,
}
Draft202012Validator.check_schema(schema)
validator = Draft202012Validator(schema)
samples = [
    {"item": "notebook", "quantity": 3},
    {"item": "notebook", "quantity": "3"},
    {"item": "notebook", "quantity": 0},
    {"item": "notebook", "quantity": 3, "approved": True},
]
for index, sample in enumerate(samples, start=1):
    errors = list(validator.iter_errors(sample))
    print(index, "PASS" if not errors else "FAIL")
    for error in errors:
        print(list(error.path), error.message)

macOS/Linux 用 .venv/bin/python validate_output.py;Windows 用 .\.venv\Scripts\python.exe validate_output.py。接模型时先解析 JSON 文本,解析失败与 Schema 失败分别记录,不让异常直接穿透到写入逻辑。

哪些常见误区会让校验形同虚设?

仅写 properties 不会强制字段存在,需同时写 required;未限制额外属性时,模型可以输出合同之外的键。另一方面,过严的合同也可能拒绝业务允许的空值,应该用真实需求决定,而不是追求“越严格越好”。

官方校验文档说明 format 检查需要额外启用,不能只写 format: email 就假定已经验证邮箱。外部 $ref 还涉及引用资源管理;本例不使用远程引用,生产中不要让不可信 Schema 任意控制资源加载。对外错误信息也应脱敏。

什么时候选择别的方案,怎样接入业务?

如果你的 Python 应用已经统一使用带类型模型的数据验证库,优先评估现有方案,不为单个字段重复引入第二套约束。需要跨语言共享 Schema 时,显式合同更方便;但各语言实现与草案支持仍要用同一组样本核对。

校验失败应转向有限重试、人工审核或明确拒绝,而不是自动把字符串、单位和未知值强制转换。流程设计可以参考生产级 Agent 工程原则。语义真实性、权限和幂等仍需分别验证,这个库只是数据入口的一道闸门。

FAQ

问:Schema 通过代表内容真实吗? 答:不代表,只说明满足已定义的结构约束。

问:只有 properties 会要求字段必须出现吗? 答:不会,还需 required 等存在性约束。

问:本例是否调用了模型接口? 答:没有,示例仅校验本地合成数据。

参考来源

核查日期:2026-10-06。安装与接口依据官方资料,示例输出未经本轮执行验证。

{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Schema 通过代表内容真实吗?", "acceptedAnswer": {"@type": "Answer", "text": "不代表,只说明满足已定义的结构约束。"}}, {"@type": "Question", "name": "只有 properties 会要求字段必须出现吗?", "acceptedAnswer": {"@type": "Answer", "text": "不会,还需 required 等存在性约束。"}}, {"@type": "Question", "name": "本例是否调用了模型接口?", "acceptedAnswer": {"@type": "Answer", "text": "没有,示例仅校验本地合成数据。"}}]}

RELATED

Posts