
能输出JSON不等于能进生产:Schema之后还要做值校验

要让大模型稳定返回可供程序处理的JSON,先定义字段结构,并选用支持JSON Schema约束的模型与接口;收到结果后,应用仍要确认响应完整、解析JSON、验证结构,再核对字段值与原始输入及业务规则。能解析只说明格式过关,字段齐全也不代表抽取的事实正确。
生产流程应按这个顺序设置关口:检查接口状态和结束原因,解析响应,用约定的Schema校验对象,最后执行订单号比对、分类依据检查等业务校验。失败结果先与自动执行流程隔离,再按错误类型决定重试、标记未知或交人工复核。
JSON Object、Schema和业务规则分别拦什么
JSON Object解决语法问题:输出可以是合法JSON,却未必包含程序预期的键。JSON Schema进一步规定对象有哪些字段、字段采用什么类型、分类值落在哪个枚举内,以及能否出现未定义属性。因此,同一段输入即使每次都得到可解析的JSON,下游仍可能因键名变化或类型不符而无法读取。
业务规则检查的是值的来源与含义。订单号是字符串,只能说明类型正确,不能说明它确实出现在用户消息中;摘要是字符串,也不能保证它没有把“无法登录”写成“已经登录”。若结果将触发工单分派或写入业务系统,这一层需要独立于模型的格式约束。
用同一份订单抽取Schema定义字段
以下是条件示例。假设输入为“订单A123对应账号无法登录,请尽快处理”,程序需要order_id、priority和reason三个字段。示例业务规则把明确出现“请尽快处理”的消息归为urgent;normal留给按规则判定为常规的消息,证据不足时使用unknown。这些分类条件应由业务方确定,不能仅凭枚举名称让模型自行推断。
简化Schema为:{"type":"object","properties":{"order_id":{"type":["string","null"]},"priority":{"type":"string","enum":["urgent","normal","unknown"]},"reason":{"type":"string"}},"required":["order_id","priority","reason"],"additionalProperties":false}。三个字段均须出现;order_id允许null,表示没有从输入中提取到订单号。reason必须是字符串,其内容是否忠实于原文仍要另行判断。
JSON Schema对象规则区分属性缺失与属性值为null:required只要求键存在,允许null还需在该字段的类型中声明;additionalProperties设为false才会拒绝未定义的键。仅把字段写进properties不会使它自动成为必填项。若下游要求固定对象形状,“必填但可为null”和“允许省略”应明确选择其一。
同一份约束放进两种输出模式
以阿里云百炼的千问结构化输出说明为例,JSON Object模式将response_format的type设为json_object,只保证合法JSON;JSON Schema模式设为json_schema,并在json_schema中传入名称、schema及strict:true,以约束结构。该模式只适用于文档列出的部分模型;文档还提醒,设置max_tokens可能截断输出中的JSON字符串。
若只用JSON Object,条件结果{"订单号":"A123","priority":"high","reason":"无法登录"}仍是合法JSON,但键名不符,high也不在约定枚举中。按上面的Schema,期望的对象可写成{"order_id":"A123","priority":"urgent","reason":"无法登录"}。这两个对象用于说明约束差异,并非实际调用的测试结果;接入其他平台时,还须按其接口格式传参并核对支持的Schema关键字。
结构通过后,核对字段值
Gemini结构化输出文档说明,其模式支持JSON Schema规范的子集,并要求应用验证字段值、处理符合架构却在语义上出错的输出。应用侧因此应使用约定版本的Schema校验收到的对象,再执行能够依据原文或业务数据判断的规则。
在条件示例中,若模型返回order_id为A132,字段存在、类型正确,priority也可能合法,但输入写的是A123。“订单号必须能在原始消息中找到”可由程序直接比对。若订单号需要经过规范化才能与业务系统匹配,应先定义规范化规则,不能把任意相近的编号视为同一笔订单。
null也需要结合输入解释:用户未提供订单号时,它可以表示“未提取到”;用户明明给出A123却返回null,则是抽取失败。这两种情况都不同于“业务系统中不存在该订单”。分类依据不足时可以保留unknown;若摘要改变了否定关系或遗漏影响处理的条件,即便它符合string类型,也不能用于自动分派。
按失败位置决定重试和降级
先检查响应是否正常结束,再解析和校验,可避免把半截输出误当成完整结果。重试应带上原始输入与明确的失败原因,并设置次数上限;每次新结果都须从完整性检查重新走完验证流程。
- 接口报错、响应为空或结束原因显示截断:不解析半段内容,也不提交下游。可重新请求完整响应;仍失败时返回明确的处理失败状态。
- JSON无法解析,或缺少字段、类型错误、出现额外属性:记录具体错误并重新请求,必要时仅修复格式。修复后的对象仍须再次解析和运行Schema校验。
- priority出现high等非法枚举:拒绝该值,并要求在约定选项内重新分类。原文不足以支持urgent或normal时使用unknown,不把陌生标签悄悄映射为有效值。
- Schema通过,但订单号与原文不符或摘要歪曲事实:阻止自动执行。能确定的字段由程序依据原文重新提取;仍需判断的内容保留未确认状态,或交人工复核。
上线配置应把每个字段的缺失、null和非法值分别写明,并给每条失败路径指定返回状态。对会改变业务状态的动作,只有完整响应、结构校验和业务校验都通过后才提交;失败记录保留原始输入、响应及错误原因,才能定位问题发生在哪一道关口。
相关阅读:
相关文章
订阅我们的新闻通讯
将最新 Web3、AI 和加密货币新闻直接发送到您的邮箱。




