🐦 第9章 实战案例:看图学英语智能助手
📄 一句话概括

需求就一句话:拍张照,把上面的英文讲明白。 这句话里藏着两个交付物——一段解释给人看,一张卡片留下来。 直接问模型,回来的是一段散文:能读,捞不出字段。 拆成四步——图片理解、信息提取、翻译、画板,五个字段才全部落地。

📝 本章和前面几章的关系

第 8 章那条链解决「写出来」,这条链解决「看懂」。 两条链长度差不多,但输出形状完全不同:一个是给人读的文案,一个是给程序用的字段。 书里这个案例叫「看图学英语智能助手」,一共九节。 形状和第 8 章一样,内容全换——正好拿来对照,看哪些做法是可以照搬的。 这一节只设计,不动手。设计错了,后面八节全是返工。

一、一句话需求,回来一段散文

用户的话是「拍张照,把上面的英文讲明白」。听着简单,但它没说清楚「讲明白」是讲给谁听。 讲给人听,一段话就够;讲给程序听,得是字段。这两个交付物的形状不一样。 演示里第一步就是把同一张卡片直接丢给模型问。 回来的是一段散文,五十一个字,读着挺顺:「上面画着一个红苹果,写了英文单词,底下还有一句例句。」

然后拿这段话去捞五个字段:单词、音标、词性、释义、例句。一个都没捞到。 不是模型说得不好,是它压根没提音标——它说「有读音」,没说读音是什么。散文里连一个英文单词都没出现。 这就是「一句话直调」的真实结局:效果看着不差,接不下去。

二、四步怎么分

分法只有一条原则:每个节点的输出,是下一个节点的输入。

节点 吃什么 吐什么
图片理解 图片地址 一段三段式文字
信息提取 那段文字 五个字段
翻译模型 英文释义 中文释义
画板 五个字段 一张 1200×1600 的图
结束 五个字段 + 图 交给智能体的结果

加上开始节点,整条链六步。演示里真跑了一遍,六步全部按顺序走完。 跑完再回头数一遍:散文那一版捞到 0 个字段,这条链五个全在。 同一张图、同一件事,差别只在拆没拆。

三、为什么是四步,不是两步也不是八步

两步也能做:图片理解 → 信息提取 → 画板,三步就完事。中间那个翻译节点为什么单列? 因为「提取错了」和「翻译错了」坏的样子不一样。提取错了是字段错位——音标那一格填了词性; 翻译错了是意思跑偏——词对了,释义不对。 合成一个节点,这两种错混在同一段输出里,你得靠猜。拆开,坏了就知道找谁。

反过来,拆太细也坏。每多一个节点,多一次模型调用、多一段延迟、多一处要维护的提示词。 四步这个数是我试出来的,不是书上的定数。 判断标准:这一步的失败,能不能和别的步骤分得开。 分得开就拆,分不开就并。

四、输入从哪来

开始节点只有一个字段:图片地址。不是图片本身,是地址。 三种来源都行:用户在对话框里上传(平台自动给一个 URL)、小程序拍照后上传到对象存储、 API 调用方直接传 URL。 别在节点之间传图片本身。 传 base64 也能跑,但每过一道节点就要复制一遍字符串。 一张 2 MB 的图转成 base64 是 2.7 MB 的文本,过五个节点就是十三四兆。

这一点和第 8 章不同:那一章的输入是一个主题词,几十字节;这一章的输入是一个链接,也几十字节。 两边都很轻,重的东西在存储里。

五、输出交给谁

结束节点交出去五个字段。智能体拿到之后渲染成一张卡片,显示在对话框里,用户还能点开大图存下来。 如果只是自己看,交一段话也行。 要给下游程序用,就必须是字段——这是第 8.7 节讲过的输出契约,换了个内容,道理一样。 先想清楚谁接,再定交什么。 顺序反了,就是先做一张卡再找人用。

六、动手 Demo:一句话直调,和四步流水线

同一张单词卡走两条路:一条直接问模型,一条拆成四步。 两条路都不报错,差别在最后能不能按字段取。

FIVE = (u'word', u'phonetic', u'pos', u'meaning', u'example')

def dig(text):        # 散文 -> 字段:靠「音标是」「意思是」这类标记词
def flow():           # 六个节点按拓扑序跑,键是「节点.端口」
    ...
    return g, rec     # g 里 ext.word / ext.phonetic ... 全在

实跑输出:

--------------------------------------------------------------------
一句话直调,和四步流水线
--------------------------------------------------------------------


  ① 把整件事丢给模型,回来一段散文
  --------------------------------------------------------------------
  一段 51 字的散文。人读着挑不出毛病,问题在下一步。

| 字段 | 英文名 | 散文里能捞到 |
|---|---|---|
| 单词 | word | — |
| 音标 | phonetic | — |
| 词性 | pos | — |
| 释义 | meaning | — |
| 例句 | example | — |

  五个字段一个都没捞到。散文里连英文单词都没出现——模型说「写了英文单词」,可没说是哪个。

  ② 拆成四个节点,每个只管一件事
  --------------------------------------------------------------------

| 步 | 节点 | 类型 | 输出端口 | 毫秒 |
|---:|---|---|---|---:|
|  1 | 开始 | 开始 | url | 0.0 |
|  2 | 图片理解 | 大模型 | desc | 0.0 |
|  3 | 信息提取 | 大模型 | def_en、example、phonetic、pos、word | 0.0 |
|  4 | 翻译模型 | 大模型 | cn | 0.0 |
|  5 | 画板 | 画板 | png | 0.0 |
|  6 | 结束 | 结束 | card | 0.0 |


| 字段 | 散文里 | 流水线里 |
|---|---|---|
| 单词 | — | apple |
| 音标 | — | /ˈæpl/ |
| 词性 | — | n. |
| 释义 | — | 一种红皮的圆形水果 |
| 例句 | — | I ate an apple. |

  同一张图、同一件事:散文捞到 0 个,流水线五个全在。

  ③ 四步各管什么,坏在哪一步看得出来
  --------------------------------------------------------------------

| 节点 | 只管一件事 | 这步坏了会怎样 |
|---|---|---|
| 图片理解 | 把图变成一段可读的文字 | 后面全没输入,整链空转 |
| 信息提取 | 把文字拆成五个字段 | 下游按字段名取值,全取不到 |
| 翻译模型 | 英文释义转成中文 | 卡片上印英文,读者看不懂 |
| 画板 | 五个字段排成一张图 | 交出去是文字,不像卡片 |
| 结束 | 声明交出去哪几个字段 | 下游取不到,而且不报错 |

  ! 一句话直调和四步流水线的差别不在效果,在定位:坏了以后回查几步。

①第一张表五行全是「—」:散文里一个字段都捞不到,连英文单词都没出现。 ②第二段六个节点按顺序跑完,信息提取那一步一次吐出五个字段。 ③第三张表逐字段对照:散文 0 个,流水线 5 个。 ④最后一节列四步各管什么、坏了会怎样——这张表就是排错时的路线图。 ⑤四步里只有图片理解和信息提取容易混。前者把图变文字,后者把文字变字段。

30 秒实验

  1. 把你手上任意一个「一句话需求」写在纸上,拆成节点,每个只写「吃什么、吐什么」。
  2. 数一下有几个节点的输出下游根本不用。不用的就砍掉,别留着好看。
  3. 找一个你以前用一句话直调做的功能,看它的输出能不能改成字段。改不动就是缺一步提取。

常见误区

  1. 「拆得越细越好。」每多一个节点多一次调用、多一份延迟。四步够用就别拆六步。
  2. 「先做出来再想输出形状。」输出形状决定中间怎么拆。定晚了整条链返工。
  3. 「模型说得挺全的,够用了。」散文里没有字段名,程序取不到就是取不到。
自测三问(点开对答案) 1. 为什么不能一句话直调? —— 回来的是一段散文。程序按字段取值,取不到;人也只能读到「有读音」,读不到读音。 2. 四步各干什么? —— 图片理解把图变文字,信息提取把文字变字段,翻译把英文变中文,画板把字段变图。 3. 什么情况下可以少一步? —— 不需要中文释义就去掉翻译;不需要图就去掉画板。判据是「这一步的失败能不能单独看出来」。

设计定完,下一节把骨架搭起来。先别配节点——空壳能跑通再说。

相关笔记