How LangChain & LangGraph Work, Visually

One coffee shop, two libraries: prompts, chains, tools, memory, graphs, checkpoints, interrupts, and the ten questions that decide production

Pranjal Rawat

Two libraries, one idea

A model call is a pure function: messages in, message out. Everything an application needs beyond that one call is plumbing, and every team was rebuilding the same plumbing by hand.

LangChain standardizes one call: prompts, parsing, tools, memory. LangGraph choreographs many calls: state, branching, persistence, interruption.

One call vs. many calls

LangChain, one composed call

prompt | model | parser, plus tools and memory around it. Everything happens inside a single .invoke(); nothing persists once it returns.

LangGraph, many calls, persistent

Nodes, edges, and state threaded across an entire run: branches, cycles, checkpoints, and interrupts that survive a restart.

Meet Beanline Coffee

Every figure ahead is a photograph of real code running one small coffee shop: a real menu, a real stock room with counts that go down, a real till with a balance that moves, and a barista bot built up from raw calls to a full graph.

scripted model a fixed list of replies, so every run replays exactly Beanline's bot real langchain + langgraph: prompts, tools, graphs, checkpoints the shop menu: latte $4.50, sizes, extras stock room: oat milk, 2 left till: $200.00 and counting all mutable, all asserted The model's words are scripted. Everything else executes. Prompts really render, parsers really raise, tools really check stock, graphs really pause and resume. Nothing is a mockup.

Ten questions before you ship an agent

The APIs are the easy part. Practitioners converge on the same checklist, and the four in amber are the ones teams skip.

1. Does this need an agent at all? or a pipeline, a classifier, one structured call 2. What exactly counts as success? the reservation exists, not "sounds booked" 3. What can it see and do? tools with typed args, real evidence back 4. Which decisions stay deterministic? the model routes; the till does arithmetic 5. What is the authoritative state? a schema you can draw, not a transcript 6. What is the simplest graph that works? every extra node must earn its keep 7. When does it stop, retry, escalate? bounded loops, policies per failure class 8. Can it resume without double-charging? replayed nodes must not repeat side effects 9. What authority does it have? high-blast-radius actions wait for a human 10. What does each model call buy? quality vs cost, measured call by call This deck answers all ten, with running code

Synthesis: OpenAI, A practical guide to building agents · Anthropic, Building effective agents · Anthropic, Demystifying evals · LangChain persistence & interrupt docs · AutoGen termination docs

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Gluing Model Calls by Hand

Part 1 · LangChain: one call, composed

Everything in Part 1 is about a single model call and the plumbing around it: what goes in, what comes out, and who remembers.

LangChain composes one call. Prompts, parsers, tools, and memory all live inside a single .invoke().

Message

A message is LangChain’s typed unit of conversation: a role (system, human, ai, or tool) plus content. Chains pass a list of messages, never a bare string.

The Conversation Is a Typed List

The Conversation Is a Typed List

The Conversation Is a Typed List

The Conversation Is a Typed List

The Conversation Is a Typed List

The Conversation Is a Typed List

Prompt Template

A prompt template is a function from a dict of inputs to a rendered prompt. It fills variables into a fixed structure and returns a typed ChatPromptValue, ready for a model.

Prompts Are Functions

Prompts Are Functions

Prompts Are Functions

Prompts Are Functions

Prompts Are Functions

Prompts Are Functions

The pipe changes the payload’s type

One order, four shapes. LCEL’s | is function composition, and the thing flowing through really changes type at every hop.

{"name": "Maya", "input": "..."} DICT prompt [system, human] rendered, typed CHATPROMPTVALUE model role: ai + tool_calls, meta AIMESSAGE parser "One mocha, $5.00" STR prompt | model | parser Composable because uniform: every stage answers .invoke, .batch and .stream

LCEL Pipe

The LCEL pipe (|) composes runnables into a pipeline, prompt | model | parser. Every stage answers .invoke / .batch / .stream, so pipes compose uniformly even as the payload’s type changes at each hop.

Chains Are Pipes

Chains Are Pipes

Chains Are Pipes

Chains Are Pipes

Chains Are Pipes

Chains Are Pipes

Chains Are Pipes

Structured Output

Structured output binds a schema, an OrderItem or other Pydantic class, to the model call, so the reply parses straight into a typed object instead of prose you’d have to regex apart.

From Prose to Objects

From Prose to Objects

From Prose to Objects

From Prose to Objects

From Prose to Objects

From Prose to Objects

From Prose to Objects

Tool Round Trip

A tool round trip: the model emits a tool_calls request, your code runs the real function (check stock, price an order), and the result goes back into the message list as a tool message for the next model call.

Tools Are Round Trips

Tools Are Round Trips

Tools Are Round Trips

Tools Are Round Trips

Tools Are Round Trips

Tools Are Round Trips

Memory Is Yours, Not the Model’s

Memory Is Yours, Not the Model’s

Memory Is Yours, Not the Model’s

Memory Is Yours, Not the Model’s

Memory Is Yours, Not the Model’s

The Same Answer, Sooner

The Same Answer, Sooner

The Same Answer, Sooner

The Same Answer, Sooner

The Same Answer, Sooner

The Same Answer, Sooner

Part 2 · LangGraph: many calls, choreographed

A pipe points one way. A real conversation loops, branches, pauses, and survives a restart. LangGraph’s move is to make your control flow an object: nodes, edges, and state you can draw, checkpoint, and interrupt.

LangChain composes one call; LangGraph choreographs many. The difference is state that persists across turns, not just a longer pipe.

a chain: one direction, no memory of place take_order check_stock confirm suggest_alt a graph: the back-edge is a real, drawable edge

Chains Can’t Loop

Chains Can’t Loop

Chains Can’t Loop

Chains Can’t Loop

Chains Can’t Loop

Chains Can’t Loop

Chains Can’t Loop

Pitfall: Chains Can’t Loop

A LangChain pipe (|) runs strictly one direction; there is no way to route back to an earlier stage. The moment a task needs to retry, branch, or loop, it needs a graph, not a longer chain.

State, Defined

State is the schema LangGraph threads through every node, one object every node reads and writes, so the shape of a run is a diagram you can draw, not an implicit transcript.

A reducer is the function attached to a state field that says how updates combine, replace, append, sum, so two nodes touching the same field don’t silently clobber each other.

State and Reducers

State and Reducers

State and Reducers

State and Reducers

State and Reducers

State and Reducers

State and Reducers

Graphs Are Data

Graphs Are Data

Graphs Are Data

Graphs Are Data

Graphs Are Data

Graphs Are Data

Graphs Are Data

Conditional Edge

A conditional edge routes to a different next node based on the current state. The branch, and the back-edge that makes a loop possible, are real, drawable graph edges, not hidden if statements inside a Python loop.

Branching on Real State

Branching on Real State

Branching on Real State

Branching on Real State

Branching on Real State

Branching on Real State

Branching on Real State

Branching on Real State

ReAct, in five lines

The famous agent loop is small enough to memorize, and LangGraph ships it as a two-node graph you have already built by hand.

THE PSEUDOCODE while True: reply = model(messages) if not reply.tool_calls: return reply messages += run(reply.tool_calls) THE GRAPH model tools no tool_calls: END create_agent(model, tools) is this exact shape

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

The Agent Is a Two-Node Cycle

Checkpoint

A checkpoint is a saved snapshot of a graph’s state after each step, keyed to a thread id. A run can be walked away from and resumed exactly where it left off.

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Walk Away, Come Back

Part 3 · The questions that decide production

Everything so far was mechanism. What separates a demo from a system is a set of decisions, and four of them are chronically skipped: what counts as success, where state lives, when to stop, and what happens on replay.

Success is a property of the world, not the transcript. A reply that “sounds booked” is not a reservation that exists.

OpenAI, A practical guide to building agents · Anthropic, Demystifying evals for AI agents · LangChain interrupt docs

Do You Need an Agent at All?

Do You Need an Agent at All?

Do You Need an Agent at All?

Do You Need an Agent at All?

Do You Need an Agent at All?

Do You Need an Agent at All?

Do You Need an Agent at All?

The Decision, as Three Shapes

Straight chain

prompt | model | parser, one fixed path. Right when the task is well-specified and every input takes the same route.

Router

One call classifies the request, then each branch is its own fixed path. Right when inputs split into a few known kinds.

Agent loop

create_agent(model, tools): the model decides how many calls to make and which tools to call, in a loop. Right only when the answer depends on something the code can’t know in advance, like live stock.

Define Done, Verifiably

Define Done, Verifiably

Define Done, Verifiably

Define Done, Verifiably

Define Done, Verifiably

Define Done, Verifiably

Define Done, Verifiably

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Stop, Retry, Escalate

Interrupt

interrupt() is called inside a node and pauses the graph right there, handing control to a human. On Command(resume=...) that node runs again from its start with the supplied value, so the graph continues from the checkpoint instead of restarting the whole run.

Approve Before You Act

Approve Before You Act

Approve Before You Act

Approve Before You Act

Approve Before You Act

Approve Before You Act

Approve Before You Act

Approve Before You Act

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Resume Without Double-Charging

Pitfall: Double-Charging on Resume

Resuming a graph with no checkpointer replays every node from the start, side effects included, so Beanline’s till gets charged twice for one latte. A checkpointer makes a resume skip completed steps instead of re-running them.

The Whole Shop

Every abstraction, one order

Maya’s large oat-milk latte, one last time, touching every piece the deck introduced.

ONE CALL (LANGCHAIN) prompt: menu + {input} model -> Order object tools: check_stock, price MANY CALLS (LANGGRAPH) take_order check_stock confirm human gate THE PRODUCTION LAYER checkpointer: thread per customer recursion_limit + retry policy interrupt() before the till moves THE REAL WORLD stock: oat milk 2 -> 1 · till: $200.00 -> $206.25 every number asserted by an oracle, every run Success is a property of the world, not the transcript

Ten questions, answered

# The question Where the deck answered it
1 Need an agent at all? Do You Need an Agent at All?
2 What counts as success? Define Done, Verifiably
3 What can it see and do? Tools Are Round Trips
4 Which decisions stay code? Graphs Are Data (the price node has no LLM)
5 Authoritative state? State and Reducers · Walk Away, Come Back
6 Simplest graph that works? Chains Can’t Loop · Do You Need an Agent at All?
7 Stop, retry, escalate? Stop, Retry, Escalate
8 Replay-safe side effects? Resume Without Double-Charging
9 Authority and approval? Approve Before You Act
10 What does each call buy? Do You Need an Agent at All? (the call-count scorecard)

Pydantic AI

Pydantic AI is a typed single-agent framework: Agent(model, output_type=SomeModel) runs one call and hands back a real, validated instance of that model. One pip install, no graph, no checkpointer.

Instructor

Instructor patches any OpenAI-compatible client so .create() returns a validated Pydantic object instead of raw JSON text, the smallest possible step from prose to a typed object.

The Lighter Workhorses

The Lighter Workhorses

The Lighter Workhorses

The Lighter Workhorses

The Lighter Workhorses

Pick the lightest tool that does the job: raw SDK for one call, Pydantic AI for one typed agent, LangGraph when you need durable multi-step.

Three Ways to Get a Typed Order

Raw SDK

One call, hand-parsed JSON, no framework dependency. Right when there is exactly one call and you’re willing to parse the reply yourself.

Pydantic AI

Agent(model, output_type=Order), one pip install. Right when one call needs a validated typed result and nothing more.

LangGraph

Nodes, edges, a checkpointer. Right when the job is many calls, branching, or must resume without re-running side effects.

References

Guides OpenAI, A practical guide to building agents · Anthropic, Building effective agents · Anthropic, Demystifying evals for AI agents

LangChain / LangGraph docs LangGraph persistence · Interrupts · LangChain messages, runnables, tools

Also drawn on AutoGen, termination · 12-factor agents

Siblings How Git Works, Visually · How RAG Works, Visually · How Inference & Serving Work, Visually · How Evals & Observability Work, Visually · How Agentic Harnesses Work, Visually

Every figure in this deck: a real run of langchain 1.3 / langgraph 1.2 at Beanline Coffee, regenerable with build/regen_all.py · versions pinned in build/requirements.txt