一个正在发生的混乱:你搭了一条工作流,第一步查数据、第二步处理、第三步生成报告。搭到第三步,你觉得"这一步应该让 AI 自己判断怎么写报告,别写死模板了"。于是你把第三步换成了一个 Agent。跑了一遍,发现不对——工作流的调度器开始试图理解 Agent 在想什么,Agent 的推理过程里又冒出"我现在在工作流的第三步"这种奇怪的自觉。确定性和自主性,两头都没保住。
一、行业正在经历一场分野
2026 年,"工作流"和"Agent"这两个词,开始被明确地分开讨论。
微软在 2026 年 8 月的 Agent Framework 文档里写了一段很直白的话:最左端是一个带工具的单 Agent——模型自己决定做什么、什么时候委派、什么时候停;最右端是纯确定性执行器组成的工作流——完全可预测,但没有 AI 推理。大多数真实应用,活在中间的某个地方 $TRAE_REF。
学术界也在往同一个方向走。一篇 2026 年 5 月的论文把这件事说得更狠:"把智能和执行分开"——Agent 推理一次,产出一份声明式的工作流蓝图(JSON 格式的工具调用序列、循环、并行分支),之后的每次执行都直接跑这份蓝图,不再消耗额外推理 $TRAE_REF。
行业里的工具分类也在重排。有人把 n8n、Zapier、Temporal、AWS Step Functions 归为"工作流引擎"——路径是预先定义好的;把 LangGraph、AutoGen、CrewAI 归为"Agent 框架"——路径是运行时由模型决定的 $TRAE_REF。
这件事为什么值得写?因为大多数团队的真实痛点,不是"我要不要用工作流",也不是"我要不要用 Agent",而是我怎么把两个东西放在同一个系统里,又不让它们互相污染。
二、两种心智模型,本来就不该混
先说清楚一件事:工作流和 Agent,背后是两种完全不同的心智模型。
工作流的心智是:我知道每一步要做什么。我只要管两件事——第一步什么时候跑、跑完之后第二步能不能跑。它关心的是顺序、依赖、条件、并发。它要的是确定性:同样的输入,永远走同样的路径。
Agent 的心智是:我不知道下一步做什么。我要让模型自己判断——这个问题该用哪个工具、这个工具失败了要不要换另一个、什么时候算做完了。它关心的是推理、探索、纠错、停止条件。它要的是自主性:同样的输入,可能走出不同的路径。
这两种心智模型,一旦混在同一个体系里,就会互相打架。
工作流的调度器开始试图理解 Agent 在想什么——它要判断 Agent 的推理过程是不是符合预期、要不要打断、要不要回滚。Agent 的推理过程里开始冒出"我现在在工作流的第三步"这种自觉——它要考虑自己的动作会不会破坏工作流的后续步骤。
结果是:工作流的确定性被 Agent 的自主性冲垮了,Agent 的自主性被工作流的束缚捆死了。两头都不靠。
三、正交解耦:两个体系,互不感知
我们的做法很简单,也很反直觉——把两个体系彻底分开,让它们互相不知道对方的存在。
工作流层,只管插件的执行顺序。调度器从预计算好的拓扑里读出:哪些节点是起点、哪些节点的上游已经完成了、现在可以跑哪些。它只关心"这个节点能不能跑",不关心"这个节点里面跑的是什么"。节点里是 HTTP 调用、是数据库查询、还是一个 Agent 的推理过程——对调度器来说都是黑盒。
Agent 层,只管推理过程。Agent 内核启动的时候,加载的是自己的推理引擎、工具箱、记忆管理器、追踪记录器。它只知道:我收到了一个输入,我要推理、我可以用哪些工具、我要记住什么。它不知道自己是不是跑在某个工作流里、不知道上游节点是谁、不知道下游还有什么等着它的结果。
这就是"正交解耦"的意思——两个体系的关注点互相垂直,没有交集。工作流的纵轴是"执行顺序",Agent 的横轴是"推理过程"。它们在一张图上,但不互相穿越。
这件事的意义要辩证地看。有人会说:"那不就是把两个东西并排放在一起吗?有什么技术含量?"
技术含量不在于"放一起",在于两边都真的不知道对方的存在。
如果调度器知道节点里跑的是 Agent,它就会开始想"我要不要干预这个 Agent 的推理过程";如果 Agent 知道自己跑在工作流里,它就会开始想"我这个动作会不会破坏工作流的后续步骤"。只要两边有任何一点"感知",解耦就破了——确定性和自主性的互相污染,就从那一点点感知开始。
四、单向桥接:插件是唯一的粘合层
两个体系互不感知,那它们怎么协作?答案是:通过插件单向桥接。
插件是工作流的执行单元——调度器把插件当一个节点来调度,插件跑完了,调度器才知道下一步该跑谁。
插件也是 Agent 的调用入口——插件在执行过程中,可以调用另一个 Agent。这个调用不是 Agent 内核提供的能力,是插件基类提供的方法。
整个调用链长这样:
- 调度器发现某个节点的上游全完成了,触发这个节点
- 执行服务加载这个节点绑定的插件,执行它的方法
- 插件在执行过程中,调用了一个 Agent——"帮我把这段数据分析一下"
- Agent 收到输入和历史,开始推理、用工具、记记忆
- Agent 返回结果
- 控制权回到插件手里,插件继续执行
- 插件返回最终结果给调度器
- 调度器标记这个节点完成,检查下游有没有可以跑的节点
注意这里面的方向。调用是单向的——工作流可以调插件,插件可以调 Agent,但 Agent 不会反过来调工作流。Agent 不知道是谁在调它,它只收到输入和历史,它只管推理和回答。
这意味着什么?意味着 Agent 永远不知道自己是被一个画布节点调起的,还是被另一个 Agent 调起的,还是被一个用户直接对话调起的。它的行为模式、上下文组装、工具选择——全部是一样的。
这种单向性带来的好处是:同一个 Agent,可以用在任何地方。你可以把它挂在画布的一个节点里,也可以让它作为另一个 Agent 的工具被嵌套调用,也可以直接开一个对话窗口和它聊。它不需要知道自己在哪,它只需要知道自己是谁。
血缘追溯是另一个值得说的点。插件调 Agent 的时候,会把父会话和父轮次 ID 传过去。Agent 返回的时候,这些 ID 会跟着返回结果一起回来。整个调用链——从最外层的画布触发,到最内层的 Agent 推理——形成一条完整的血缘链。出了问题,你可以顺着这条链一层一层往上查,是哪一层的调用出了问题。
五、为什么这种解耦是对的
回到最开始那个混乱的场景:你把工作流的第三步换成了一个 Agent,结果两头不靠。
如果按正交解耦的思路做这件事,答案是什么?
工作流的第三步,是一个节点。这个节点绑定了一个插件。这个插件在执行过程中,调用了一个 Agent。
就这么简单。
工作流的调度器还是只关心"这个节点能不能跑"——上游完成了就跑,跑完了就标记完成。它不知道这个节点里面是一个 Agent。
Agent 还是只关心"我收到了什么输入"——它收到插件传过来的数据和指令,开始推理、用工具、返回结果。它不知道这个调用来自一个画布节点。
插件是中间的粘合层——它从工作流的执行上下文里拿到上游数据,把数据组装成 Agent 能理解的输入,调 Agent,拿到 Agent 的输出,再把输出转成工作流能消费的格式。
工作流的确定性保住了——调度器还是按 DAG 顺序跑,该并发的并发,该等上游的等上游。Agent 的自主性也保住了——Agent 还是自己决定用什么工具、怎么推理、什么时候停。
这就是正交解耦的价值。它不是把两个体系"切开不管",而是让各自管各自最擅长的事:工作流管顺序,Agent 管推理,插件管两边的翻译。
六、回到起点
回到开头那个问题:怎么把工作流和 Agent 放在同一个系统里,又不让它们互相污染?
答案不是"让工作流约束 Agent"——那会把 Agent 捆死。也不是"让 Agent 接管工作流"——那会把工作流冲垮。
答案是:正交解耦,单向桥接。
工作流层管插件的执行顺序,Agent 层管推理过程。两层互相不知道对方的存在,插件是两层之间唯一的粘合层。工作流不知道节点里跑了 Agent,Agent 不知道自己跑在工作流里。插件把工作流的上下文翻译成 Agent 的输入,把 Agent 的输出翻译回工作流能消费的结果。
这种设计的好处,回过头看其实很朴素:每个体系只需要为自己负责的事情做优化。工作流的调度器可以专注于拓扑排序、并发执行、状态管理;Agent 内核可以专注于推理质量、工具调用、记忆管理。不需要任何一方去"理解"另一方。
如果你也在做一个既要确定性流程、又要 AI 自主性的系统,不妨先问自己一个问题:我的工作流调度器,知道节点里跑了什么吗?我的 Agent,知道自己跑在哪里吗? 如果两个答案都是"知道",那大概率正在两头不靠。
这篇文章讲的是我们在策熔平台上做工作流与 Agent 协作时形成的一些工程判断——两层正交解耦、插件单向桥接、调用链血缘追溯。如果你也在搭类似的系统,欢迎在评论区聊聊你的做法。