前两篇的图都是"一条路走到底":并行也好,汇合也好,执行路径在写代码时就已经确定。可真实的流程充满了"看情况":用户问退款就转退款,问技术就转技术;草稿不合格就退回重写;要拆成几个子任务,得等规划完才知道。这一篇讲 LangGraph 的四种流程控制手段:条件边、循环、Send、Command。它们解决的问题各不相同,最后我们会用官方总结的几种工作流模式,把它们串成一张选型表。

一、条件边:让图根据情况选路#

先看最常见的需求——分流。一个客服助手收到用户的问题,先判断类别,再交给对应的处理流程:

flowchart LR
  S([开始]) --> C[判断类别]
  C -.->|退款| R[退款流程]
  C -.->|技术问题| T[技术支持]
  C -.->|其他| H[闲聊]
  R --> E([结束])
  T --> E
  H --> E

"判断类别"之后去哪,取决于运行时的 State,这在普通边里没法表达。条件边就是为此设计的:它由一个路由函数决定下一步。路由函数读取 State,返回下一个节点的名字:

Python
from typing import Literal

def route(state) -> Literal["refund", "tech", "chat"]:
    return state["category"]          # 由上一个节点写入的类别

builder.add_conditional_edges("classify", route)

整个分流就靠这两步:classify 节点负责把判断结果写进 State,route 函数负责读取它、指出去向。把"做判断"和"选路线"拆开,各自都很简单。

1.1 返回值的类型标注不是摆设#

注意 route 的返回类型写成了 Literal["refund", "tech", "chat"]。去掉它,程序照样能跑,但 LangGraph 就无从知道这条条件边可能通向哪些节点。实测把标注删掉后再导出流程图,三个处理节点全都成了"孤岛",classify 被画成直接连到结束。

所以,给路由函数写上 Literal 返回类型(或者给 add_conditional_edges 传一个"返回值 → 节点名"的映射字典),流程图才画得出来,后面讲到的调试工具也才能正确展示图结构。

1.2 判断交给谁#

例子里的"判断类别"可以是关键词规则,也可以交给大模型。交给模型时,最稳妥的做法是用 LangChain 系列第二篇讲过的结构化输出,让模型只能从几个固定选项里挑:

Python
class Category(BaseModel):
    category: Literal["refund", "tech", ]

classifier = model.with_structured_output(Category)

 ():
    result = classifier.invoke()
     {: result.category}