An agent that answers questions about a single PDF takes about forty lines of code. An agent that files an insurance claim, pauses for a human to approve the payout, and picks up three days later without forgetting what it already checked takes something else entirely. That gap between a loop that works and a system you can operate is where LangGraph agents earn their keep.
LangGraph is a compact orchestration library from the LangChain team. It models an agent as a graph: nodes do work, edges decide what happens next, and a shared state object carries everything the run has learned so far. Simple idea. The consequences are large.
What a graph actually buys you
A while-loop agent is a single point of control. Every decision lives inside one prompt, and the model picks the next step by choosing a tool. That works fine until you need a step that isn’t a tool call, like a validation gate, a database write, or a wait for a human signature.
In a graph, those become nodes. You get an explicit map of how a request travels: parse intent, retrieve, draft, check against policy, escalate or send. You can read that diagram in a design review and spot the missing branch before it costs you a customer.
Debugging changes too. When a loop goes wrong you get a transcript and a shrug. When a graph goes wrong you get the exact node, its input state, and the edge it took. If you’re arriving from the tool-calling side of the ecosystem, it’s worth understanding the difference before you commit; this breakdown of what LangChain AI agents actually are and how to build one that holds up covers where plain agent executors stop being enough.
State is where these systems live or die
You define a typed state schema. Every node receives it, returns a partial update, and the runtime merges the update back in. The merge rule matters more than it looks.
Messages are the classic trap. If your reducer appends without trimming, turn thirty ships a 90,000-token prompt and latency triples. LangGraph ships an add-messages reducer that handles IDs and de-duplication, but you still need a summarisation step or a windowed history once conversations run long.
The other trap is putting things into state that can’t be serialised: live database connections, open file handles, SDK clients with sockets inside them. Checkpointing fails, usually at 2am, usually on the thread belonging to your most important customer. Keep state to plain data and rebuild clients inside nodes. The mechanics of reducers, thread state and persistence get a fuller treatment in this walkthrough of LangGraph in practice, from state and control through to memory.
Checkpointers turn a run into a record
Attach a checkpointer and every step is persisted against a thread ID. That one feature unlocks a surprising amount:
- Resume after a crash or a mid-deploy restart, from the last completed node
- Conversation memory across sessions, keyed by user or ticket
- Time travel, forking from step 12 to test a new prompt against identical history
- Audit trails, because you can show exactly what the agent saw at each decision
Postgres and SQLite are the usual production backends. Watch storage growth anyway. A chatty agent with large state and no thread pruning adds gigabytes quietly over a quarter. Set a retention policy in week one, not month six.
Control flow you can read and edit
Conditional edges are just functions. They take state and return the name of the next node. Routing becomes testable Python instead of a prompt you hope behaves.
Human-in-the-loop is the piece people underestimate. A node can call interrupt, which serialises state and stops the run. Approval arrives later, sometimes from a completely different process, and execution continues on the same thread. For anything that moves money or sends external email, this is the pattern that gets you past a security review.
Multi-agent setups that don’t become a swamp
The supervisor pattern is the one that survives contact with reality: a router node picks one of several specialist subgraphs, each with its own state and tools, then hands control back. Clean boundaries, separate prompts, separate evals.
What doesn’t survive is free-form agent-to-agent chat. Two agents discussing a task will happily burn 40,000 tokens agreeing with each other. If you find yourself writing a third agent to moderate the first two, the architecture is telling you something.
When a graph is overkill
Plenty of tasks don’t need one. A single retrieval call plus a summary is a function, not an agent. Two steps with no branches means a new dependency and a mental model for nothing. Most teams should start with a plain instrumented loop and see where it hurts, which is exactly the path laid out in this guide to building AI agents with Python from a 60-line loop upward.
The parts that bite in production
- Silent recursion. Set the recursion limit to something honest. Twenty-five is generous for most flows, and hitting it should page someone rather than vanish into a log.
- Retries that replay supersteps. A node failing after its sibling succeeded may re-run the sibling. Keep side effects idempotent or push them to the last node in the step.
- Streaming confusion. Token-level and state-level streaming are different modes. Mixing them up gives you a UI that renders every update twice.
- Routing drift. Log each edge decision with its inputs. When quality drops, that log is the difference between a two-hour fix and a two-week mystery.
- Cost creep. A graph makes adding steps easy, and each step is usually a model call. Add up per-run token spend before you scale traffic.
Testing a graph without testing your patience
Unit-test nodes as pure functions. Feed state in, assert on the partial update that comes back. Then run a handful of trajectory evals: full graph runs against recorded inputs, scored on the final state and the path taken, not just the wording of the answer.
Trajectory matters. A graph can reach the right answer by a ridiculous route, calling six tools it never needed, and no answer-quality score will catch that. Tracing helps enormously; LangSmith is the default, though OpenTelemetry exporters work fine if you already run an observability stack.
Once you start comparing runtimes and hosting, the questions stop being about features and start being about isolation, load behaviour and what happens at three times your current traffic, which is the same bar used in this comparison of enterprise AI agents under real production load. Self-hosting the runtime is genuinely viable, and the trade-offs are laid out clearly in this look at open source AI agents, what you get and where they break.
A realistic first build
Start with one graph of four nodes: classify, retrieve, act, respond. Add a Postgres checkpointer. Wire a single interrupt before the act node so a human sees the plan before anything external happens. Then measure three things for a week: completion rate, median cost per run, and how often classify routes wrong.
That last number is usually the surprise. Routing accuracy of 88% sounds respectable until you notice that one request in eight takes the wrong path and the downstream nodes can’t recover from it. Fixing the router, with better few-shot examples, a narrower label set, or a cheap model constrained to a strict output schema, tends to move overall quality further than upgrading your main model to a bigger one.
After that, add nodes only where you have evidence you need them. The graph is a map of your process, and a map drawn from guesses is worse than no map at all.

