Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

LangGraph blueprint · Banks & Regulated industries

Stateful graph with human review

Nodes, conditional edges and a checkpointer turn an agent into a graph that can loop, pause and resume.

Steps
6
Subjective questions
32
Objective questions
32

The problem and the outcome

Problem: Fully autonomous agents are too risky where one wrong action is costly.

Outcome: Agents that loop and use tools, but pause for a person before risky steps.

Architecture

STARTNode: agentcalls the model01Conditionaledge02Node: toolsruns tool calls03interrupt()human review04END06Checkpointerstate per thread05tool callsloop backriskyapproveddonesave

How it works, step by step

  1. State is a typed object (the messages plus your own fields) that every node reads and updates.
  2. A conditional edge reads the state and picks the next node.
  3. The tools node runs the requested calls and hands control back: a cycle, not a chain.
  4. interrupt() pauses the graph so a person can approve or edit before a risky step.
  5. A checkpointer saves state after every step for each thread, so a run can pause, resume or rewind.
  6. The graph reaches END when the router finds no more work.

Tech stack

  • LangGraph StateGraph
  • Checkpointer (InMemorySaver for dev, PostgresSaver in production)
  • interrupt() and Command(resume=…)
  • thread_id per conversation
  • LangSmith tracing

Key design decisions

  • Model the agent as explicit nodes and conditional edges, so loops and branches are visible and testable.
  • A checkpointer saves state after every step, so a run can pause for a person and resume hours later.
  • Pause with interrupt() before any irreversible action, and resume with the reviewer's decision.

Common mistakes

  • Using an in-memory checkpointer in production, so restarts lose every paused run.
  • Side effects before the interrupt in the same node, which run again when the node resumes.
  • Reusing one thread_id for different users and mixing their state.

What to measure

  • Runs paused vs. approved vs. rejected
  • Time waiting for human review
  • Resume success rate

Most-asked interview questions

Subjective questions 32

1What does LangGraph add over a simple LangChain agent?Asked almost every time

Explicit control: you define state, nodes and edges, including cycles and branches. It adds durable execution through checkpointers, human-in-the-loop pauses, streaming of intermediate steps, time travel to earlier states, and multi-agent patterns, while still letting a node call any model or tool.

2How does human-in-the-loop work in LangGraph?Asked almost every time

A node calls interrupt() with a payload, such as the proposed action. The graph saves its state through the checkpointer and returns the interrupt to the caller. Later, the app invokes the graph again with the same thread_id and Command(resume=value), and execution continues from that node with the reviewer's answer.

3Design a LangGraph workflow where a manager approves refunds above a threshold.Asked almost every time

Nodes: classify the request, gather order data with tools, compute the refund, then a conditional edge routes amounts above the threshold to an approval node that calls interrupt() with the proposed refund. The graph pauses with its state checkpointed; the manager's decision resumes it via Command(resume=...), and the graph either issues the refund or explains the denial.

4What patterns of human-in-the-loop does LangGraph support?Asked almost every time

Approve or reject an action, edit the proposed state or tool arguments before continuing, review and edit generated output, and answer a question the agent asks. All use interrupt() to pause and Command(resume=...) or update_state to continue.

5How do you make interrupts safe in production?Asked almost every time

Use a durable checkpointer (Postgres), keep code before interrupt() idempotent because the node reruns on resume, include enough context in the interrupt payload for the reviewer, set timeouts and escalation for unanswered reviews, and audit who approved what.

6What happens to code inside a node when a graph resumes after interrupt()?Asked almost every time

The node restarts from the beginning of its function, so any code before the interrupt() call runs again. The value passed in Command(resume=...) becomes the return value of interrupt(). That is why side effects before an interrupt must be idempotent, placed after it, or moved to a separate node.

Sourced from Docs by LangChain (MCP)

7Why must the node be safe to re-run after an interrupt?Very often asked

When resumed, the node runs again from its start, and interrupt() returns the resume value this time. Any code before the interrupt, such as an API call, runs twice, so put side effects after the interrupt or in a separate node, or make them idempotent.

8How does the UI find and display pending approvals?Very often asked

When a run hits an interrupt, the stream or invoke result includes the interrupt payload; the app stores the thread ID and payload in an approvals queue, shows it to reviewers, and sends their decision back to resume that thread.

9How do you let a reviewer edit tool arguments?Very often asked

Interrupt before the tool runs with the proposed tool call, let the reviewer modify arguments, then resume with the edited call (or update the state's last AI message) so the tool executes with corrected values.

10Static vs. dynamic interrupts: what is the difference?Very often asked

Static interrupts (interrupt_before / interrupt_after at compile time) pause at fixed nodes and are mainly for debugging. Dynamic interrupt() calls inside nodes pause conditionally with a payload, which is the recommended production approach.

11How do you handle a reviewer who never responds?Very often asked

Track pending interrupts with timestamps, send reminders, escalate to another reviewer after a deadline, or resume with a safe default (reject or hold) recorded as automatic.

12How do you resume a graph from a different server or after a deploy?Very often asked

Because state is in the checkpointer keyed by thread_id, any instance can load it and resume with the same compiled graph; keep graph structure backward compatible so old checkpoints still match.

13How do multiple interrupts in parallel branches work?Very often asked

Each paused branch produces its own interrupt with an ID; the resume value can map interrupt IDs to answers so all pending questions are answered in one resume.

14How do you audit human decisions?Very often asked

Store each interrupt payload, the reviewer, their decision and timestamp alongside the checkpoint history, so you can reconstruct why the graph took each path.

15Which thread must you use when resuming an interrupted graph, and why?Very often asked

The same thread ID used when the interrupt happened. The thread ID is the durable pointer to the saved checkpoint, so resuming on another thread would start fresh instead of continuing the paused run.

Sourced from Docs by LangChain (MCP)

16Why is Command(resume=...) the only Command you should pass as graph input?Very often asked

Resume is the Command pattern designed as input to invoke or stream. The other Command parameters, update, goto and graph, are meant to be returned from node functions. To continue a conversation you pass a normal input object, not Command(update=...).

Sourced from Docs by LangChain (MCP)

17What is time travel used for in review workflows?Often asked

You can inspect past checkpoints, fork from an earlier state with corrections and rerun, which helps debug wrong decisions or replay a run after fixing a tool.

18How do you design the approval payload?Often asked

Include what action is proposed, why, the key data (amount, customer, policy rule), risk flags and the options available, so reviewers decide quickly without opening other systems.

19How do you prevent the same action executing twice after resume?Often asked

Put side effects after the interrupt in a separate node or make them idempotent with keys, because nodes rerun from the start on resume.

20How do you test human-in-the-loop graphs?Often asked

Run the graph to the interrupt in tests with an in-memory checkpointer, assert the payload, then resume with approve, edit and reject values and assert each path.

21When should a human be in the loop at all?Often asked

For irreversible, costly, regulated or low-confidence actions, and while a new automation earns trust; remove reviews for low-risk paths once metrics show reliable behaviour.

22How do you stream progress while waiting for a human?Often asked

Stream updates up to the interrupt, then show the pending review state in the UI; after resume, continue streaming the remaining steps on the same thread.

23How does LangGraph Platform help with human review?Often asked

It provides persistence, thread and run APIs, and a UI (Studio) to inspect interrupts and resume runs, so you do not build the infrastructure yourself.

24How do you limit what reviewers can change?Often asked

Validate edited values against schemas and business rules in the node after resume, and reject edits beyond a reviewer's authority level.

25How do you safely change a graph's state schema while some threads are paused for review?Often asked

Add new state fields as optional so old checkpoints still validate, treat removals as deprecations kept for at least one drain cycle, rename by adding the new field alongside the old one before removing it, and spot-check existing threads with time travel and get_state in staging.

Sourced from Docs by LangChain (MCP)

26Can you add or remove nodes while threads are interrupted?Often asked

Yes. Graph structure can change without breaking resume for existing threads, because resumed runs use the saved state and execute whatever graph you compile now. Stricter rules apply only to the order of tasks and interrupt calls inside a node.

Sourced from Docs by LangChain (MCP)

27How do you resume an interrupted run on a deployed Agent Server?Often asked

Call the runs API on the same thread with a command containing the resume value, for example client.runs.wait(thread_id, assistant_id, command=Command(resume=value)) in the Python SDK. The interrupt payload is visible earlier in the run result under __interrupt__.

Sourced from Docs by LangChain (MCP)

28How do you measure the cost of human review?Sometimes asked

Track review volume, time to decision, approval and edit rates, and how often reviewers override the agent, to decide which reviews can be reduced.

29What is the difference between interrupt and a regular input node?Sometimes asked

A regular node expects input at the start of a run; interrupt() pauses midway with saved state and can be resumed later, possibly by a different person.

30Can you add a human review step to a create_agent agent?Sometimes asked

Yes, using the human-in-the-loop middleware that interrupts before chosen tools, configured with which decisions (approve, edit, reject) are allowed.

31What happens to state when the reviewer rejects an action?Sometimes asked

The resume value records the rejection; the graph routes to a node that informs the user or tries an alternative, and the rejected proposal remains in history for audit.

32What does the human-in-the-loop middleware add to a create_agent agent?Sometimes asked

It pauses execution for human approval of tool calls, so a reviewer can approve, edit or reject a proposed call before it runs, without building a custom graph.

Sourced from Docs by LangChain (MCP)

Objective questions 32

1What does a LangGraph checkpointer store?Asked almost every time
  1. AOnly the final answer
  2. BThe vector index
  3. CModel weights
  4. DThe graph state after each step, per threadCorrect answer

Why: Saved state per thread_id is what enables pause/resume, memory and time travel.

2What must be safe to re-run after an interrupt?Asked almost every time
  1. AThe UI
  2. BCode before interrupt() in the nodeCorrect answer
  3. CCode in other graphs
  4. DThe checkpointer

Why: The node restarts on resume.

3Which checkpointer suits production human review?Asked almost every time
  1. AA durable one such as PostgresCorrect answer
  2. BIn-memory only
  3. CA local file without backups
  4. DNone

Why: Pauses may last days.

4How do you continue a paused graph with the reviewer's decision?Asked almost every time
  1. AA new thread
  2. BEditing the code
  3. CCommand(resume=decision)Correct answer
  4. Dgraph.restart()

Why: Resume uses the same thread_id.

5On resume, a node that called interrupt()…Asked almost every time
  1. AIs skipped
  2. BRuns twice in parallel
  3. CRe-runs from the start of its functionCorrect answer
  4. DContinues from the exact line

Why: Code before the interrupt executes again.

Sourced from Docs by LangChain (MCP)

6Which call resumes a graph paused by interrupt()?Very often asked
  1. ACalling the tool directly
  2. Bgraph.restart()
  3. CInvoking again with Command(resume=…) and the same thread_idCorrect answer
  4. DDeleting the checkpoint

Why: Command(resume=…) passes the human's answer back into the paused node.

7Static interrupt_before is mainly for…Very often asked
  1. ACaching
  2. BDebugging at fixed nodesCorrect answer
  3. CProduction approvals
  4. DStreaming tokens

Why: Dynamic interrupt() is preferred.

8Where should side effects go relative to the interrupt?Very often asked
  1. AAfter it, in a separate node or idempotentCorrect answer
  2. BBefore it in the same node
  3. CIn the UI
  4. DNowhere

Why: Avoid running them twice.

9What should an approval payload include?Very often asked
  1. ANothing
  2. BThe proposed action, reason and key dataCorrect answer
  3. COnly the thread ID
  4. DThe model's weights

Why: Reviewers decide without digging.

10What happens when a reviewer never responds?Very often asked
  1. AThe graph runs forever
  2. BThe action executes anyway
  3. CThe thread is deleted silently
  4. DEscalate or apply a safe default after a deadlineCorrect answer

Why: Track pending reviews.

11What lets any server resume a paused run?Very often asked
  1. AState stored in the checkpointer by thread_idCorrect answer
  2. BSticky sessions
  3. CLocal memory
  4. DCookies

Why: Persistence is shared.

12How do you let reviewers edit tool arguments?Very often asked
  1. AChange the model
  2. BInterrupt before the tool and resume with edited argsCorrect answer
  3. CEdit the code
  4. DRestart the server

Why: The tool runs with corrections.

13The value given in Command(resume=...) becomes…Very often asked
  1. AThe graph's final output
  2. BThe return value of interrupt()Correct answer
  3. CA new system prompt
  4. DThe thread ID

Why: The node continues with the human's input.

Sourced from Docs by LangChain (MCP)

14Where should a non-idempotent side effect go relative to interrupt()?Very often asked
  1. AJust before it
  2. BIn the checkpointer
  3. CAnywhere, it never repeats
  4. DAfter it, or in a separate nodeCorrect answer

Why: Code before the interrupt re-runs on resume.

Sourced from Docs by LangChain (MCP)

15What decides which node runs after the agent node?Often asked
  1. AThe order nodes were added
  2. BA conditional edge function reading the stateCorrect answer
  3. CAlphabetical node names
  4. DThe checkpointer

Why: Conditional edges inspect the state (for example, whether there are tool calls) and return the next node.

16What does time travel allow?Often asked
  1. ADeleting history
  2. BForking from an earlier checkpointCorrect answer
  3. CPredicting the future
  4. DFaster models

Why: Rerun with corrections.

17When is human review most justified?Often asked
  1. AEvery read-only lookup
  2. BSpell checks
  3. CLogging
  4. DIrreversible or regulated actionsCorrect answer

Why: Match review to risk.

18How should edited values be handled after resume?Often asked
  1. AIgnored
  2. BSent to the model only
  3. CValidated against schemas and rulesCorrect answer
  4. DTrusted blindly

Why: Reviewers make mistakes too.

19Parallel interrupts are resumed by…Often asked
  1. AMapping interrupt IDs to answersCorrect answer
  2. BResuming each thread separately always
  3. CIgnoring some
  4. DRestarting

Why: One resume can answer all.

20What should be audited for each decision?Often asked
  1. AReviewer, decision, payload and timeCorrect answer
  2. BOnly the result
  3. CNothing
  4. DThe model name only

Why: Reconstruct why paths were taken.

21How are interrupt paths tested?Often asked
  1. ASkipping interrupts
  2. BSnapshot of the UI only
  3. CRun to the interrupt then resume with each optionCorrect answer
  4. DOnly manually

Why: Approve, edit and reject.

22Which middleware adds review to create_agent?Often asked
  1. AHuman-in-the-loop middlewareCorrect answer
  2. BSummarisation middleware
  3. CPII middleware
  4. DModel fallback

Why: Interrupts before chosen tools.

23Graph changes after deploy must keep…Often asked
  1. AThe same server
  2. BAll threads deleted
  3. CThe same model
  4. DOld checkpoints compatibleCorrect answer

Why: Paused runs must still resume.

24To continue a multi-turn conversation you pass…Often asked
  1. ACommand(goto=...)
  2. BA new thread ID each time
  3. CA plain input objectCorrect answer
  4. DCommand(update=...)

Why: Only resume is meant as a Command input.

Sourced from Docs by LangChain (MCP)

25New state fields added while threads are paused should be…Often asked
  1. ARequired
  2. BRenamed immediately
  3. CStored in a new database
  4. DOptionalCorrect answer

Why: Old checkpoints must still validate.

Sourced from Docs by LangChain (MCP)

26Where does the interrupt payload appear in a run result?Often asked
  1. ANowhere
  2. BUnder __interrupt__Correct answer
  3. CIn the system prompt
  4. DIn the thread ID

Why: It mirrors every payload passed to interrupt().

Sourced from Docs by LangChain (MCP)

27Which metric shows reviews may be unnecessary?Sometimes asked
  1. AHigh approval rate with few editsCorrect answer
  2. BLow traffic
  3. CHigh CPU
  4. DLong prompts

Why: Automate low-risk paths.

28What does a rejected proposal do to history?Sometimes asked
  1. ARestarts the graph
  2. BDeletes the thread
  3. CStays recorded for auditCorrect answer
  4. DIs erased

Why: History is append-only.

29Which tool shows interrupts and lets you resume runs?Sometimes asked
  1. ALangGraph StudioCorrect answer
  2. BExcel
  3. CDocker Desktop
  4. DChrome DevTools

Why: Part of the LangGraph platform.

30interrupt() differs from an input node because it…Sometimes asked
  1. ACannot be resumed
  2. BNeeds no checkpointer
  3. CPauses midway with saved stateCorrect answer
  4. DRuns only at start

Why: Resume later, even by another person.

31What should the UI show while waiting?Sometimes asked
  1. AAn error
  2. BNothing
  3. CA spinner forever
  4. DA pending review stateCorrect answer

Why: Users know a person is deciding.

32Adding a node to a graph with paused threads…Sometimes asked
  1. ADoes not break resumeCorrect answer
  2. BDeletes all checkpoints
  3. CRequires new thread IDs
  4. DIs impossible

Why: Resumed runs use saved state with the newly compiled graph.

Sourced from Docs by LangChain (MCP)

Track your progress through every blueprint in your dashboard.

Start learning