The enthusiasm around LLM agents has hit an uncomfortable wall. The classic loop pattern (invoke the model, check if it requests a tool, execute it, repeat) works in demos and crumbles the moment the task has three steps and a condition. Agents lose context, get stuck in infinite loops, can’t be resumed after failure and, when something goes wrong, the operator stares at a flat log wondering why the model decided what it decided. LangGraph[1] tackles that problem by treating the agent as an explicit state graph rather than a conversational black box.

Key takeaways

  • LangGraph replaces the ReAct loop with nodes, edges, and explicitly typed state.

  • Checkpointing on SQLite, Postgres, or Redis enables long-running agents and failure recovery.

  • Per-step streaming lets UIs show real-time progress without waiting for the final result.

  • Explicit loops with exit conditions prevent the infinite recursion that kills naive agents.

  • Not worth it for single-turn chatbots; yes for flows with non-trivial conditional logic or duration over a minute.

Why "simple" agents break

The hand-rolled ReAct-style agent is always the same template. A loop calls the LLM with message history, checks whether the response contains a tool call, executes it, appends the result, and starts again. LangChain’s own AgentExecutor acknowledges the problem by capping execution at 15 steps by default. It has 4 problems that scale badly:

  • No natural bound: if the model fixates on the same tool, you spin indefinitely until tokens run out.

  • No persistence: a network blip, a timeout, or a container restart sends you back to square one.

  • No observability: the "step" you’re on is implicit, living only in the length of the message history.

  • Impossible to unit-test: all the logic sits inside the same loop body.

Take a support agent that escalates to a human, a multi-step research task across more than one source, or an ETL process with intermediate validations. In flows like those, these 4 problems appear in the first week.

The LangGraph mental model

LangGraph changes the unit of composition. Instead of a loop, you define four things: a typed state dictionary, nodes as pure functions returning partial state updates, edges connecting nodes conditionally or unconditionally, and the graph as the compiled executable object.

from langgraph.graph import StateGraph, END

graph = StateGraph(AgentState)
graph.add_node("classify", classify)
graph.add_node("search", search)
graph.add_node("respond", respond)
graph.set_entry_point("classify")
graph.add_conditional_edges("classify", route_from_classify)
graph.add_edge("search", "respond")
graph.add_edge("respond", END)
app = graph.compile()

Each agent step is now an independent function with a clear input/output contract, testable in isolation and observable from outside. It fits naturally into structured RAG pipelines (see retrieval evaluation frameworks) where each retrieval step becomes a distinct node with a defined interface.

Finite state machine example with nodes, transitions and comments illustrating the graph structure LangGraph applies to LLM agents

The three features that do the work

Checkpointing: LangGraph persists graph state at every transition into SQLite, Postgres, or Redis. This enables long-running agents measured in hours or days, real cross-session memory, and recovery from process failures. It also enables the human-in-the-loop pattern where the graph pauses on an approval node while an operator decides.

Per-step streaming: the stream method emits one event per executed node with the partial state update. UIs can show the user what the agent is doing in real time.

Explicit loops with exit conditions: a node can point back to itself through a conditional edge distinguishing between "continue" and "terminate". It’s the same ReAct pattern, but with the stopping condition declared in one place rather than buried inside the loop body.

How it compares

Aspect AgentExecutor (LangChain) LangGraph CrewAI / AutoGen
Persistence Not native Native (checkpointer) Variable
Debugging Hard Per node Medium
Conditional logic Limited Declarative Role-based
Learning curve Low Medium Medium

Versus AgentExecutor, LangGraph wins on native persistence, per-node debugging, and the ability to model non-trivial conditional logic. Versus frameworks like CrewAI or AutoGen, LangGraph is lower level: it does not give you a predefined role model, it gives you primitives. The LangSmith[2] integration for observability tips the balance for teams already in the LangChain ecosystem. See also embeddings with nomic-embed-text to build the retrieval layer that feeds the search nodes.

When it pays off and when it doesn’t

LangGraph pays its cost when the flow has non-trivial conditional logic, agent duration exceeds a minute, human intervention is needed at intermediate steps, or production observability is a hard requirement. It does not pay for a single-turn chatbot, a one-shot tool call, or exploratory prototypes where building the graph is more ceremony than product.

Conclusion

LangGraph is one of those libraries that feel like a detour until you face your second serious production agent, and then it’s hard to go back. The underlying argument is organisational: the hand-rolled ReAct loop forces flow logic, error handling, persistence, and observability to coexist in the same code body. A state graph separates those concerns almost by design, and that value shows in every week of maintenance.

Frequently asked questions

How does LangGraph stop an agent from getting stuck in an infinite loop?

By declaring the stopping condition in one place: a node can point back to itself through a conditional edge that distinguishes between continue and terminate. It is the same ReAct pattern, but explicit, instead of the hand-rolled loop that spins indefinitely until tokens run out if the model fixates on the same tool. For reference, LangChain's AgentExecutor caps execution at 15 steps by default.

Can a LangGraph agent resume after a failure or wait for human approval?

Yes, through checkpointing: LangGraph persists graph state at every transition into SQLite, Postgres or Redis. A network blip, a timeout or a container restart no longer sends the agent back to square one. The same mechanism enables the human-in-the-loop pattern: the graph pauses on an approval node while an operator decides, and then continues from that point.

When is LangGraph not worth it?

For a single-turn chatbot, a one-shot tool call, or exploratory prototypes where building the graph is more ceremony than product. It pays off when the flow has non-trivial conditional logic, the agent runs for more than a minute, human intervention is needed at intermediate steps, or production observability is a hard requirement. If you never have to explain why the agent did something at a given step, you probably do not need it.

Sources

  1. LangGraph
  2. LangSmith