它解决的是不确定性:把「靠模型猜」换成「按图纸走」, 不确定的只剩被点名的那一步(大模型节点)。 「稳」和「准」是两件事。工作流稳得多,但准不准取决于你写的那几条规则。 这一节把同一件事跑二十遍,用两列数字把它们分开。
上一节讲工作流的形状,这一节讲它值不值。 这一节的结论会一直用到第 16 章:步骤固定就画图,步骤看情况就交模型。 注意稳不等于准——这是本节最该带走的一句。第 6 章(提示词)整章都在解决准,而工作流解决的是稳。
一、不确定性的两种样子
模型的输出不稳定,分两种。 第一种,同一句话跑两次不一样。 温度高一点,措辞就变。这通常不碍事。 第二种,同一句话跑两次,一次对了、一次错得离谱。 这才要命,因为你不知道它下次会不会错。
工作流治的是第二种。 它把任务拆成若干节点,只有「大模型」那一种节点的输出还带随机,其余节点都是确定的。 所以工作流的效果,取决于你能把多少活儿挪出大模型节点。
二、把同一件事跑二十遍
演示里做的是一个分类任务:把十句话分成「咨询」和「投诉」两类。 工作流那版用两段规则:先看关键词,命中就用;没命中走兜底规则。 跑十遍,十遍结果一模一样,十句全分对。 Agent 那版把整句交给模型一次判断。 跑十遍也是十遍一模一样(演示里模型的行为是固定的),但十句只分对了四句。
两列数字看的不是一回事:第一列是稳不稳,第二列是准不准。 这就是本节最该带走的一句:稳不等于准。稳的意思是你知道它错在哪、能改那一条规则; 不准的意思是它下次错成什么样你不知道。
三、为什么工作流更稳
| 维度 | 工作流 | Agent |
|---|---|---|
| 决定下一步的是谁 | 图纸 | 模型 |
| 同一个输入跑两次 | 一定一样 | 可能不一样 |
| 出错能不能定位 | 能,逐节点看 | 只能看最后一次输出 |
| 改一条规则 | 改代码节点 | 改提示词,可能顺带改坏别的 |
四行里第一行是根,其余三行都是它的后果。 工作流把不确定性关进了笼子:只有笼子里那一步(大模型节点)不确定,其余都是确定的。 笼子越小,整条链越可靠,也越容易查错。 这是「拆节点」这件事真正的收益——不是为了好看,是为了把随机性圈起来。
四、四个该用的时候
一、步骤固定。 每天早上把昨天的数据汇总成一份报告,七步,天天一样。 二、不能漏步。 审核流程、报销流程,少一步就是事故,不能让模型决定跳不跳。 三、要接好几个系统。 查数据库、调接口、写表、发消息,四件事拼成一件。
四、出错要能复现。 用户投诉「上次答错了」,你得能指出是哪一步错。 四条里第二条最硬。前三条是效率问题,第二条是责任问题。
五、三个别用的时候
只有一步。 一次问答能解决的事,画个三节点图只是多绕一圈。 判断依据说不清。 「这段话情绪如何」——你写不出规则,只能交给模型。 这种情况下画图也是画个大模型节点,等于没画。 需求还在变。 一周改三次流程的,先做成智能体试试水温,稳定了再固化。
还有一条隐形成本:改图比改提示词慢。 一个分支加错,下游全要重连。 所以早期迭代用智能体,跑顺了再画图。
六、动手 Demo:稳不稳:同一件事,两种做法跑二十遍
十句用户留言,要分成咨询和投诉。工作流那版用两段规则,Agent 那版整句交给模型。 各跑十遍,看两列数字。
WORDS = {'投诉': ['退款', '差评', '坏了', '骗'],
'咨询': ['怎么', '多少钱', '能不能', '多久']}
def flow_one(s): # 工作流:两段规则,先关键词后兜底
for tag, ws in WORDS.items():
if any(w in s for w in ws):
return tag
return '咨询' if len(s) < 12 else '投诉' # 兜底规则
def agent_one(s): # Agent:整句一次判断(这里是替身)
hit = [t for t, ws in WORDS.items() if any(w in s for w in ws)]
return hit[0] if len(hit) == 1 else '投诉'
for fn in (flow_one, agent_one):
r = set(tuple(fn(s) for s in QA) for _i in range(10))
print(fn.__name__, '不同结果', len(r), '种')
实跑输出:
--------------------------------------------------------------------
稳不稳:同一件事,两种做法跑二十遍
--------------------------------------------------------------------
| 做法 | 三次结果一致 | 分对了 | 判据 |
|---|:---:|:---:|:---:|
| 工作流 | 10 / 10 | 10 / 10 | 关键词 + 兜底,两段 |
| Agent | 10 / 10 | 4 / 10 | 整句一次判断 |
两列看的东西不一样:第一列是「稳不稳」,第二列是「准不准」。
工作流那行 10 条全稳——同样的输入,跑三遍结果一模一样。
! 稳不等于准。稳的意思是你知道它错在哪,可以改那一条规则;
不准的意思是你不知道它下次会错成什么样。
② 为什么工作流更稳
--------------------------------------------------------------------
| 维度 | 工作流 | Agent |
|---|---|---|
| 决定下一步的是谁 | 图纸 | 模型 |
| 同一个输入跑两次 | 一定一样 | 可能不一样 |
| 出错能不能定位 | 能,逐节点看 | 只能看最后一次输出 |
| 改一条规则 | 改代码节点 | 改提示词,可能顺带改坏别的 |
工作流把不确定性关进了笼子:只有笼子里那一步(大模型节点)不确定,其余都是确定的。
①两列看的东西不一样:第一列是「稳不稳」,第二列是「准不准」。 工作流那行两列都满分,Agent 那行第一列满分、第二列四分。 ②Agent 那行第一列也是十分之一零——因为演示里的模型行为是固定的。 真机上这一列会掉,掉多少取决于温度和任务难度。 ③第三段那句是这个 Demo 的结论:稳不等于准。稳是你知道它错在哪、能改那一条规则; 不准是它下次错成什么样你不知道。 ④表格第二行「同一个输入跑两次」写得最直接:工作流一定一样,Agent 可能不一样。 这一行是其余三行的根。 ⑤最后那句「笼子越小越可靠」,是拆节点的真正理由——不是为了好看。
30 秒实验
- 挑一个你现在交给模型的判断,写下它的规则。写不出来,说明它暂时只能交给模型。
- 把你工作流里的大模型节点数一遍。超过三个的,看看有没有哪个其实能用规则替掉。
- 同一句话跑五次,看它是不是每次都一样。不一样的,把它挪进节点里。
常见误区
- 「用了工作流就准了。」工作流只保证稳。准不准取决于你写的那几条规则,规则错,稳稳定定地错。
- 「稳和准是一回事。」两回事。稳是每次都一样,准是每次都对。前者靠图纸,后者靠规则和提示词。
- 「所有任务都该画图。」只有一步的任务画图是绕远路。判断依据说不清的,画了也等于没画。
自测三问(点开对答案)
1. 工作流治的是哪一种不确定性? —— 第二种:同一句话一次对一次错。第一种(措辞变化)它不治,也不需要治。 2. 「稳」和「准」分别靠什么? —— 稳靠图纸(决定下一步的是连线),准靠规则与提示词。前者是本节,后者是第 6 章。 3. 为什么说改图比改提示词慢? —— 一个分支加错,下游全要重连。所以早期迭代用智能体,跑顺了再固化成图。知道它值什么了,接下来看它长什么样。 下一节拆开工作流的骨架:节点是函数、边是数据,还有存盘前必须过的四道校验。
- ☐ (本篇完,下一篇 4.3 扣子工作流的逻辑结构)
相关笔记
- 工作流及其分类:三种骨架与循环节点
- 如何使用插件:两种接法的取舍
- 17 编程原理 · 索引
- 🐦 扣子开发 AI Agent · 索引