CMU AI AGENTS / 从一句回答,到一次真实动作 / 第 04 课

JSON 写对了,为什么订单仍然可能下错?

区分可解析、符合 schema、字段含义正确、业务前提成立四层。约束解码可限制部分格式,却不能证明数量合理或库存真实。

完整讲解 · 条件对照 · 理解检查所在单元与学习顺序官方课件全页浏览

JSON写对了,为什么订单仍然可能下错?

从四个“看起来都差不多”的请求开始

继续库存场景,系统收到一个创建订单请求:商品红笔,数量3,当前库存2。JSON可以被解析,字段也齐全,但库存不足。若程序只检查括号有没有闭合,就会把结构正确当作业务可行。

把问题缩小,依次看四份输入:缺一个右花括号;quantity写成字符串“3”;quantity写成整数-3;quantity写成整数3但库存只有2。它们不是同一种错误,也不该由同一层含糊地返回“格式不对”。本课先用这些小输入识别验证边界,不讨论真实下单的完整交易设计。

第一份根本不能变成JSON对象,失败在解析。第二份可以解析,却不符合要求整数的字段约束,失败在结构校验。第三份的类型正确,若规则还要求quantity至少为1,就能在数值约束处拦住。第四份满足静态格式和范围,但需要查询当前库存才能判断可执行性。

一层检查只证明一件事

解析器回答“这是不是合法语法”。JSON Schema描述对象形状、必填项、类型、枚举和数值范围。业务规则再判断当前状态是否允许动作。权限规则还要确认这个用户或运行是否有资格执行。最后真正提交时,状态可能已经变化,因此执行端仍须维护库存等业务不变量。

官方原课件 · Lecture 2 · PDF 第 28 页形式约束不证明任务成功
原课将约束分为Syntax、Shape、Types、Values,并说明不保证事实权限和成功。

从左到右看,约束逐渐精细,但都没有自动获得当前库存。课件底部的边界非常关键:格式保证不能替代事实、权限、工具选择和任务成功。这个边界比记住某个校验库名字更值得保留。

设定最小规则:item为字符串,quantity为整数且至少1,额外字段不允许。请求 {item:红笔, quantity:3} 通过后,程序仍要检查库存2是否不少于需求3。比较得到2小于3,拒绝创建是正确业务结果,不是模型“不会调用工具”。把这次拒绝作为观察回填,模型才可能询问减少数量或更换商品。

还有一个容易漏掉的时间条件。检查时库存3,提交前别人买走1盒,执行时只剩2盒。如果“查库存”和“扣库存”不是受保护的同一个业务操作,仅靠前置查询仍可能超卖。执行端应以自己的可靠事务或条件写入保护库存;模型生成的文字不是锁,也不是事务。

官方原课件 · Lecture 2 · PDF 第 29 页用Schema说清输入形状
原课JSON Schema示例规定city字符串、units枚举和required字段。

图里的 units 只能是C或F,可以把K挡在接口外。但city即使是字符串,也可能不是目标城市。把同样方法用于库存时,整数和下限可以机器检查,用户到底要哪种笔仍需要任务与业务上下文。

让错误在最早负责的层停下

观察过程 · 改变条件

同一个数量字段,四种错误

先预测结果,再逐步展开;最后只改变一个条件,找出最早发生分歧的位置。

教学构造场景 · 按下方规则逐步回放;不调用真实模型,不代表实际成功率。

这一轮的输入

quantity="3",协议要求整数。

  1. 1. 解析

    JSON字符串合法,可以解析。

  2. 2. 类型检查

    quantity是string,不是integer。

  3. 3. 处理

    返回明确字段错误,不创建订单。

解析

JSON字符串合法,可以解析。

1 / 3
先预测,再核对结果与原因停在结构校验。

不能因为人能猜出意思,就由执行端悄悄改变输入含义。

改一项条件,结果为何不同

把字符串“3”改成整数3,只修好了类型错误,没有凭空增加库存。把库存从2补到5,只修好了数量前提,没有自动给用户下单权限。每次修改要对应一个确定的失败条件,否则容易把“某次通过了”误读成所有风险都消失。

约束解码可以在生成过程中限制可出现的输出形式,例如不让某些违反语法的续写被选中。它减少部分格式失败,却不能替代执行前校验。模型可能输出一个格式完美、含义错误的商品ID;也可能选择本不该使用的工具。生成层和执行层分别保护自己的边界,不能因为前面用了约束就省掉后面的检查。

对用户的错误消息也要有区分。格式错误适合指出字段;库存不足适合说明可满足数量;权限不足不应该被建议“多重试几次”。清楚的错误类型既帮助人理解,也给下一轮模型提供可执行的修正方向。一个通用“失败”会丢掉决定下一步所需的信息。

自己解释一次

quantity=-3是JSON语法错误吗?

不是。负数是合法JSON数字,也可能符合integer类型。需要minimum等范围规则或业务约束明确拒绝它,不能指望语法解析替你定义合法订单。

校验通过后库存变少,谁负责防止超卖?

真正修改库存的业务执行端负责维护不变量。前置查询只是一个观察快照,不能代替事务、条件更新或对应的一致性机制。

格式约束很好,为什么仍要测试错误商品?

因为Schema通常只知道商品ID是字符串,不知道是否符合用户意图。应该把同类型但语义错误的值放进测试,验证任务约束和业务检查。

可以把本课压成一句:每一层只证明自己的条件,不把前一层通过当作整个任务正确。下一课比较窄工具与代码工具,看看表达力变大后这些检查为什么更难做。