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,组件的构造参数省略了。本站没有运行它。
底层的图构建器按连线形状建不同的通道:
| 写法 | 通道 | 何时就绪 |
|---|---|---|
一对一 ("a", "b") | 触发通道 | 收到一条消息就就绪 |
一对多 ("a", ["b", "c"]) | 静态路由 | 同时发给多个下游 |
多对一 (["a", "b"], "c") | 屏障通道 | 每一组都至少到了一个 |
屏障通道支持"且"和"或"的组合:图构建器层面,[{"a"}, {"b"}] 表示 a 且 b,[{"a", "b"}] 表示 a 或 b,[{"a", "b"}, {"c"}] 表示 (a 或 b) 且 c。
超步:图是怎么跑起来的
执行引擎采用 Pregel 模型,按"超步"推进。每一个超步:
- 找出所有已就绪的节点
- 并发执行它们,等全部完成
- 把它们发出的消息统一投递到下游通道
- 进入下一步;没有就绪节点也没有待投递消息时结束
因为第 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,并给图配好状态存储。
源码出处
- agent-core/openjiuwen/core/workflow/workflow.py:279
def add_connection连线 API - agent-core/openjiuwen/core/workflow/workflow.py:311
def add_conditional_connection条件分支 - agent-core/openjiuwen/core/workflow/__init__.py内置组件清单
- agent-core/openjiuwen/core/graph/pregel/builder.py:28
def add_edge一对一、一对多、多对一三种边 - agent-core/openjiuwen/core/graph/pregel/channels.py:129
class BarrierChannel汇合用的屏障通道,支持"且"和"或" - agent-core/openjiuwen/core/graph/pregel/engine.py:98
async def _run_step一个超步做什么 - agent-core/openjiuwen/core/graph/pregel/engine.py:173
async def _save_state_on_error失败时保存现场
链接指向固定提交,仓库后续更新不影响这里的行号。
过关测验
1. 同一个超步里有两个节点,一个 0.2 秒完成,一个 3 秒完成。快的那个的下游什么时候开始?
2. add_connection(["a", "b"], "c") 和分别写两次 add_connection("a", "c")、add_connection("b", "c") 有什么区别?
3. 工作流在第 3 步失败。下次运行想从第 3 步接着跑,需要什么?