From ReAct to LangGraph: Designing Reliable LLM Agents
AgentFlow started as a textbook ReAct-pattern agent: reason, act, observe, repeat, until the model decides it has an answer. It worked, right up until I needed to debug why it chose one tool over another, or add a checkpoint where a human should approve a step before it executed.
The problem with implicit control flow
A standard ReAct loop hides its reasoning inside a single prompt-response cycle running in a while loop. That's fine for a linear happy path. It breaks down when you need:
- Conditional branching: "if the web search returns nothing useful, try Wikipedia before giving up."
- Observability: knowing exactly which state the agent was in when it made a decision.
- Human-in-the-loop checkpoints: pausing execution for approval before a costly or irreversible action.
None of these are exotic requirements. They're what separates a demo agent from one you'd trust in production.
Modelling reasoning as an explicit state machine
Rebuilding AgentFlow in LangGraph meant representing the agent's reasoning loop as an explicit graph of states and transitions, rather than an implicit loop buried in a prompt. Each node in the graph is a discrete step ("select tool," "execute tool," "evaluate result," "decide next action") with clear edges defining what happens next based on the outcome.
The payoff was immediate:
- Debugging became visual. I could trace exactly which node the agent was in and why it transitioned where it did.
- Adding a human checkpoint took one node, not a rewrite of the control flow.
- Conditional branches were declarative. No more nested if/else logic buried in prompt engineering.
Memory that doesn't bloat the context window
A subtle failure mode in long-running agents is memory bloat: every tool call and observation gets appended to the context, and by turn 15 you're burning tokens on stale information the model doesn't need anymore. I addressed this with a persistence layer that stores facts extracted from the conversation, not the raw transcript, so the agent retains what matters without dragging the full history along.
Takeaway
If your agent's logic fits comfortably in a single prompt, a ReAct loop is fine. The moment you need branches, checkpoints, or a debugging story you can explain to a teammate, model the reasoning as a graph. It costs you an afternoon of refactoring and saves you weeks of guessing why the agent did what it did.