先记住这个答案
当图的下一个节点必须根据当前状态动态选择,例如模型判断是否需要工具或直接回复,应使用条件边。相反,若步骤链条每次执行都相同,用固定边更直观。条件路由将路由逻辑散落在边函数中,增加认知负荷和测试难度,过度使用会把简单线性流程拆成多个分支,导致状态更新和调试变复杂。
- 固定边适合确定顺序,条件边适合状态驱动分支
- 过度条件路由降低图的可读性与可测试性
- 判断依据是路由是否依赖运行时状态且分支可枚举
固定边与条件边的执行机制差异
LangGraph 中边定义节点完成后消息的传播目标。固定边在编译时就确定唯一的接收节点,例如节点 A 完成后总是去节点 B。它的执行路径是静态的,调试时只要读图结构就能知道完整顺序。条件边则注册一个路由函数,节点完成后由该函数读取当前状态并返回下一个节点名称或节点列表。路由函数只在节点成功返回后调用,它不修改状态,仅做决策。
这种机制使得条件边把路径选择推迟到运行时,但代价是图结构不再自明。一个节点有多条出边时,实际走哪条依赖状态值,需要检查路由函数逻辑。LangGraph 内部在 super-step 中执行节点,条件边在节点结束后触发,返回的节点会进入下一个 super-step。若多个分支并行返回,会并行激活多个节点,这不是默认行为,而是路由函数返回列表的结果。
客服 Agent:需要动态判断是否调用工具
构造一个客服工作流:用户问题先进入 reason 节点,该节点用模型判断意图并输出是否调用检索工具。固定边无法做到,因为后续节点取决于模型输出。因此用条件边:从 reason 节点路由,若路由函数返回 'retrieve' 则去检索节点,否则去 generate 直接回答。reason 节点在状态里写入 needs_retrieval 布尔字段,路由函数读该字段返回相应节点。
这个场景中,条件边是必须的,因为模型输出无法静态确定。但注意只有 reason 节点后用了条件边,后续 retrieve 完成后固定接到 generate。若整个流程每个节点都加条件边,例如 retrieve 之后还要判断是否去另一个工具,就会形成多级动态路由,每个分支状态需要额外字段管理,图会迅速复杂。实际处理上,将意图分类集中在 reason 节点,后续用固定边执行,确保核心分支唯一。
过度使用条件边:可诊断性丢失与维护成本
一个容易失效的边界是:开发者为了短期扩展性,把所有节点连接都改成条件边,即使当前只有一条固定路径。这会迫使每次运行都调用路由函数,且路由函数内部必须处理所有不可能分支,否则抛错。它让图的执行依赖于大量隐式条件,当出现意外输出时,必须逐个检查路由函数,无法通过边的静态连接快速定位断点。LangGraph 的 stream_mode 调试也会看到每次经过条件边,但原因不直观。
另一个代价是测试成本上升。固定边图可以用简单的链式样例验证调用序列,条件边图则需要为每个路由分支构造状态输入,否则分支可能未被覆盖。更严重的是,条件边与循环结合时,如果路由条件永远不满足终止,会引发 GraphRecursionError。过度使用会模糊流程主干,应该把条件边限制在语义上有意义的决策点,例如任务分发、循环判断、工具调用分支。
容易答错的地方
- 所有动态流程都必须用条件边
- 并非所有动态流程都必须用条件边,但固定边无法实现运行时分支。若分支不依赖运行时状态,而是由调用方在调用前确定路径,可通过配置不同起始节点或构建不同图实例实现,不必在单一图中使用条件边。此外,LangGraph 的 Command 机制允许节点返回 Command 来动态指定下一个节点,也可以替代条件边。因此,条件边是常见选择,但并非唯一。
- 条件边越多,控制力越强
- 条件边多意味着图路径组合爆炸,测试需要覆盖每条路径的组合。控制力来自清晰的路由决策,而不是边的数量。集中决策点(如 router 节点)优于多个零散条件边。一个大型图若每个节点都输出不同路由,修改一个条件会影响全局,增加维护风险。
面试官还会怎么问?
条件边和固定边在 Checkpoint 恢复时表现有何不同?
恢复时 LangGraph 从最近检查点继续,会重新执行因中断而暂停的节点。对于条件边,若节点重跑,路由函数也会重新求值,因此路由函数必须无副作用且只依赖检查点中保存的状态。固定边则直接恢复转移,少一次函数调用。
条件边能否返回多个节点实现并行?
可以,路由函数返回节点名列表时会并行激活多个节点,类似扇出。但需注意这些节点在同一 super-step 中执行,且它们的更新需要 reducer 合并。若并行分支之间没有数据依赖,这是合理用法。但若只是为了同时执行而故意用条件边返回多路,不如用普通并行边更直观。
如何避免条件路由函数中的重复逻辑?
可将路由函数设计为纯函数,并提取共享判断为可复用 helper。更推荐将多个决策集中到一个 router 节点,由该节点更新状态并返回 Command 跳转,避免每条边各写逻辑。如果逻辑复杂,使用状态机模式管理可枚举状态。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。