Conditional edges for routing decisions
Conditional edges choose the next node at runtime by running a function over the current state. They enable branching logic in the graph based on state values, such as grading whether retrieved documents are relevant before proceeding to answer generation.
Edge topology changes are safe for in-flight threads
Edge topology itself is not persisted in the checkpoint. Adding, removing, or rerouting edges between nodes that still exist is safe for in-flight threads. The only topology change that can break an interrupted thread is renaming or removing a node.
Graph API for parallel processing
When you need to run multiple operations in parallel and then combine their results, the Graph API handles this naturally. Multiple edges can start from the START node pointing to different nodes (which run in parallel), and then all those nodes can have edges pointing to a combine node that waits for all parallel operations to complete.
Conditional edges in SQL agent workflow
A conditional edge is used at the query generation step that routes to the query checker if a query is generated (tool calls are present), or ends the workflow if there are no tool calls present (the LLM has delivered a response without needing further tools).
Add edges with add_edge for fixed routing between nodes
Use workflow.add_edge(source, destination) to connect nodes with fixed routing. Example: workflow.add_edge(START, "read_email"), workflow.add_edge("read_email", "classify_intent"), workflow.add_edge("send_reply", END). This creates essential connections; nodes handle dynamic routing via Command.
Conditional edges route based on tool calls
Use add_conditional_edges() to route between nodes based on conditions. A common pattern is to check if the last message has tool_calls: if it does, route to the tool node; otherwise route to END.
Normal edges for static routing
If you always want to go from node A to node B, you can use the add_edge method (Python) or addEdge method (JavaScript) directly to create a normal edge.
Conditional edges for optional routing
If you want to optionally route to one or more edges or optionally terminate, you can use the add_conditional_edges method (Python) or addConditionalEdges method (JavaScript). This method accepts the name of a node and a routing function to call after that node is executed. The routing function accepts the current state and returns a value. By default, the return value is used as the name of the node(s) to send the state to next. All those nodes will run in parallel as part of the next superstep. You can optionally provide a dictionary/object that maps the routing function's output to the name of the next node.
Entry point for graph execution
The entry point is the first node(s) that run when the graph starts. You can use add_edge (Python) or addEdge (JavaScript) from the virtual START node to the first node to execute to specify where to enter the graph.
Conditional entry point
A conditional entry point lets you start at different nodes depending on custom logic. You can use add_conditional_edges (Python) or addConditionalEdges (JavaScript) from the virtual START node to accomplish this. You can optionally provide a dictionary/object that maps the routing function's output to the name of the next node.
Multiple parallel edges from a node
A node can have multiple outgoing edges. If a node has multiple outgoing edges, all of those destination nodes will be executed in parallel as a part of the next superstep.
Do not mix normal edges with dynamic routing
For each node, choose one routing mechanism: use normal edges for static routing, or use conditional edges and Command for dynamic routing. Do not mix normal edges and dynamic routing from the same node, because both paths can execute and make graph behavior harder to reason about.
Send for map-reduce pattern
By default, Nodes and Edges are defined ahead of time and operate on the same shared state. However, there can be cases where the exact edges are not known ahead of time or you may want different versions of State to exist at the same time, such as with map-reduce design patterns. LangGraph supports returning Send objects from conditional edges. Send takes two arguments: the name of the node and the state to pass to that node. This allows a first node to generate a list of objects, and you can apply some other node to all those objects even when the number of objects is unknown ahead of time.
Command for combining state updates and routing
Command is a versatile primitive for controlling graph execution. It accepts four parameters: update (apply state updates), goto (navigate to specific nodes), graph (target a parent graph when navigating from subgraphs), and resume (provide a value to resume execution after an interrupt). Command is used in three contexts: return from nodes to combine state updates with control flow, input to invoke or stream to continue execution after an interrupt, and return from tools.
Command update and goto in node return
Return Command from node functions to update state and route to the next node in a single step. Use Command when you need to both update state and route to a different node. If you only need to route without updating state, use conditional edges instead. When returning Command in your node functions, you must add return type annotations with the list of node names the node is routing to.
Command only adds dynamic edges
Command only adds dynamic edges. Static edges defined with add_edge / addEdge still execute. For example, if node_a returns Command(goto='my_other_node') and you also have graph.add_edge('node_a', 'node_b'), both node_b and my_other_node will run. For each node, use either Command or static edges to route to the next nodes, not both.
Command inside tools for state update and routing
You can return Command from tools to update graph state and control flow. Use update to modify state (e.g., saving customer information looked up during a conversation) and goto to route to a specific node after the tool completes. When used inside tools, goto adds a dynamic edge—any static edges already defined on the node that called the tool will still execute. For each node, use either tool-driven dynamic routing or static edges, not both.
Conditional edge routing with add_conditional_edges
Use add_conditional_edges to select execution paths based on graph state. The routing function receives the state and returns the next node name or list of node names. Example: builder.add_conditional_edges('a', conditional_edge_function).
Conditional edges returning multiple destinations
Conditional edge functions can return a single node name or a Sequence of node names to route to multiple destinations. Example: def route_bc_or_cd(state: State) -> Sequence[str]: if state['which'] == 'cd': return ['c', 'd']; return ['b', 'c'].
ConditionalEdgeRouter type definition
A ConditionalEdgeRouter is a function type that takes state and returns either a node name or END. It is typed as ConditionalEdgeRouter<{ InputSchema: typeof State; Nodes: "node_name" }> and receives the state as input, using conditional logic to determine which node to route to next.
addConditionalEdges method
The addConditionalEdges method on StateGraph accepts a source node name and a ConditionalEdgeRouter function. It allows routing from a node to different destination nodes based on the state, with the router function determining which path to take.
StateGraph addEdge method
The addEdge method on StateGraph connects two nodes. It takes a source node name and destination node name. Use START as the source to connect from the graph start, and END as the destination to connect to the graph end.
Example conditional routing graph
Example TypeScript code showing conditional routing: node1 increments value by 1, node2 multiplies value by 2. A router function checks if state.value < 10 and returns "node2" to continue looping, otherwise returns END. Edges connect START to node1, node1 conditionally routes to node2 or END, and node2 loops back to node1.