结构化输出与数据契约

本讲目标

把"一段话"变成"一张表",并且知道哪个字段它会读错。

你会做出

一张票据信息表 + 一份输入输出契约 + 5 条测试。

120 分钟怎么排
  1. 课前课前准备
  2. 0–30补核心
  3. 30–75讲错题
  4. 75–120拆案例
  5. 课后课后作业

课前:先自学,再做 15 道题

上课前,先花点时间自己看一页材料,就三样:

  • 弄懂 3 个词:结构化输出(固定字段固定类型,程序才能校验)、字段四要素(名字/类型/必填/取值范围)+ 判据(怎么算对)、Schema(数据契约)。
  • 记住 1 个比方:把模型的输出"锁进一个程序能检查的格子里"。
  • 记住 1 条红线:结构化输出只解决"格式稳定",不解决"内容正确"——格式对了值仍可能错,所以每条测试都要写"预期 + 判据"。

看完做 15 道自测题。哪几道大家错得多,直播时老师就重点讲哪几道。

直播 0–30|把核心快速过一遍

  1. 输出格式决定它能不能被程序用。 自然语言段落 → 给人看;表格 → 勉强能用;固定字段 → 能逐个字段校验。
  2. 一个字段定义四件事 + 一个判据。 名字 / 类型 / 必填 / 取值范围 / 判据(这条怎么算对)。没有判据就测不了,测不了就交付不了。
  3. 缺的信息不猜,留空或追问。 模型最危险的动作不是答错,是缺字段的时候"合理补全";规则写死:没有就 null + missing_fields。

直播 30–75|挑大家做错的题讲

  • 字段要太多,一次抽 20 个字段准确率必崩,先拿 5 个跑通再加。
  • 没定义空值,模型不知道"没有"该写什么,就编一个。
  • 拿自然语言当结果,"金额大约 1280"程序没法用,这不算完成。

直播 75–120|拆一个真实案例:会议录音抽行动项,4 条里 2 条没负责人

一家 60 人的软件公司,每周 6 个会,行动项经常漏。拿一段会议字幕来练("双十一方案下周定""李婷出三版海报""商品图找王强""预算按 8 万""渠道让赵敏对接——张总改周杰顶"),期望的输出是 {decisions:[...], actions:[...], missing_fields:[决策1负责人, 决策2负责人, 行动2截止, 行动3截止]}。

这里埋了 3 个坑:没人被指派的时候,模型爱填"张总"(谁说话最多就填谁),正确应该是 null;"赵敏"被改成"周杰",模型却抓了前半句,同一件事要以最后一次为准;"下周三"别擅自换算成具体日期。

课上让全班跑一遍,数数有几组填了"张总"、几组填了"赵敏",再加三条规则重跑。

这一讲想让你记住的就一句:owner 只能是被明确指派的那个人;说话人不等于负责人。

当堂练一个(8 分钟):把下面这句"报销口述"丢给 AI,让它抽成四字段的表(事项 / 金额 / 日期 / 缺什么),每个字段先写"类型 + 判据":

上周五我和王强请客户吃饭,花了六百多,发票我回头拍照补;打车回来是李婷垫的 45 块,她明天拿票来报。

然后对照原文逐格查三处:它有没有把"六百多"擅自写成"600 元"?把"明天"写成具体日期?"回头补"的发票它填了还是留空了?

判断标准:能说清每个字段"怎么算对"(金额是数字、日期不能是未来、缺失写 null 不编),并且至少抓出 1 处它"合理补全"的地方。一处都抓不到,说明判据还没写清——值对了不代表没编。

课后:答疑 + 陪跑,交一份作业

给自己的委托定"数据长什么样":写输入 + 5–8 个字段(类型/必填/取值/判据)+ 建表 + 5 条测试 + 至少修掉 1 个"编造字段"。再迁移到简历/合同/质检任选一个,补 5 条新输入。

这节课你该会的:

  1. 能说出一个字段的"四要素 + 判据"(名字、类型、必填、取值范围,外加"怎么算对");
  2. 能写出一条测试(预期 + 实际 + 通过/失败),并至少抓出 1 处"编造字段";
  3. 知道"格式对"不等于"值对"——缺失就写 null,不猜、不补。

三个翻车:

  • 字段要太多——一次抽 20 个字段准确率必崩,先拿 5 个跑通再加;
  • 没定义空值——它不知道"没有"该写什么,就顺手编一个;
  • 拿自然语言当结果——"金额大约 1280 元"程序没法用,不算完成。

延伸自读:《原理讲义》§7

展开查看

一句话定义:数据契约(Schema)是模型输出和程序消费之间的一份"书面协议"——双方事先约好字段的名字、类型、必填、取值范围和判据,模型照着填格,程序照着校验。一句话:把"一段话"锁进一个程序能一格一格检查的格子里。

核心原理

1. Schema 把"概率输出"收敛成"可校验形状"。 模型默认吐出来的是自然语言段落:人读没问题,程序却无从下手——它分不清"哪句是负责人、哪句是金额"。Schema 的意义,就是把输出从"给人看的文字"变成"给程序看的格子":字段固定、类型固定,程序才能一格一格做机械校验。抽象例子:一场会议转写,原始材料里"预算按 8 万""李婷出三版海报"混在一起,只有先约好 {decisions, actions, missing_fields} 的结构、并规定 amount 是数值而不是字符串,程序才能自动查出"负责人为空""金额不是数字"这类问题。格式先于内容:形状不定,内容再对也进不了流水线。

2. 字段四要素 + 判据:判据是让"能说会道"变成"能验收"的那座桥。 一个字段的定义包含四件事——名字、类型、必填、取值范围——再加一个判据:这一条"怎么算对"。四要素回答"它长什么样",判据回答"什么算通过"。判据为什么要单独拿出来?因为模型输出"看着像"不等于"能验收":没有判据就测不了,测不了就没法交差。典型的失败是拿自然语言当结果——"金额大约 1280",程序既不能比大小、也不能加总,等于没抽出来。判据把"对不对"从主观感觉变成可执行的检查:amount 必须为正数、精确到分;owner 只能是被明确指派的人名,而不是"说话最多的人"。

3. 缺失处理:不猜,是比"答对"更重要的纪律。 模型最危险的动作不是答错,而是字段缺失时"合理补全"——没人被指派负责人,它就填一个在场的人;"下周三"它就擅自换成某个具体日期。正确的做法是把缺失写成三条规则:没有就是 null(字段确实不存在)、判定不了就是 unknown(存在但材料不足以判断)、还差就进 missing_fields(列明缺哪一条,驱动追问)。三者必须分开:null 表示"没有",unknown 表示"不知道",missing_fields 表示"还差什么"——混成一团,下游要么把"没有"当成错,要么把"没问"当成"没有"。

常见误区 / 边界
  • 别把格式稳定当内容正确:契约只保证"格子对",不保证"格子里填的值对";格式对了值仍可能错,所以每条都要写"预期 + 判据"。
  • 别拿自然语言当结果:"大约""左右""差不多"都不算完成,程序用不了。
  • 别一次抽太多字段:一次要 20 个字段准确率必崩,先 5 个跑通再加。
  • 别擅自换算与脑补:"下周三"就留"下周三",不换日期;说话人 ≠ 负责人,没人指派就 null。
  • 别把三种缺失混成一团:null / unknown / missing_fields 是三件事,各有各的处理分支,不可合并。
一句可带走的话

没有判据就测不了,测不了就交付不了;缺了就留空,不猜。

案例包 · 15 题自测

展开查看

看完做 15 道自测题。每题都有解析,容易错的地方标了出来。哪几道大家错得多,直播时老师就重点讲哪几道。

  1. (单选)哪种输出能被程序直接处理?
    • A. 自然语言段落
    • B. 固定字段的结构化输出
    • C. 口语表格
    • D. 摘要

答案:B | 解析:固定字段才能逐字段校验。

  1. (单选)一个字段要定义几件事?
    • A. 两件:名字、类型
    • B. 四件:名字、类型、必填、取值范围(外加判据)
    • C. 一件:名字
    • D. 三件:类型、长度、格式

答案:B。

  1. (单选)"判据"(rubric)是什么?
    • A. 代码注释
    • B. 这条字段"怎么算对"的明确标准
    • C. 测试数量
    • D. 提示词长度

答案:B | 解析:没有判据就测不了,测不了就交付不了。

  1. (单选)字段缺失时,模型应该?
    • A. 合理补全
    • B. 写 null 并加进 missing_fields
    • C. 报错
    • D. 跳过

答案:B | 解析:缺失不猜,留空或追问。 容易错:很多人会顺手让模型"合理补全"。

  1. (判断)会议里说话最多的人就是负责人。

答案:错 | 解析:说话人不等于负责人;只有被明确指派的人才能填 owner。 容易错。

  1. (单选)"下周三"这个截止日期,正确写法是?
    • A. 擅自换算成具体日期 10/15
    • B. 保留原文"下周三",或换算后标注"原文如此"
    • C. 写成"近期"
    • D. 不填

答案:B | 解析:不擅自换算,要保留原文或标注推算依据。

  1. (单选)同一事项被先后指派给"赵敏"又改"周杰",应该?
    • A. 都填上
    • B. 以后一次为准(周杰)
    • C. 以第一次为准(赵敏)
    • D. 空着

答案:B | 解析:同一事项以后一次为准。 容易错:模型常抓前半句,填成"赵敏"。

  1. (判断)格式对、值错,也算对。

答案:错 | 解析:格式对、值错,也算错;要逐字段核对。

  1. (单选)"金额大约是 1280 元"这种输出,问题在哪?
    • A. 太长
    • B. 是自然语言,程序没法用
    • C. 太短
    • D. 没引用

答案:B。

  1. (单选)一次抽取 20 个字段会怎样?
    • A. 更准
    • B. 准确率崩,先 5 个跑通再加
    • C. 没影响
    • D. 更快

答案:B | 解析:字段太多,准确率必然崩。

  1. (单选)没定义"空值怎么写"会怎样?
    • A. 没问题
    • B. 模型不知道"没有"该写什么,就编一个
    • C. 输出更短
    • D. 更快

答案:B。

  1. (判断)"缺失信息就合理补全"是模型最危险的动作之一。

答案:对 | 解析:规则要写死:没有就 null。

  1. (单选)判据的作用是?
    • A. 让输出更漂亮
    • B. 让每条测试能判断对错
    • C. 减少 token
    • D. 没用

答案:B。

  1. (单选)测试记录里"看情况"这种判定,应该?
    • A. 允许
    • B. 不允许,只能写通过/失败/部分
    • C. 可以
    • D. 看情况

答案:B。

  1. (判断)结构化输出能保证内容正确。

答案:错 | 解析:只解决格式稳定,不解决内容正确;还要抽检。

案例包 · 案例拆解素材

对应第 7 讲「结构化输出与数据契约」

课堂用时:12 分钟案例 + 24 分钟项目迁移

材料:data/meeting_transcript.md

期望输出:data/expected_output.json

1. 客户和场景

一家 60 人的软件公司,每周 6 个会。会议纪要靠人整理,行动项经常漏,负责人经常写错。

这次给到的是一段 20 分钟产品例会的字幕节选(模拟),讨论双十一活动。会议结束后,记录人要把"决定了什么、谁做什么、什么时候交"录进任务表。

2. 为什么拿这个案例来讲
  • 它看起来很简单,学生一放松就掉坑;
  • 它同时考三件事:抽取、判断、留空;
  • 它的错误非常直观:把"张总"填成负责人,全班一眼能看出来;
  • 它能直接搬到任何行业:会议、访谈、客服通话、需求评审。
3. 原始材料

见 data/meeting_transcript.md,核心 7 句:

00:03:12 张总:这次双十一的活动方案,我们下周一定要定下来。
00:05:40 李婷:海报我这边可以出三版,但是要给我商品图。
00:06:05 张总:商品图找王强要,他那边有。
00:12:30 张总:预算这块,先按 8 万报,超了再说。
00:15:10 王强:那投放的渠道,是不是让赵敏来对接?
00:15:22 张总:赵敏最近在休假,先让周杰顶一下。
00:20:00 李婷:下周三之前我给初稿。
4. 期望输出

见 data/expected_output.json。关键点:

  • 2 条 decision:活动方案、预算;负责人都是 null。
  • 3 条 action:海报(李婷)、商品图(王强)、投放渠道(周杰)。
  • missing_fields 至少包含 4 项:两条决策的负责人、商品图和投放渠道的截止时间。
  • due 保留原文"下周""下周三",不擅自换算成具体日期。
5. 故意埋的三个坑
坑 1:把说话人当负责人

00:03:12 张总说"我们下周一定要定下来",但没有指派任何人。模型特别喜欢填"张总",因为他是说话最多的人。

对的做法:owner: null,并写进 missing_fields。

坑 2:抓前半句,漏掉改派

00:15:10 王强提议"让赵敏对接",00:15:22 张总改口"赵敏休假,让周杰顶"。

模型经常只抓前半句,填成"赵敏"。对的做法:owner: "周杰"。

坑 3:把相对日期擅自换算

00:20:00 李婷说"下周三之前"。模型可能直接写成 2026-10-21。

对的做法:保留 "下周三";如果一定要换算,必须标注"原文为下周三,按会议日期 2026-10-14 推算"。

6. 两版提示词
  • prompts/v1_naive.txt:一句"帮我整理成任务表",必然翻车。
  • prompts/v2_rules.txt:加了三条硬规则(说话人≠负责人、改派以最后一次为准、缺失写 null)。

课堂做法:先跑 v1,统计错几条;再跑 v2,做并排对比。不要一开始就给 v2。

7. 验收样例(3 条)
#输入期望判定
1完整字幕3 条 action,负责人分别为李婷、王强、周杰;2 条 decision 负责人为 null通过
2"这个事情要尽快处理,别拖"只有 1 条 action,owner=null,due=null,missing 包含两项通过
3"让赵敏对接……赵敏休假,让周杰顶"owner=周杰,不是赵敏通过

完整 5 条见 data/test_cases.csv。

8. 12 分钟课堂流程
分钟做什么
0–2抛字幕,问:"这段里有几件事?几个人?" 让学生先人工数一遍
2–5跑 v1,把结果贴出来,全班数"张总"出现了几次
5–8找一组错的,追问"模型凭什么觉得负责人是张总?"
8–11加三条规则,重跑 v2,对比
11–12收一句结论:说话人不等于负责人;缺失就留空。
9. 一句话总结

结构化输出不是"让 AI 填表",是"让 AI 在没把握时敢留空"。这一条学会了,后面所有抽取任务都稳一半。

案例包 · 课后操作单

目标:把一段会议字幕变成一张任务表,不许猜负责人,不许猜日期。

时间:课后 60 分钟。

你要交的东西
  1. 一份 actions_v2.json(按 data/schema.json 的字段);
  2. 一张测试表(5 条,含预期、实际、通过/失败);
  3. 一句"我改了什么,为什么"。
怎么做
第 1 步:建技能(3 分钟)

在 WorkBuddy 里新建技能 会议行动项抽取 v0.1,贴上 prompts/v1_naive.txt,先不加任何规则,看原始表现。

第 2 步:跑一遍,数错误(8 分钟)

把 data/meeting_transcript.md 全文贴进去,对照 data/expected_output.json 逐条数:负责人错了几条?有没有多出不存在的人?due 有没有被换算成具体日期?missing_fields 有几项?

第 3 步:改规则(5 分钟)

加 prompts/v2_rules.txt 三条:①owner 只能是被明确指派的人;②同一事项以后一次为准;③没有负责人写 null + missing_fields。

第 4 步:重跑对比(5 分钟)

同一段字幕重跑,v1/v2 并排对比(决策1负责人/决策2负责人/行动3负责人/行动2截止/行动3截止)。

第 5 步:跑 5 条测试(10 分钟)

用 data/test_cases.csv 逐条跑,判定只写通过/失败/部分。

课后作业
  1. 换成你自己的一段会议/访谈/客服记录(脱敏),重跑同一套规则。
  2. 补 2 条测试:一条"没有负责人",一条"两个负责人"。
  3. 写 100 字:这次你最想删掉的一条规则是什么?为什么?
达标标准(这节课你该会的)
  1. 能说出一个字段的"四要素 + 判据"(名字、类型、必填、取值范围,外加"怎么算对");
  2. 能写出一条测试(预期 + 实际 + 通过/失败),并至少抓出 1 处"编造字段";
  3. 知道"格式对"不等于"值对"——缺失就写 null,不猜、不补。
容易踩的坑
  • 只测完整字幕,没测"没负责人" → 测试集不完整。
  • 把 due 写成具体日期还没标注推算依据 → 这是编造。
  • 看到 JSON 格式对就判通过 → 值错也是错。

案例包 · 教师脚本(教师用)

展开查看
课前准备
  • 自己先跑 v1,确认它会填"张总"(说话最多的人)当负责人。
  • 开课前看一眼 quiz 错误率,圈出错误率最高的 3–5 题。
0–30|把核心快速过一遍(3 个点)
  1. 输出格式决定它能不能被程序用(10 分钟)— 自然语言段落是给人看的,固定字段才能逐字段校验。
  2. 一个字段定义四件事 + 一个判据(10 分钟)— 名字/类型/必填/取值范围,外加"怎么算对"。
  3. 缺失信息不猜,留空或追问(10 分钟)— 最危险的动作是缺字段时"合理补全"。
30–75|挑大家做错的题讲

按 quiz 里错得多的题(Q4 / Q5 / Q7),每道讲清"错在哪一层 + 对的做法":

  • Q4:缺失时"合理补全" → 写 null + missing_fields。
  • Q5:说话人当负责人 → 只有被明确指派的人才能填 owner。
  • Q7:抓前半句"赵敏" → 同一事项以后一次为准。
75–120|拆案例:会议字幕抽行动项,4 条里 2 条没负责人

发材料(3 分钟):发 data/meeting_transcript.md,先让学生自己读一遍,标出"哪句是决策、哪句是行动项"。

全班跑一遍(12 分钟):用 prompts/v1_naive.txt 跑,把结果贴白板。全班一起数:几组填了"张总"?几组填了"赵敏"?逐字段对,格式对、值错也算错。

找错的原因(8 分钟):问"模型凭什么觉得负责人是张总?"——因为它把"说话人"当成了"责任人"。

加三条硬规则(12 分钟):加 prompts/v2_rules.txt:①owner 只能是被明确指派的人;②同一事项以后一次为准;③没有负责人写 null + missing_fields。重跑对比。

跑 5 条测试(7 分钟):用 data/test_cases.csv 逐条跑,判定只写通过/失败/部分,不许写"看情况"。

收口(3 分钟):owner 只能是被明确指派的人;说话人不等于负责人。

学生会错在哪
  1. 把"说话人"当"负责人"(填"张总")。
  2. 抓前半句("赵敏"),忽略后一次的更正("周杰")。
  3. 把"下周三"擅自换算成具体日期。
  4. 只测完整字幕,没测"没负责人"的情况。
  5. 看到 JSON 格式对就判通过 → 值错也是错。
评分点(每条 1 分,共 5 分)
  • [ ] 决策 1、2 负责人 = null(不填"张总");
  • [ ] 行动 3 负责人 = 周杰(不是赵敏);
  • [ ] "下周三"保留原文或标注推算;
  • [ ] missing_fields 列全;
  • [ ] 5 条测试判定清晰,无"看情况"。
如果学生问"能不能让模型自己猜一个负责人"

回答:不能。 猜一个负责人 = 给一个错误的人派活。没有明确负责人就写 null,交给人工确认——这是"缺失信息不猜"这条原则在业务上的落地。

可搜索 16 讲与全部课程章节。