LangGraph: Stateful Agents
Beyond the loop. Why ReAct hits a glass ceiling.
1. The Limit of Loops
ReAct is a while loop.
while not done: act()
This works for "Search Google," but it fails for "Write Code -> Test -> Fix -> Deploy."
That requires a state machine. It requires Directed Graphs.
2. Nodes and Edges
LangGraph treats your agent as a graph.
- Nodes: Functions that do work (e.g.,
AgentNode,ToolNode,HumanNode). - Edges: Logic that decides where to go next (e.g.,
if tool_called: go_to_tools else: end).
3. State as First-Class Citizen
In LangChain chains, state is often implicit (hidden in memory buffers).
In LangGraph, you define a explicit StateSchema.
class AgentState(TypedDict):
input: str
chat_history: list[BaseMessage]
agent_outcome: str | None
intermediate_steps: list[tuple[AgentAction, str]]
Every node receives this State, modifies it, and passes it to the next node. It is Functional Programming applied to Agents.
4. Why This Wins
- Cyclic Graphs: You can code explicit loops.
Code -> Test -> Fail? -> Fix Code -> Test. - Persistence: You can pause the graph at any node, save specific state to a database, and resume days later.
- Human-in-the-Loop: A "Node" can be "Wait for User Approval." The graph literally sleeps until the API receives a POST request.
5. Summary
For simple chatbots, use ReAct. For complex workflows (Coding Assistants, Research Teams), use LangGraph. Structure beats prompt engineering every time.
Key Intuition: "Draw the flowchart. That is your Agent."