[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f3d9v6jt3cv5vl":3},{"_id":4,"slug":5,"title":6,"subtitle":7,"kind":8,"cards":9,"tags":24,"categories":25,"source":26,"lang":29,"author":30,"audioState":33,"stats":34,"publishedAt":37,"renderer":38},"6abb35d5ca21c797c7e9c074","langgraph-6024babf","读懂LangGraph 的分支执行逻辑","一个 AI 请求只有一个答案时，流程很直；一旦同一输入要走几个方向，代码就像突然遇到一组路口：选哪条路、哪些路能同时走、最后在哪里汇合。LangGraph 把这些路口变成可以运行的图。 编译图时，所有候选节点已经注册完成。运行时只是在这些固定节点中选择一条或几条。 图中只准备通用 Worker，运行时才决定创建几个任务、每个任务带什么参数。Send 属于动态分支，适合批量处理和数量不确定的任务。…","news",[10,14,19],{"headline":6,"body":11,"imageUrl":12,"images":13},"一个 AI 请求只有一个答案时，流程很直；一旦同一输入要走几个方向，代码就像突然遇到一组路口：选哪条路、哪些路能同时走、最后在哪里汇合。LangGraph 把这些路口变成可以运行的图。 编译图时，所有候选节点已经注册完成。运行时只是在这些固定节点中选择一条或几条。 图中只准备通用 Worker，运行时才决定创建几个任务、每个任务带什么参数。Send 属于动态分支，适合批量处理和数量不确定的任务。 ⭐ 判断口诀： 节点集合提前知道，是静态分支；任务数量运行时才知道，是动态分支。 ⭐ 判断口诀： 节点集合提前知道，是静态分支；任务数量运行时才知道，是动态分支。 下面的代码可以直接运行。add_conditional_edges() 根据路由函数返回的标签，选择已经注册好的节点。 ⭐ 重点： 图中只有 poem_node 和 joke_node 两个候选节点，运行时不会凭空增加第三个节点。 ⭐ 重点： 图中只有 poem_node 和 joke_node 两个候选节点，运行时不会凭空增加第三个节点。 Command 把“判断状态”和“跳转位置”放在一个节点里。下面是完整写法，未知类型会直接结束： Command(goto=...)（运行时跳转到下游节点）","\u002Fapi\u002Fmedia\u002Fposts\u002Flanggraph-6024babf\u002F0.webp",{"local":12},{"headline":15,"body":16,"imageUrl":17,"images":18},"有效任务会先经过对应 Worker，再到 END；只有未知类型才从 Router 直接结束。add_conditional_edges()…","有效任务会先经过对应 Worker，再到 END；只有未知类型才从 Router 直接结束。add_conditional_edges() 是“返回标签后查映射表”，属于静态分支；Command 是“函数在运行时直接指定下一站”，属于动态分支。两者选一种即可，不要给同一个 Router 再接一套普通下游边。 ⭐ 重点： Command 的“动态”指运行时决定跳转路径，目标节点本身仍然要提前注册到图中。 ⭐ 重点： 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 日志，说明它等待两个前置节点都完成后才执行。 ⭐ 重点： 独立边是“谁先完成谁触发”，列表边是“全部完成后触发一次”。 ⭐ 重点： 独立边是“谁先完成谁触发”，列表边是“全部完成后触发一次”。","\u002Fapi\u002Fmedia\u002Fposts\u002Flanggraph-6024babf\u002F1.webp",{"local":17},{"headline":20,"body":21,"imageUrl":22,"images":23},"主任务完成后，可以让延迟节点负责日志和完整性检查： 它适合统计、质量检查和日志记录。defer 不是新的分支类型，而是一个收尾时机控制器。…","主任务完成后，可以让延迟节点负责日志和完整性检查： 它适合统计、质量检查和日志记录。defer 不是新的分支类型，而是一个收尾时机控制器。 固定类型选择一个处理器：add_conditional_edges 或 Command。 数量不固定的批量任务：Send 动态创建 Worker。 多来源同时查询后汇总：并行扇出，再用列表形式的多前置边扇入。 任务结束后检查和记录：defer=True 配合日志节点。 ✅ 一句话记忆： 静态分支是在固定节点中选路，动态分支是在运行时发任务；扇出负责拆开任务，扇入负责等齐结果。 ✅ 一句话记忆： 静态分支是在固定节点中选路，动态分支是在运行时发任务；扇出负责拆开任务，扇入负责等齐结果。","\u002Fapi\u002Fmedia\u002Fposts\u002Flanggraph-6024babf\u002F2.webp",{"local":22},[],[],{"name":27,"url":28},"Juejin","https:\u002F\u002Fjuejin.cn\u002Fpost\u002F7690468159975637038","zh",{"handle":31,"displayName":32},"spots","Spots",null,{"views":35,"likes":36,"saves":36,"shares":36,"completions":36,"opens":36,"skips":36,"depthSum":36},3,0,"2026-09-29T03:51:49.384Z","local"]