Nodes describe the work. Edges decide what runs next.
A fixed edge is always followed.
After tools return their observations, the model always reads them.
A conditional edge reads state and chooses a route.
The routing function does not need to solve the trip. It only needs to turn the latest verdict into a route name.
def route_after_check(state: TripState) -> str:
if state["verdict"]["compliant"]:
return "draft"
if state["attempts"] < 3:
return "replan"
return "escalate"
Read it in order:
compile() turns the declared shape into an agent that can run, be drawn, and be inspected.
from langgraph.graph import END, START, StateGraph
builder = StateGraph(TripState)
builder.add_node("retrieve_policy", retrieve_policy)
builder.add_node("llm_call", llm_call)
builder.add_node("check_policy", check_policy)
builder.add_edge(START, "retrieve_policy")
builder.add_edge("retrieve_policy", "llm_call")
builder.add_conditional_edges("check_policy", route_after_check)
graph = builder.compile()
The full graph would also register the tool, draft, and escalation nodes. The short example only shows how nodes and edges fit together.
A super-step is one round of graph execution.
Independent active nodes can run at the same time. Their updates are then merged before the graph moves forward.
| Super-step | Active work |
|---|---|
| 1 | retrieve_policy |
| 2 | llm_call |
| 3 | tool_node: flights and hotels together |
| 4 | llm_call reads both results |
| 5 | check_policy returns fail and routes to replan |
| 6 | llm_call plans another attempt |
Each super-step ends with a saved checkpoint.
The run stops when:
END, orrecursion_limit is reached—for example, 25 super-steps.The recursion limit is a safety ceiling, not a target.
END, so a finished task keeps moving.recursion_limit as the only time or cost budget.Edges turn small nodes into a visible workflow, while super-steps make parallel work, merging, checkpoints, routing, and stopping explicit.