Guides · Series · 8 parts
Building Real-World Agentic AI Systems with LangGraph
An eight-part guide to the part of agent engineering nobody demos: making the thing survive a restart, a concurrent write, a bad tool call, and a Tuesday deploy.
Orchestration is the layer everyone skips
The gap between an agent demo and an agent in production is not prompt quality. It is that a demo runs once, on a happy path, watched by the person who built it. Production runs it ten thousand times, unattended, while the database times out, a deploy restarts the process mid-run, two branches write the same key, and a customer asks for something the tool schema does not cover.
A raw while loop around an LLM call handles none of that. It has no memory of where it was when it died, no way to replay what happened, and no boundary between "retry this, it is cheap" and "do not retry this, it moves money." Most production agent incidents are not reasoning failures. They are state-management failures wearing a reasoning failure’s clothes: the agent lost its place, re-ran a step it had already completed, and reported success.
Three failure modes account for most of it. Hallucinated control flow — the model decides what happens next, so what happens next is non-deterministic and untestable. Lost state — the run’s progress lives in a Python variable, so a crash is a total loss. No recovery — a tool raises, the exception is swallowed, and the model narrates around the gap instead of failing loudly.
The control/autonomy dial
There are two live positions in this argument and both are half right. The 2023 thesis says an agent is a control problem, not a prompt problem: constrain it with state machines, fixed routing, gates, and validation. The 2026 counter-trend says give a strong model good tools, memory, and a harness, then get out of the way.
Treating that as a binary is the mistake. It is a dial, and the setting is determined by one thing: the cost of being wrong. Drafting a summary someone will read before acting on it? Turn autonomy up; the blast radius is a wasted minute. Issuing a refund, modifying a production record, sending mail to a customer? Turn structure up, because the model being confidently wrong costs real money and the mistake is not reversible by apologising.
Maxing the dial in either direction is what produces the two recognisable kinds of bad agent system: the one so constrained it is a state machine with an expensive autocomplete bolted on, and the one so unconstrained nobody can say what it will do tomorrow. Tuning it deliberately, per decision rather than per system, is the skill.
Why LangGraph, specifically
LangGraph is a stateful, durable runtime rather than a prompt-chaining library, and that distinction is the whole point. State is explicit and typed, so you can see it, test it, and decide how concurrent writes merge. Control flow lives on edges, so routing is inspectable rather than buried in a function body. Checkpointing is built in, so a restart resumes at the last completed step rather than from scratch. And interrupts are first-class, so a human can approve a step without you hand-rolling a queue.
None of that makes the model more reliable. It makes the system around the model reliable enough that the model’s unreliability becomes something you can bound, observe, and recover from. That is the trade this series is about.
The series targets LangGraph 1.x and LangChain 1.x, matching the book’s tested version matrix. Where an API is beta or version-gated, that is called out inline rather than glossed — the 0.x-to-1.x churn burned enough people already.
Which part solves my problem
The series reads in order, but if something is already broken, start here.
- “My agent loops forever, or picks the wrong tool and confidently reports success.”Part 1 →
- “Two branches write the same state key and one silently clobbers the other.”Part 2 →
- “I am hand-parsing provider-specific message formats, or maintaining integrations MCP would give me.”Part 3 →
- “The process restarts mid-run and everything is gone — or worse, the refund fires twice.”Part 4 →
- “Costs climb every turn because history grows without bound, and the agent still forgets the user.”Part 5 →
- “One agent is doing too many jobs badly and I am wondering whether to split it up.”Part 6 →
- “It works on my machine and I have no idea what it does in production.”Part 7 →
- “I need to justify this stack — or decide whether LangGraph is the wrong tool here.”Part 8 →
The series
8 of 8 published
LangGraph or a While Loop? You Already Have a Runtime
A checkpointer makes the run's past readable and leaves its next-step space exactly as wide as it was. Production agents fail in that gap.
LangGraph Reducers Are a Concurrency Policy
Rename a node and the answer changes. The code that decides how concurrent writes merge lives inside a type annotation, appears on no diagram, and the docs decline to guarantee its order.
LangGraph create_agent: The Graph Isn't the Runtime
Bind three tools or three hundred - the rendered diagram is byte-identical. The constraints that actually decide the next step live in middleware nobody draws.
LangGraph Checkpoints Restore Your Limits, Not Just Your State
Every bound the runtime gives you is re-derived from checkpointed state on entry. Resume, retry, or just take a second turn, and it arrives at full - by working exactly as designed.
LangGraph Compaction Deletes the View, Not the Record
Your summarizer removed the message from state. Eighteen checkpoints on disk still have it, and an ordinary fork puts it back.
LangGraph's recursion_limit Bounds Depth, Not Width
A limit of 4 let 1,000 workers run. The bound is real, it is enforced, and it counts the one axis the runtime knows how to count.
LangGraph Evals Test the Answer, Not the Thread
One approval decision fired the charge three times. Both output assertions passed, and every checkpoint on the thread recorded nothing about it.
LangGraph Names the Guarantee, Not the Unit
Seven parts of measurement found one recurring shape: the bound is real, it is correctly enforced, and it is scoped to something you did not assume.
The companion code
Every part builds on the same project the book builds: Atlas, a customer-support agent that starts as a deliberately fragile loop and ends up durable, observable, and evaluated. It ships as the atlas/ Python package, with seeded, mockable backends — the knowledge base, ticket API, and research corpus all run locally, with no external accounts to sign up for.
View the companion repository on GitHub →Other guide series
Harness Engineering
AI systems do not fail at the model layer. They fail in the code around it — and that code is a designable layer with its own architecture.
RAG Engineering
Most RAG failures happen upstream of the LLM, accumulate invisibly, and only surface as an incident. This series names each one.
Claude Code Playbook
Claude Code has four layers — context, skills, subagents, hooks — and the variable that decides which one you need is enforceability, not capability.
AI Control Plane
A fleet of agents needs a layer that is not itself an agent — observability, policy, orchestration, versioning, cost, and audit, built as infrastructure.
Agentic AI in the Data Center
In physical infrastructure, an agent’s autonomy is capped by reversibility and jurisdiction — not by how good the model is.
Codebase to Architecture Doc
A three-pass methodology for compressing any codebase into validated diagrams and decisions — and then a LangGraph pipeline that runs it for you.


