LangGraph Basics: State, Nodes and Edges
Intuition
Your agent loops so far were while loops with ifs inside. As workflows grow — retries,
approvals, several workers — that control flow becomes hard to read and test. LangGraph makes it
explicit: a state dict, nodes that read the state and return updates, and edges that
decide which node runs next.
Precise explanation
import operator
from typing import Annotated, TypedDict
from langgraph.graph import END, START, StateGraph
class State(TypedDict):
text: str
steps: Annotated[list[str], operator.add] # reducer: updates are appended, not replaced
def strip(state):
return {"text": state["text"].strip(), "steps": ["strip"]} # return only what changes
graph = StateGraph(State)
graph.add_node("strip", strip)
graph.add_edge(START, "strip")
graph.add_conditional_edges("check", route) # route(state) returns a node name or END
app = graph.compile()
app.invoke({"text": " Hello ", "steps": []}) # the final state
- A node returns a partial update. Keys without a reducer are overwritten; a key annotated with a
reducer such as
operator.addcombines the old and new values. (operator.add(a, b)isa + bas a function, from the standard-libraryoperatormodule; for lists it concatenates.) add_conditional_edges(node, route)callsroute(state)after the node and follows the returned name, which may point back to an earlier node to form a loop.compile()checks the graph (unknown nodes, unreachable nodes) and returns a runnable withinvoke.app.get_graph().nodeslists the nodes; LangGraph can also draw the graph.- A loop that never ends stops with
GraphRecursionErrorafterrecursion_limitsteps (default 25).
Worked example
For " The Quick Brown Fox Jumps " and max_words=3: strip, lower, check (5 words, too long),
shorten, check (4), shorten, check (3, done). The final text is "the quick brown" and steps is
["strip", "lower", "shorten", "shorten"].
Common mistakes
- Mutating
stateinside a node instead of returning an update. - Forgetting the reducer, so each node's list replaces the previous one.
- A routing function that returns a name that is not a node.
Why this matters
The ReAct agent, orchestrator and guardrail steps that follow are LangGraph graphs; reading and drawing them is how you debug agents.
References
- Graph API (LangGraph docs) — LangChain (
S136) - Workflows and agents (LangGraph docs) — LangChain (
S139)