🎯 By the end of this module, you will:
Implementing Conditional Edges in LangGraph
Standard pipelines flow in a straight line. Real agents make decisions. Conditional edges are the railway switches of LangGraph — they inspect current state and dynamically route execution to the right destination node.
# SOURCE NODE: The node whose output triggers the routing decision
# This runs the LLM and updates state["messages"]
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
model = ChatOpenAI(model="gpt-4o-mini").bind_tools([search_web, get_weather])
def agent_node(state: AgentState) -> dict:
"""Calls LLM with tool bindings — result drives routing decision."""
response = model.invoke(state["messages"])
# State update: routing function will inspect this later
return {"messages": [response]}
# After agent_node runs:
# - If LLM chose to call a tool → response.tool_calls is non-empty
# - If LLM wrote a final answer → response.tool_calls is empty
# The routing function reads this to decide where to go next🔬 Railway Switch Simulator
Conditional Edge Railway Switch Simulator
See how a routing function inspects state and flips the execution track in real time
Where the edge starts: "agent_model"
Inspects state dict: def should_continue(state): ...
Maps returns to nodes: {"continue": "tools", "stop": END}
Conditional Edge Traps
If your routing function returns "retry" but your path map only has keys for "call_tools" and "__end__", LangGraph will raise a KeyError at runtime. Always ensure every possible return value of your routing function has a corresponding key in the path map.
A cyclic edge (tools → agent → tools → ...) with no escape condition creates an infinite loop that burns tokens until your budget limit hits. Always add a loop_count field to state and route to END when loop_count exceeds your maximum iteration threshold.
Key Takeaways
- 1.3 Components, Not 1: add_conditional_edges() needs all three: source node, routing function, path map. The path map is what makes the routing function's string output meaningful — without it, the string has no target.
- 2.Typing Prevents Runtime Errors: Use Literal['call_tools', '__end__'] as the return type of routing functions. This lets TypeScript/pyright catch missing path map keys at write-time, before any runtime error.
- 3.Always Add a Loop Ceiling: Any cyclic conditional edge (agent ↔ tools loop) needs a termination condition. Add a recursion_limit parameter to builder.compile() or track iterations in state. A tool error without a ceiling = infinite loop.
Designing Custom Workflows with State Graphs
Master the 3 canonical graph topologies: Linear Pipelines, Cyclic Reflection Loops, and Branching Triage Networks.