把三段文字拆成五个字段:word、phonetic、pos、def_en、example。 不给 schema,三张图给出三种键名,下游一行代码都写不出来。 给了 schema 也不是万事大吉:字段数能查出「漏」,查不出「糊」。
这一步是整条链的腰。上面是自由文字,下面是固定字段,全靠这里转。 书里用「信息提取」节点配一张 JSON Schema。 本沙箱没有这个节点,用规则从同一段文字里抠——抠不出来的地方,模型那次同样会漏。 这一节的重点不是怎么写正则,是为什么必须有 schema,以及 schema 管不到什么。
一、不给 schema:三张图三种写法
同一句「把图上的信息提成字段」,跑三张图,键名能给你三种:
| 图 | 回来的键 | 几个 |
|---|---|---|
| card_01 | 单词、读音、中文、例句 | 4 |
| card_02 | word、phonetic、pos、meaning、example | 5 |
| card_03 | 内容 | 1 |
三张图加起来十种键名。下游写 g['word'],只有第二张对得上。
注意第一张:它甚至没有词性。不是抽漏了,是模型觉得这张图上没有词性——图上确实写着 n.,它没认。
这就是 schema 存在的理由:不是让输出好看,是让下游能写代码。
二、schema 三个字段:名字、类型、缺了怎么办
schema 不是只写五个名字。每个名字后面还要两样东西:类型、缺失规则。
| 字段 | 类型 | 缺了怎么办 |
|---|---|---|
| word | string | 必填,缺失整条作废 |
| phonetic | string | 可空,填 null |
| pos | string | 可空,统一用 n. / v. / adj. |
| def_en | string | 必填 |
| example | string | 可空 |
「缺了怎么办」这一列最容易被跳过。跳过的后果是:缺的时候模型随手编一个,你分不清哪个是真的。 必填项缺失要整条作废,不要凑。凑出来的卡片比没有卡片更糟——用户会照着错的去背。
三、给了 schema,抽出 5/5、4/5、1/5
同一套规则跑三张图:第一张五个全在,第二张四个,第三张一个。
第二张缺的是词性。原因很朴素:图上写的是中文「名词」,而 schema 要的是 n. 这种缩写。
规则认缩写,不认中文。
第三张最阴:它抽到了 1 个——把「无」当成了释义。
空图不是抽不到,是抽到一个假的。 下游拿到一条有释义、没单词的记录,如果只检查「字段数大于 0」,这条就混过去了。 所以必填项的检查不能只数个数。word 为空就直接作废,别管别的字段有几个。
四、抽全了不等于抽对了
第一张五个全在,看着满分。可它的音标是 / bʌs /——斜杠里多了两个空格。
这张卡的文字里,音标前后确实有空格(排版留白),原样抄就抄进来了。拿这个串去查词典,查不到。
字段数没掉,类型也没错(还是 string),只有格式错了。
这就是 schema 管不到的那一层。类型管的是「是不是字符串」,管不了「字符串长得对不对」。
补法是加格式校验:音标必须匹配 ^/[^/]+/$,词性必须是那几个缩写之一。校验放在提取之后、下游之前。
字段数能查出「漏」,查不出「糊」。糊的那种只能靠格式校验。
五、温度、重试、兜底
这一步温度调到 0。要的是同一张图两次跑出一样的结果,不是多样性。 重试一次有意义:模型偶尔会多打一个括号、少一个引号,JSON 解析失败。重试一次多半就好了。 重试两次还失败,就走兜底:把原始描述交出去,让智能体说「这张图我没看懂,你自己看看」。
兜底不是认输,是让失败变成一句人话。这比抛一个 500 给用户强。
六、动手 Demo:信息提取:五个字段,一个都不能少
先看不给 schema 时三张图各给什么键名,再看给了 schema 之后抽到几个。 最后单独看第一张图:五个字段全在,但音标的格式是错的。
def extract(desc):
seg = dict(s.split(u':', 1) for s in desc.split(u'|'))
parts = seg[u'文字'].split(u';')
got = {}
for p in parts:
if p.startswith(u'/') and p.endswith(u'/'): got[u'phonetic'] = p
elif POS.match(p): got[u'pos'] = p
elif p.endswith(u'.') and u' ' in p: got[u'example'] = p
...
return got
实跑输出:
--------------------------------------------------------------------
信息提取:五个字段,一个都不能少
--------------------------------------------------------------------
① 不给 schema,三张图三种写法
--------------------------------------------------------------------
| 图 | 模型给回来的键 | 几个 |
|---|---|---|
| card_01.jpg | 单词、读音、中文、例句 | 4 |
| card_02.jpg | word、phonetic、pos、meaning、example | 5 |
| card_03.jpg | 内容 | 1 |
三张图加起来 10 种键名。下游写死 g[word],只有第二张对得上。
这就是 schema 存在的理由:不是让输出好看,是让下游能写代码。
② 给一张 schema:五个字段、类型、缺了怎么办
--------------------------------------------------------------------
| 字段 | 类型 | 缺了怎么办 |
|---|---|---|
| word | string | 必填,缺失就整条作废 |
| phonetic | string | 可空,填 null |
| pos | string | 可空,统一用 n. / v. / adj. 这种缩写 |
| def_en | string | 必填 |
| example | string | 可空 |
③ 同一套规则跑三张图
--------------------------------------------------------------------
| 图 | 抽到几个 | 抽到哪些 |
|---|---:|---|
| card_01.jpg | 5/5 | def_en、example、phonetic、pos、word |
| card_02.jpg | 4/5 | def_en、example、phonetic、word |
| card_03.jpg | 1/5 | def_en |
card_02 只抽到 4 个:图上的词性写成了中文「名词」,而 schema 要的是 n. 这种缩写。
第三张图更阴:它抽到了 1 个——把「无」当成了释义。空图不是抽不到,是抽到一个假的。
card_02 的音标出来是「/ bʌs /」,斜杠里多了两个空格。
拿这个串去查词典会查不到。它的字段数是 4/5,音标那一个还算「在」。
! 字段数能查出「漏」,查不出「糊」。糊的那种只能靠格式校验:音标必须匹配 ^/[^/]+/$。
①第一张表三行键名:4 个、5 个、1 个,加起来十种写法。
②第二张表是 schema:名字、类型、缺了怎么办。三列缺一列都不算完整的 schema。
③第三张表:5/5、4/5、1/5。第二张缺词性,因为图上写的是中文「名词」。
④第三张抽到的那 1 个是假的——把「无」当成了释义。空图不是抽不到,是抽到假值。
⑤最后两句讲格式:音标 / bʌs / 多两个空格,字段数不掉,照样是错的。
30 秒实验
- 给你现在的提取节点补一列「缺了怎么办」。必填项写「整条作废」,别写「尽力补全」。
- 写一条格式校验:音标必须匹配
^/[^/]+/$。拿第一张图跑一次,看它过不过。 - 把温度从默认值改成 0,同一张图连跑三次,看三次结果是不是一模一样。
常见误区
- 「给五个字段名就够了。」还要给类型和缺失规则。少一列,缺的时候模型就自己编。
- 「字段全在就是对的。」音标带空格、词性写中文,字段数照样满分,值全是错的。
- 「空图抽不到字段。」会抽到假字段,比如把「无」当释义。必填项为空才作废。
自测三问(点开对答案)
1. 为什么必须有 schema? —— 不给 schema,三张图给出三种键名,下游一行代码都写不出来。schema 是给程序用的契约。 2. schema 除了字段名还要写什么? —— 类型和缺失规则。缺了怎么办最容易漏,漏了模型就自己编一个填上。 3. 「抽全了」和「抽对了」差在哪? —— 字段数够不代表值对。音标带空格、词性写中文,数着满分,用起来全错。得加格式校验。字段有了,但释义还是英文。下一节把它翻成中文——难点在一个词有好几个意思。
- ☐ (本篇完,下一篇 9.5 配置【翻译模型】节点)
相关笔记
- 创建扣子数据库:字段怎么定
- 开发自定义插件案例:查询股票价格:参数类型与校验
- 配置图片生成模块:上一章同样的位置
- 🐦 扣子开发 AI Agent · 索引