这个案例只有一条主线:抓热点 → 写文案 → 转画图提示词 → 出图 → 拼装输出。 看着像「文案和配图两条线并行」,其实不是——画图的提示词是从文案里抽的。 真正能并行的只有两件互不依赖的事,而并行只省一层,不省多少。
前七章把零件都讲完了:插件、卡片、工作流、知识库、提示词、数据库。 这一章是第一次把它们装成一台机器。 这个案例在书里是「图文混合的火爆推文生成器」。 它不复杂,但五脏俱全——后面八个案例(第 9 到 16 章)都是在它的形状上改。 这一节只有设计,不动手。设计错了,后面八节全是返工。
一、先把依赖列成一张表
设计工作流的第一步不是画图,是列一张表:每个节点吃什么、谁给它。
| 节点 | 吃什么 | 谁给它 |
|---|---|---|
| 抓热点 | 一个主题词 | 开始节点 |
| 写文案 | 几条热点 | 抓热点 |
| 出图提示词 | 文案正文 | 写文案 |
| 生成配图 | 画图提示词 | 出图提示词 |
| 拼装输出 | 文案 + 图地址 | 写文案、生成配图 |
这张表列完,「文案和配图能不能并行」这个问题自己就消失了——画图要吃文案,就是不能并行。 大部分「该不该并行」的争论,都能靠这张表结束。
二、假并行:看着两条线,其实串着
演示里画了两张图。串行那张五层,从开始一路到结束。 并行那张也是五个节点,但把「抓热点」和「查素材库」拆成两条支路,汇到「写文案」再往下。
| 图 | 节点数 | 边数 | 关键路径层数 |
|---|---|---|---|
| 串行 | 5 | 4 | 5 |
| 并行 | 5 | 5 | 4 |
节点数一样、步数一样,关键路径差一层。 按每个节点耗时一样算,串行要串四次,并行串三次就够了——抓热点和查素材库同时跑。 只省一层。这就是「并行」在这个案例里的真实收益。为了省一层把图画复杂,值不值?多数时候不值。
三、什么时候真该并行
两条支路各自耗时长的时候。比如抓热点要等三秒、查素材库要等两秒,并行省两秒,串行要多等两秒。 还有一种是两条支路里有一条经常失败。分开之后,失败那条不影响另一条。 反过来,如果每个节点都只要几十毫秒——并行省下的时间还不如你多连两条线的时间。
所以判断标准是:先看关键路径上有几个耗时节点,再决定要不要并行。而不是「并行听起来更专业」。
四、拓扑序不保证你画的顺序
这一条容易踩坑:两条互不相干的支路,你画的时候先连 A 再连 B,不代表跑的时候 A 一定在 B 前面。 调度器按拓扑序跑:一个节点的所有上游跑完了,它才能跑。没有依赖关系的,谁先谁后由调度决定。 所以要依赖,就明明白白连一条边。别指望「我先画的先跑」。
实践里出过这样的事故:两个节点都往同一个变量里写值,靠「先后顺序」保证谁最后写。 图上没连边,顺序就不保证,结果随机。
五、汇合点的坑
两条支路汇到一个节点时,判断「这个节点要不要跑」不能按节点判,得按边判。 按节点判会错:从 A 支过来被跳过了,节点也被整块跳过——可 B 支还活着,数据白拿了。 正确做法:一个节点的所有入边都断了,才跳过它。
这条规则在第 8.8 节会救一次:短文那一路会跳过改写节点,但后面的出图提示词还得跑。 按节点判,它会跟着一起被跳掉。
六、这个案例的五步
| 步 | 节点 | 用的是什么 |
|---|---|---|
| 1 | 抓热点 | 插件(第 3 章) |
| 2 | 写文案 | 大模型 + 提示词(第 6 章) |
| 3 | 出图提示词 | 代码节点(第 4 章) |
| 4 | 生成配图 | 图像生成(第 4 章) |
| 5 | 拼装输出 | 结束节点(第 8.7 节) |
五步用了前七章的六样东西。这本书的案例都是这么拼起来的,没有新东西。 所以读案例的价值不在「学新功能」,在「看别人怎么把它们摆在一起」。
七、动手 Demo:两条线,最后才合
先画一张串行的图,再画一张拆了两条支路的图。两张图都真跑一次。 量的是关键路径层数——不是节点数,也不是步数。
def depth(flow):
u'''关键路径:从开始到结束最长的那条链有几层。'''
d = {}
for nid in flow.topo():
ins = [a for a, b in flow.edges if b == nid]
d[nid] = 1 + max([d[a] for a in ins] or [0])
return max(d.values())
f2.link(u's', u'hot').link(u's', u'lib') # 两条支路
f2.link(u'hot', u'txt').link(u'lib', u'txt') # 汇到写文案
f2.link(u'txt', u'e')
实跑输出:
--------------------------------------------------------------------
两条线,最后才合
--------------------------------------------------------------------
① 串行和并行:节点数一样,层数差一
--------------------------------------------------------------------
| 步 | 节点 | 类型 | 输出端口 | 毫秒 |
|---:|---|---|---|---:|
| 1 | 开始 | 开始 | q | 0.0 |
| 2 | 抓热点 | 插件 | list | 0.0 |
| 3 | 写文案 | 大模型 | t | 0.0 |
| 4 | 生成图 | 图像生成 | url | 0.0 |
| 5 | 结束 | 结束 | out | 0.0 |
串行:5 步。写完文案才去画图——因为画图的提示词要从文案里抽。
② 真并行:图不依赖文案?不成立
--------------------------------------------------------------------
看图上的依赖:画图的提示词是从文案里抽出来的。
所以「文案」和「配图」不是两条独立的线,是一条线加一个后续。
真正能并行的只有两件事:抓热点 和 查素材库。它们互不依赖。
| 步 | 节点 | 类型 | 输出端口 | 毫秒 |
|---:|---|---|---|---:|
| 1 | 开始 | 开始 | q | 0.0 |
| 2 | 抓热点 | 插件 | list | 0.0 |
| 3 | 查素材库 | 知识库检索 | pic | 0.0 |
| 4 | 写文案 | 大模型 | t | 0.0 |
| 5 | 结束 | 结束 | out | 0.0 |
| 图 | 节点数 | 边数 | 关键路径层数 | 实际走几步 |
|---|---:|---:|---:|---:|
| 串行 | 5 | 4 | 5 | 5 |
| 并行 | 5 | 5 | 4 | 5 |
两张图节点数一样、步数一样,关键路径差一层:串行五层,并行四层。
按每个节点耗时一样算,串行要串四次,并行串三次就够了——抓热点和查素材库是同时跑的。
③ 拓扑序不保证你画的顺序
--------------------------------------------------------------------
这一条容易踩坑:两条互不相干的支路,你画的时候先连 A 再连 B,不代表跑的时候 A 一定在 B 前面。
要依赖,就明明白白连一条边。 别指望「我先画的先跑」。
④ 汇合点的坑
--------------------------------------------------------------------
两条支路汇到一个节点时,只要有一条活着,这个节点就该跑。
早期我用「按节点判跳过」,结果两路一汇,从 A 过来被跳了,节点也被整块跳过,B 那边的数据白拿了。
正确做法是按边判:一个节点的所有入边都断了才跳过。
第 8.8 节那条链就是这个形状,短文那一路会跳过摘要节点,但后面的抽取还得跑。
! 画图之前先列一张依赖表:每个节点吃什么、谁给它。
表列清了,线就不会连错,也不会误以为两条线能并行。
①第一张轨迹表是串行:五步,一层压一层。写完文案才去画图——因为画图的提示词要从文案里抽。 ②第二张是并行:抓热点和查素材库并排跑,都汇到写文案。 ③第三张对照表只有两行,看最后两列:节点都是五个、步数都是五步,关键路径一个五层一个四层。 ④只省一层。这就是并行在这个案例里的真实收益——不是「快一倍」,是「少等一次」。 ⑤最后那段讲汇合点:早期按节点判跳过,两路一汇就整块被跳,B 支的数据白拿了。改成按边判才对。
30 秒实验
- 给你的流程列一张依赖表:每个节点吃什么、谁给它。列完再决定要不要画图。
- 数一下你的图从开始到结束最长那条链有几层。超过七层的,看看哪两个节点能合并。
- 找找有没有两个节点靠「先后顺序」暗自依赖的。有就补一条边。
常见误区
- 「图文两条线当然并行。」画图的提示词从文案里抽,串着。真正的并行只有互不依赖的那些。
- 「并行一定更快。」这个案例里只省一层。节点都很短的时候,省下的时间不如连线的功夫。
- 「我先连的先跑。」调度按拓扑序走,无依赖的节点顺序不保证。要依赖就连边。
自测三问(点开对答案)
1. 为什么文案和配图不能并行? —— 画图的提示词是从文案里抽出来的,画图要吃文案,所以串着。查依赖表就知道。 2. 并行在这个案例里省了多少? —— 关键路径从五层降到四层,只省一层。节点都很短时,这点收益不值得把图弄复杂。 3. 汇合点为什么不能按节点判跳过? —— 从 A 支过来被跳了,节点整块被跳过,可 B 支还活着,数据白拿。要按边判:所有入边都断才跳。设计完了,下一节动手:空画布、起名、连开始节点。三件小事,但地基歪了后面全歪。
- ☐ (本篇完,下一篇 8.2 创建基础工作流)
相关笔记
- 工作流及其分类:三种骨架与循环节点
- 扣子工作流的逻辑结构:四道校验
- 扣子工作流实战演练:那条六节点链
- 🐦 扣子开发 AI Agent · 索引