Why do LangGraph conditional edges exist when a plain DAG already has edges?
A conditional edge runs a routing function over state and returns the next node name. That is the primitive that lets a graph express cycles, branches, and retries.
Picture a board game. A normal arrow on the board says 'after square 3, always go to square 4'. Every game plays out the same way. A conditional arrow looks at the dice you just rolled and says 'if you rolled a 6, go back to start; if you rolled even, advance two; otherwise stay.' That single change turns a fixed path into a game with strategy. A flowing pipeline only has fixed arrows. An agent that decides what to do next based on what it just saw needs the dice-reading arrow. LangGraph's conditional edges are those dice-reading arrows.
Detailed answer & concept explanation~4 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
7 min: routing function shape, three behaviours unlocked, contrast with DAG frameworks, interaction with checkpointer, common production patterns.
from langgraph.graph import StateGraph, END
def call_model(state):
response = llm.invoke(state["messages"])
return {"messages": state["messages"] + [response]}
def call_tool(state):
out = run_tool(state["messages"][-1].tool_calls[0])
return {"messages": state["messages"] + [out]}
def route(state) -> str:
last = state["messages"][-1]
return "tool" if getattr(last, "tool_calls", None) else END
graph = StateGraph(dict)
graph.add_node("model", call_model)
graph.add_node("tool", call_tool)
graph.add_edge("tool", "model") # fixed edge: tool result re-enters model
graph.add_conditional_edges("model", route) # routing function decides next step
graph.set_entry_point("model")
app = graph.compile()
Real products, models, and research that use this idea.
- LangGraph's prebuilt `create_react_agent` uses a conditional edge between the LLM node and the tool node to loop until the model emits no more tool calls
- Anthropic's research-agent reference implementation routes via conditional edges among planner, retriever, and synthesizer until coverage is sufficient
- Mastra's TypeScript workflow runtime adopts the same routing function as edge pattern to express agent loops in TS
What an interviewer would ask next. Try answering before peeking at the approach.
QHow does the checkpointer interact with conditional edges during time-travel?
QWhy are route functions required to be pure reads of state?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Treating a conditional edge as 'just an if statement'. It is the routing primitive that makes cycles legal in the graph, which is exactly what a DAG cannot express.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.