Zenaique

When should a team graduate from LangChain's AgentExecutor to a LangGraph StateGraph?

Short answer·Hard·4.0 · 0·~3 min·Asked atCohereJane StreetUipath
Attempt it

Your team is running an agent in production on `AgentExecutor`. At what point should you graduate to a `LangGraph StateGraph`, and what specifically does the StateGraph give you that the executor cannot?

Free · 2 AI evals / day
TL;DR

Graduate when you need debuggability, durable state, or human in the loop approval, StateGraph makes the hidden AgentExecutor while-loop into an inspectable, checkpointable, interruptible graph.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Imagine driving with a closed-eyes navigation app vs an open map. AgentExecutor is the closed app, it gets you there, but if it takes a weird detour you cannot see which turn it picked or why, and if your phone dies mid-route you start over. StateGraph is the open map: every turn is a visible step, you can pause the trip, hand the wheel to a passenger for one decision, and even rewind to a previous junction and try a different road. For a quick errand the closed app is fine. For a complex delivery route with handoffs and recovery requirements, you want the map.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

The question "when should we move off AgentExecutor" is one of the most common production decisions for teams building LangChain agents. Answered well, it sounds like a clear engineering tradeoff. Answered badly, it sounds like cargo-culting the newer API.

The honest answer is trigger-based. AgentExecutor is the right tool below a complexity threshold; LangGraph StateGraph is the right tool above it. The threshold is defined by three concrete production needs the executor cannot natively serve. This explanation walks each trigger, names the StateGraph primitive that addresses it, and finishes with the honest tradeoffs of the migration.

What `AgentExecutor` hides, and why that matters

AgentExecutor runs a tool-using agent as an internal while loop. You hand it an LLM, a list of tools, and a prompt; it asks the LLM what to do next, parses the response, invokes the tool, appends the result, and loops until the LLM signals it is done. The implementation is a single Runnable invocation: one call into the executor, one return.

This abstraction is what makes the executor so good for prototypes. You don't write the loop, you don't manage state, you don't worry about turn limits. It just runs. In a notebook or a thin demo, this is exactly the right ergonomics.

The abstraction breaks in production because the loop's internal state is opaque to anything outside the invocation. The Python while is not pausable, not checkpointable, not inspectable mid-flight. Logging helps you see what happened after the fact. None of it lets you intervene during the loop, recover from a crash mid-loop, or step back to a prior iteration and try again.

Trigger 1: crash recovery via durable state
Trigger 2: human in the loop on irreversible actions
Trigger 3: inspectable, replayable control flow
The honest tradeoff: when to NOT migrate
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.

Real products, models, and research that use this idea.

  • Replit's Agent migrated from a custom executor to LangGraph because IDE-disconnect and reconnect required durable session state across restarts.
  • Norway's tax authority pilot used LangGraph `interrupt_before` to gate citizen-facing actions on a human caseworker's approval.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWalk through how a `PostgresSaver` checkpointer enables crash recovery in a real deployment.
A

On graph.compile(checkpointer=PostgresSaver(...)), every node invocation persists a checkpoint keyed by thread_id (and a step counter). On crash, re-invoke with the same thread_id and no input (graph.invoke(None, config)); LangGraph rehydrates state from the latest checkpoint and resumes execution from the next node. The Postgres tables hold the canonical state, so multiple workers can pick up the thread.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Graduating to LangGraph for a 50-line agent that calls one tool. The verbosity is overhead unless you have a concrete trigger like crash recovery or HITL.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Three production triggers that force a move from AgentExecutor to StateGraph.

  • What a StateGraph checkpointer actually persists and how resume works.

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Design a sensible migration…
Short answer·Hard