读懂LangGraph 的分支执行逻辑

一个 AI 请求只有一个答案时,流程很直;一旦同一输入要走几个方向,代码就像突然遇到一组路口:选哪条路、哪些路能同时走、最后在哪里汇合。LangGraph 把这些路口变成可以运行的图。

编译图时,所有候选节点已经注册完成。运行时只是在这些固定节点中选择一条或几条。

图中只准备通用 Worker,运行时才决定创建几个任务、每个任务带什么参数。Send 属于动态分支,适合批量处理和数量不确定的任务。

⭐ 判断口诀: 节点集合提前知道,是静态分支;任务数量运行时才知道,是动态分支。

下面的代码可以直接运行。add_conditional_edges() 根据路由函数返回的标签,选择已经注册好的节点。

⭐ 重点: 图中只有 poem_node 和 joke_node 两个候选节点,运行时不会凭空增加第三个节点。

Command 把“判断状态”和“跳转位置”放在一个节点里。下面是完整写法,未知类型会直接结束:

有效任务会先经过对应 Worker,再到 END;只有未知类型才从 Router 直接结束。add_conditional_edges() 是“返回标签后查映射表”,属于静态分支;Command 是“函数在运行时直接指定下一站”,属于动态分支。两者选一种即可,不要给同一个 Router 再接一套普通下游边。

⭐ 重点: Command 的“动态”指运行时决定跳转路径,目标节点本身仍然要提前注册到图中。

动态分支的另一种常见形式是运行时拆出多个任务。扇出就是“一变多”:一个 Router 把一份输入拆成多个独立任务。下面的代码从导入到调用都是完整的:

router 发出三张任务单,三个 worker_node 可以同时执行;Worker 不需要知道自己是第几个任务,只处理收到的 prompt。这就是动态分支:任务数量和参数由运行时数据决定。

扇入就是“多变一”:多个分支完成后进入同一个汇总节点。重点只看下面两种连接方式。

这是两条独立触发条件:node_c 完成可以触发一次,node_d 完成也可以触发一次。因此 node_e 会执行两次,适合“任意一个结果到达就处理”的场景,例如先到先返回、逐条通知。

完整示例中的其他节点和边都不变,只把两条独立边替换成一条列表形式的多前置边:

这是一个同步条件:node_c 和 node_d 都完成后,node_e 只执行一次。它适合汇总多个接口结果、统一审核、拼装最终答案等场景。

可以看到 node_e 出现两次:第一次由 node_c 触发,第二次由 node_d 触发。

使用 builder.add_edge(["node_c", "node_d"], "node_e"):

这里只有一次 node_e 日志,说明它等待两个前置节点都完成后才执行。

⭐ 重点: 独立边是“谁先完成谁触发”,列表边是“全部完成后触发一次”。

主任务完成后,可以让延迟节点负责日志和完整性检查:

它适合统计、质量检查和日志记录。defer 不是新的分支类型,而是一个收尾时机控制器。

✅ 一句话记忆: 静态分支是在固定节点中选路,动态分支是在运行时发任务;扇出负责拆开任务,扇入负责等齐结果。

来源:稀土掘金 原文