5. 把模糊要求裁决成五个例子
「把报价整理正确」读起来像一句完整的要求,真正拆开检查才发现里面藏着好几处没有裁决的地方:列名不一样算不算同一列,价格缺失时该保留还是该删,单位不同的两个价格能不能直接比,一段认不出来的内容该放进哪一栏。
这些空白 AI 能列出来,却没法替业务做决定。这一章把活儿分清楚:AI 负责把问题问全,人负责把答案定下来。
做完这一章,会拿到五个具体例子。下一章直接拿它们生成第一批测试。
先看一句话里藏了多少空白
Section titled “先看一句话里藏了多少空白”示范项目当前的要求是:
把几家供应商的报价表整理成统一格式,再找出每种物料的最低报价。
先不谈实现,只看「统一格式」这四个字,至少能拆出下面几种情况:
- 一张表写「品名」,另一张写「产品名称」。
- 同一种螺母,一家按「个」报价,另一家按「盒」报价。
- 价格单元格是空的。
- 价格写成「待询」。
- 同一物料同时有含税价和未税价。
这些情况没提前裁决,AI 照样会生成程序,只是程序采用的处理方式来自模型的补猜,不是业务的决定。
第一轮:从最普通的输入开始
Section titled “第一轮:从最普通的输入开始”先给一份没有歧义的输入:
| 品名 | 单位 | 含税价 |
|---|---|---|
| M6 螺母 | 个 | 0.18 |
回答三个问题:
- 整理完成后,这一行该保留哪些信息?
- 输出的列名该叫什么?
- 看到什么结果,才能说这一行处理对了?
示范项目给出的裁决是:
前提:表格里有「品名、单位、含税价」三列,内容都完整。动作:导入报价表。结果:输出一行物料,名称为「M6 螺母」,单位为「个」,价格为 0.18;这一行没有错误标记。这里没写函数名、页面组件或文件结构。验收描述的是外部能看到的行为,实现方式留给后面处理。
第二轮:换一个列名
Section titled “第二轮:换一个列名”第二家供应商用的是「产品名称」:
| 产品名称 | 单位 | 含税价 |
|---|---|---|
| M6 螺母 | 个 | 0.17 |
要裁决的问题是:「产品名称」能不能当「品名」用。
示范项目的选择是「能」,于是有了第二个例子:
前提:表格使用「产品名称」列,没有「品名」列。动作:导入报价表。结果:「产品名称」被识别为物料名称,输出中保留「M6 螺母」。自己的场景如果不允许这种自动映射,答案也可以是「停止导入并提示选择对应列」。验收条件没有标准答案,它记的是当前项目的裁决结果。
让 AI 补出还没问的问题
Section titled “让 AI 补出还没问的问题”把已有要求和两个例子交给 AI,让它只负责提问:
这是一个供应商报价整理工具。已有要求:把不同表格整理成统一格式,再按物料比较价格。已有例子:1. 完整的「品名、单位、含税价」能够正常导入。2. 「产品名称」可以映射为「品名」。
请从正常情况、边界情况、错误输入和缺失输入四个方向补问题。一次只问一个问题,等我回答后再问下一个。不要替我决定结果,不要写代码。一次只问一个问题有两个好处:当前要裁决的事不会被后面十几个问题埋掉;前一个答案也可能改变下一个问题该怎么问。
AI 可能先问:
如果价格为空,这一行应该被删除、按 0 处理,还是保留并标记?
这三个选项会算出完全不同的最低价。示范项目选「保留并标记,不参与最低价比较」,第三个例子随之定下来:
前提:某一行有品名和单位,但价格为空。动作:导入报价表。结果:这一行保留在输出中,显示「缺少价格」;最低价比较忽略这一行。第四轮:处理不能直接比较的单位
Section titled “第四轮:处理不能直接比较的单位”接下来出现两行同名物料:
| 品名 | 单位 | 含税价 |
|---|---|---|
| M6 螺母 | 个 | 0.18 |
| M6 螺母 | 盒 | 72.00 |
缺一个「每盒多少个」,两个价格就没法直接比。示范项目不猜换算关系:
前提:同一物料出现不同单位,并且没有换算关系。动作:生成最低价比较。结果:两行都保留,显示「单位不一致」;工具不产生最低供应商结论。如果业务里包装规格是固定的,允许自动换算,就把换算规则写进前提,比如「一盒固定为 500 个」。规则没写出来之前,AI 不能从常识里替业务补上。
第五轮:处理看起来像价格的文本
Section titled “第五轮:处理看起来像价格的文本”最后一份报价把价格写成「待询」:
| 品名 | 单位 | 含税价 |
|---|---|---|
| M6 螺母 | 个 | 待询 |
它不是空值,也不是数字。示范项目给出的结果是:
前提:价格单元格包含不能解析为金额的文本。动作:导入报价表。结果:原始文本「待询」仍然可见,这一行显示「价格格式无法识别」,并且不参与最低价比较。原始文本保留下来,使用者才能回到供应商实际填写的内容,工具也没有把「待询」偷偷改成 0、空白或者某个估算值。
把五个例子放在一起
Section titled “把五个例子放在一起”现在有了第一组可以逐项检查的结果:
- 完整数据能够导入,输出值与原表一致。
- 「产品名称」能够映射为「品名」。
- 空价格保留并标记,不参与比较。
- 单位不同且无法换算时,不给出最低价结论。
- 价格文本无法解析时,保留原文并标记。
这五条还没覆盖全部报价格式,它们的作用是把「整理正确」切成第一批能判断对错的行为。后面遇到新的真实情况,再补新的例子。
现在可以给它一个名字
Section titled “现在可以给它一个名字”刚才做的事,是在实现出现之前,先写清某种输入经过一次操作之后应该看到什么结果。这些例子有个名字,叫验收条件。
一种常见写法把每个例子拆成三段:
- Given:事情发生前的条件。
- When:执行的动作。
- Then:能观察到的结果。
前面用的「前提、动作、结果」和它们一一对应,Given-When-Then 只是压缩后的格式,判断内容还是来自刚才那几轮裁决。
比如空价格那一条,可以写成:
Given 一行报价有品名和单位,但价格为空When 导入报价表Then 保留这一行并显示「缺少价格」And 最低价比较忽略这一行下次跟 AI 讨论功能时,「先写验收条件」这句话就能把这套过程调出来。一句名词不够用时,回到「前提、动作、结果」把例子重新展开就行。
把自己的意图裁决成五个例子
Section titled “把自己的意图裁决成五个例子”取出第 0 章写的问题陈述,先给一个最普通的输入,再让 AI 从四个方向逐项追问:
- 正常输入还有哪些常见变体?
- 数量、长度、日期或金额落在边界上时怎么处理?
- 输入格式错误时,该停止、跳过还是保留并标记?
- 关键内容缺失时,哪些结果还能产生?
每次回答完,把裁决写成一条「前提、动作、结果」。五条里至少包含:
- 两条正常情况。
- 一条边界情况。
- 一条错误输入。
- 一条缺失输入。
最后再加一条「当前明确不支持的情况」。不支持也是一种验收边界,它能挡住 AI 为了显得完整,补出一段没经过裁决的行为。
这一章可以对 AI 说的一句话
Section titled “这一章可以对 AI 说的一句话”逐条问我这些情况下应该输出什么,再补出我没想到的边界。一次只问一个问题,把我的回答整理成「前提、动作、结果」。决定由我来作,不要替我补默认规则,也不要写代码。