模型输出通过 JSON 校验仍可能执行错事
文章区分语法解析、Schema 校验和业务语义与权限验证:合法字段也可能违背用户意图。以换货被误判为退款为例,说明应用仍需核对操作请求、订单归属及执行权限。
AI 深度解读
LLM 返回的 JSON 能解析、字段齐全,甚至通过了 schema 校验,应用仍然可能执行错误操作。原文用一个客服场景说明:用户明确要求换货、拒绝退款,模型却提取出了合法的退款指令。
作者的核心主张是:结构化输出只能解决数据怎么接进系统,不能替应用判断数据是否可信。对正在把 AI 接入业务流程的开发者,这个区分比继续打磨 JSON 格式更重要。
JSON 合法,为什么还会办错事
假设客服助手要把用户消息转成结构化请求。用户表达的是:商品损坏了,希望换货,不想退款。模型却返回:
{
"order_id": "ORD-1042",
"action": "refund",
"reason": "damaged_item"
}
这段输出展示了问题:字段看起来合理,却表达了错误意图。要盯住的是 "action": "refund",它直接违背了用户拒绝退款的要求。
作者建议把校验拆成三个层次:
- 语法校验:能否解析成 JSON,有没有多余文本、引号错误或未闭合的对象。
- 结构校验:必填字段是否存在,类型是否正确,
action是否属于允许的选项。 - 业务校验:订单是否属于当前登录用户,用户是否真的要求这个操作,订单是否满足处理条件,执行前是否需要确认。
第三层需要的信息,往往不在模型返回的对象里。
例如,schema 可以拒绝一个不存在的操作,但只要 refund 属于合法选项,就无法仅凭字段类型和枚举判断用户究竟要不要退款。订单归属也一样:一个格式正确的订单号,不代表当前用户有权操作它。
通过结构校验,只能说明这份数据符合接口约定,不能说明它符合用户意图和业务规则。
模型负责理解,后端负责决定能不能执行
作者提出,把模型输出视为一份「候选解释」。后端再查询订单、应用规则,并在请求有歧义时追问。
这个边界很关键。模型可以提取「用户可能想做什么」,但不能因为返回了一个合法的 action,就直接获得执行权限。
另一个容易忽略的设计是:允许模型表达信息不足。
如果字段必填,而可选值只有退款和换货,输入又不足以支持判断,模型就会面临必须选一个的压力。作者建议让不完整请求进入 needs_clarification 状态,避免强行归入 refund 或 replacement。
但增加一个状态还不够。应用需要有对应流程:提出后续问题、保留已获得的信息,并在补齐信息前等待,不执行操作。
作者还给出了四类测试输入:
- 用户明确拒绝某项操作。
- 一条消息出现两个不同的订单号。
- 请求缺少标识符。
- 用户在对话中途改变主意。
这些测试不能只检查提取字段,还要检查应用下一步做了什么。即使最终 JSON 完全合规,系统也可能选错订单,或者继续执行用户已经撤回的请求。
我的判断
这篇最有价值的地方,是把「格式正确」「理解正确」「允许执行」分开了。三者需要不同证据,也应该由不同校验负责。对于涉及退款、换货这类有实际后果的操作,这个划分很实用。
不过,原文是一套设计建议,没有给出实测结果、错误率或方案对照。它列出了值得测试的场景,没有证明某种模型、提示词或结构化输出方案能把错误降到什么程度。
相比继续收紧 schema,增加业务检查能覆盖订单归属、处理资格等问题;但对用户意图的判断,作者也没有给出具体实现。由规则识别否定表达,还是再调用模型复核,原文没说清。不能把「后端检查」理解成一句万能解法。
澄清也有适用条件。缺少订单号可以追问,越权订单则应由权限规则拦截,不能靠用户再确认一次放行。开发时仍然要区分信息不足、意图冲突和权限不满足。
能拿来做什么
- 在 Node 后端接收模型输出时,把 JSON 解析、schema 校验和业务检查分别实现。通过前两项后,再检查当前用户、目标订单和操作条件。
- 给信息不足的请求设计
needs_clarification路径,保留已提取字段,并让界面展示具体追问,补齐信息前暂停执行。 - 给现有 AI 客服流程加入原文的四类测试,同时断言提取结果和后续行为,尤其检查是否误触发退款或换货。
- 检查前端是否把模型返回的操作直接当成成功结果展示。界面应根据后端实际处理状态,区分等待澄清与已经执行。