构建约 15 分钟

Workflow 与 Pregel 图引擎

确定的业务步骤编排成图:超步怎么推进,多路怎么汇合,失败后怎么从断点续跑。

依据 agent-core 0.1.20 · develop@fbe6a0d9(2026-11-13)核实

什么时候用工作流而不是智能体

ReAct 智能体每一步做什么由模型决定,灵活但不完全可控。业务里有很多步骤是确定的:先查库存、再查产能、两者都有了再算交期。这类流程用工作流(Workflow)编排成图更合适:每个节点做什么、按什么顺序、在哪里分支,都写在图上。

两者也能组合:工作流里可以有大模型节点、意图识别节点、ReAct 节点;工作流本身也可以作为一个工具交给智能体调用。

openjiuwen.core.workflow 自带的组件:

类别组件
流程Start、End、BranchComponent、LoopComponent、SubWorkflowComponent
大模型LLMComponent、IntentDetectionComponent、问答组件(可向用户追问)
工具ToolComponent、HTTP 请求组件
资源知识检索、记忆读写
条件表达式、数值、数组条件

连线

flow = Workflow(card=WorkflowCard(id="promise_flow", ...))
flow.set_start_comp("start", Start(...))
flow.add_workflow_comp("inventory", ToolComponent(...))
flow.add_workflow_comp("capacity", ToolComponent(...))
flow.add_workflow_comp("promise", LLMComponent(...))
flow.set_end_comp("end", End(...))

flow.add_connection("start", "inventory")
flow.add_connection("start", "capacity")
flow.add_connection(["inventory", "capacity"], "promise")   # 汇合:两路都到齐
flow.add_connection("promise", "end")
说明

示意代码,方法名取自 Workflow 的公开 API,组件的构造参数省略了。本站没有运行它。

源码add_connectionagent-core/openjiuwen/core/workflow/workflow.py:279@fbe6a0d9

底层的图构建器按连线形状建不同的通道:

写法通道何时就绪
一对一 ("a", "b")触发通道收到一条消息就就绪
一对多 ("a", ["b", "c"])静态路由同时发给多个下游
多对一 (["a", "b"], "c")屏障通道每一组都至少到了一个

屏障通道支持"且"和"或"的组合:图构建器层面,[{"a"}, {"b"}] 表示 a 且 b,[{"a", "b"}] 表示 a 或 b,[{"a", "b"}, {"c"}] 表示 (a 或 b) 且 c。

源码BarrierChannelagent-core/openjiuwen/core/graph/pregel/channels.py:129@fbe6a0d9

超步:图是怎么跑起来的

执行引擎采用 Pregel 模型,按"超步"推进。每一个超步:

  1. 找出所有已就绪的节点
  2. 并发执行它们,等全部完成
  3. 把它们发出的消息统一投递到下游通道
  4. 进入下一步;没有就绪节点也没有待投递消息时结束

因为第 2 步要等齐,同一步里快的节点不会抢跑,每一步的输入都是确定的。超步数有上限(默认 10000),防止循环跑飞。

源码一个超步agent-core/openjiuwen/core/graph/pregel/engine.py:98@fbe6a0d9

失败了怎么办

某一步里有节点抛异常时,引擎会把现场存下来:各通道的快照、本步已成功节点发出的消息、失败的节点、当前步号。下次用同一个会话再运行时,从失败节点开始重试,已完成的节点不再执行。

前提是三样东西都在:session_id、命名空间、状态存储(store)。缺一样就不保存,只能从头再跑。

人工确认也走这条路:问答组件需要用户回答时会抛出中断,引擎同样保存现场,用户答复后接着跑。

源码_save_state_on_erroragent-core/openjiuwen/core/graph/pregel/engine.py:173@fbe6a0d9

动手:汇合与续跑

模拟器加载中…

小结

  • 确定的步骤用工作流,需要判断的步骤交给智能体,两者可以互相嵌套。
  • 多路汇合用多对一的 add_connection,不要拆成几条一对一的边。
  • 超步保证同一步的节点都完成后才往下走。
  • 想要失败续跑,运行时带上 session_id,并给图配好状态存储。

源码出处

链接指向固定提交,仓库后续更新不影响这里的行号。

过关测验

  1. 1. 同一个超步里有两个节点,一个 0.2 秒完成,一个 3 秒完成。快的那个的下游什么时候开始?

  2. 2. add_connection(["a", "b"], "c") 和分别写两次 add_connection("a", "c")、add_connection("b", "c") 有什么区别?

  3. 3. 工作流在第 3 步失败。下次运行想从第 3 步接着跑,需要什么?

通关条件

  • ○ 完成模拟器任务(0/2)
  • ○ 测验全部答对