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

LangGraph blueprint · Knowledge work

Deep research agent with subagents

A long-running Deep Agents research agent on LangGraph plans with a todo list, delegates topics to subagents with isolated context, keeps notes in a filesystem and compiles a cited report. It must never state a claim in the final report that is not backed by a source the agent actually fetched.

Steps
9
Subjective questions
33
Objective questions
33

The problem and the outcome

Problem: Single-loop research agents overflow their context window on multi-topic questions, lose track of what is done, and produce reports with unsupported or fabricated citations. Long runs also fail midway and have to start over.

Outcome: Research runs become durable, resumable and inspectable: the plan is visible, each topic is researched in a clean context, notes persist as files, and every report claim traces back to a saved source.

Architecture

Analystresearch question01Agent Serverruns + streaming01Plan approvalinterrupt()03PostgrescheckpointerOrchestratordeep agent02Todo planwrite_todos state02PostgresStore/memories/ path09Research subagentsvia task tool04Critique subagentchecks claims08Virtual filesystemnotes/*.md05Web search+ fetch tools05Citation checkclaims vs sources08Report compilefinal_report.md07questionrun on thread_idwrite_todosplan for reviewCommand(resume=...)task(topic)queries + fetchwrite_file notesshort summary onlycompile from notesread_filedraft for reviewflagged claimsgaps: re-researchsave learningsstate per super-stepstream + final report

How it works, step by step

  1. The analyst submits a research question to the agent deployed on LangSmith Agent Server; a thread is created and the Postgres checkpointer saves state for that thread_id at every super-step.
  2. The orchestrator, built with create_deep_agent, breaks the question into topics and records them with the write_todos tool, so the plan lives in graph state and is visible in the stream.
  3. An interrupt() pauses the run before delegation so the analyst can approve, edit or reject the plan; the client continues with Command(resume=...) carrying the decision.
  4. For each todo the orchestrator calls the task tool, which spawns a named research subagent with a fresh, isolated context and its own system prompt and tools; independent topics can be dispatched in the same turn to run in parallel.
  5. Each subagent searches and fetches pages, then writes findings with source URLs and quoted excerpts to notes files such as notes/<topic>.md instead of holding raw pages in messages.
  6. The subagent returns only a short summary and the file path to the orchestrator, which marks the todo complete and decides whether more topics are needed.
  7. The orchestrator reads the notes with read_file and writes final_report.md, citing each claim to a source recorded in the notes.
  8. A critique subagent reviews the draft and a citation check compares claims to saved sources; unsupported claims route back to the orchestrator as new todos for re-research or removal.
  9. The approved report streams back to the analyst, and durable learnings (source quality, user preferences) are saved under /memories/ in PostgresStore for future threads.

Tech stack

  • LangGraph (StateGraph runtime, checkpointers, interrupt, Command)
  • deepagents library (create_deep_agent, write_todos, filesystem tools, task tool)
  • Tool-calling chat model via LangChain
  • Web search and page-fetch tools
  • PostgresSaver checkpointer
  • PostgresStore for cross-thread memory
  • LangSmith tracing and Agent Server deployment

Key design decisions

  • Use subagents through the task tool rather than one long loop, so raw search results stay in the subagent's context and only a summary returns to the orchestrator.
  • Write evidence to files with URLs and excerpts, and compile the report from files rather than from chat history, so citations are checkable and context stays small.
  • Use a CompositeBackend: ephemeral per-thread scratch files in state, and only the /memories/ path routed to the store for long-term memory across threads.
  • Put a human approval interrupt on the plan, not on every tool call, to catch wrong scope early without making long runs tedious.
  • Run on a Postgres checkpointer so a crashed or timed-out run resumes from the last super-step instead of repeating paid searches.

Common mistakes

  • Letting subagents return full page dumps, which defeats context isolation and bloats the orchestrator's window.
  • Citing sources the model remembers rather than ones it fetched and saved; the citation check must only accept URLs present in the notes files.
  • Non-idempotent side effects before an interrupt: on resume the node re-runs from the start, so tools called before interrupt() run again.
  • No cap on delegation depth or re-research loops, leading to runaway cost; set a recursion limit and a maximum number of critique rounds.
  • Storing scratch notes in the long-term store so stale, unverified notes leak into unrelated future threads.

What to measure

  • Share of report claims backed by a source saved in the notes
  • Plan approval and edit rate at the interrupt
  • Tokens and tool calls per run, split by orchestrator and subagents
  • Runs resumed from checkpoint versus restarted
  • Critique loop count per report and time to final report

Most-asked interview questions

Subjective questions 33

1Why use subagents with isolated context instead of a single agent loop for deep research?Asked almost every time

A single loop accumulates every search result and page in one message history, so on a multi-topic question it runs out of context, gets slower and starts losing earlier details. With Deep Agents, the orchestrator calls the task tool, which spawns a subagent with a fresh context, its own prompt and tools. The subagent does the messy work, writes evidence to a notes file, and returns only a short summary and a file path. The orchestrator stays focused on planning and synthesis. You also get specialisation: a researcher subagent and a critique subagent can have different instructions and tools. The trade-off is extra latency and the risk of losing nuance in the summary, which is why the full evidence lives in files the orchestrator can read later.

Sourced from Docs by LangChain (MCP)

2Walk me through the end-to-end architecture of this deep research agent.Asked almost every time

The agent runs on LangSmith Agent Server. An analyst's question creates a thread, and a Postgres checkpointer saves state for that thread_id at every super-step. The orchestrator is built with create_deep_agent. It turns the question into topics with write_todos, so the plan lives in graph state. An interrupt() lets the analyst approve or edit that plan. The orchestrator then calls the task tool once per todo. Each call spawns a research subagent with a fresh context, and that subagent writes sourced notes to files such as notes/<topic>.md. The orchestrator reads those notes and writes final_report.md. A critique subagent and a citation check send unsupported claims back as new todos. The approved report streams to the analyst, and durable learnings go to /memories/ in PostgresStore.

Sourced from Docs by LangChain (MCP)

3Why do subagents write findings to notes files instead of returning raw page content in messages?Asked almost every time

Raw pages are large and noisy. If they pass through messages, they fill the orchestrator's context, raise cost and push out the plan and earlier findings. Writing to notes/<topic>.md moves that bulk out of the conversation. Each note keeps the source URL and quoted excerpts, and the subagent returns only a short summary and the file path. The orchestrator can then read specific files with read_file when it writes the report. Files also give us a reviewable evidence trail. The citation check compares report claims against these saved excerpts, which is much more reliable than relying on what a model remembers from a long message history.

Sourced from Docs by LangChain (MCP)

4How do you prove a cited source was actually fetched, rather than just named by the model?Asked almost every time

I would not trust URLs written by the model. The fetch tool itself records every successful fetch in a log outside the model's control, either in state or in a store. Each record holds the URL, timestamp, status and a content hash or stored snapshot. The citation check accepts a citation only if: 1. its URL matches a fetch-log entry for this thread; 2. the quoted excerpt is found in that stored content. A URL that appears only in model output, perhaps hallucinated or remembered from training, fails automatically. This makes the invariant 'every claim is backed by a fetched source' something code can verify, instead of something we hope the model respects.

Sourced from Docs by LangChain (MCP)

5What happens when the citation check finds unsupported claims, and how do you stop the loop from running forever?Asked almost every time

Each unsupported claim is routed back to the orchestrator as a new todo. The todo says either re-research the claim with a target source, or remove it from the draft. The orchestrator handles these like normal todos, delegating to a subagent if needed, and then revises final_report.md. To bound the loop, I keep an iteration counter in state and a maximum number of critique rounds. If claims are still unsupported when the limit is reached, they are removed rather than left in, because the invariant forbids unsupported claims. Optionally, the run raises an interrupt so the analyst can decide. Removed claims can be listed in a short 'not verified' note to the analyst, outside the report body.

Sourced from Docs by LangChain (MCP)

6How do you defend against prompt injection from fetched web pages?Asked almost every time

Treat every fetched page as untrusted data. Only subagents read raw pages, and their tools are narrow: search, fetch and write within their own notes path. They cannot send email, call internal APIs or write to /memories/. Wrap page content in clear delimiters and tell the subagent never to follow instructions found inside it. The orchestrator sees summaries and notes, not raw HTML, which limits how far an injection can spread. The citation check is deterministic: it matches quotes against fetched content. An injected 'claim' still needs real support. Memory writes are restricted to the orchestrator and validated, so a hostile page cannot poison future threads. I would also red-team the agent with injected pages in evaluation.

Sourced from Docs by LangChain (MCP)

7How do you make sure the final report's citations are real and accurate?Very often asked

I make the filesystem the source of truth. Subagents must write each finding with the fetched URL and a quoted excerpt into notes files, and the report is compiled from those files, not from model memory. After drafting, a critique subagent checks each claim against the notes, and a deterministic step verifies that every cited URL actually appears in the saved notes. Anything unsupported becomes a new todo: either re-research or remove the claim. I cap critique rounds to control cost. In LangSmith I trace runs and track the share of claims with a matching saved source as a quality metric, and I sample reports for human review, because an LLM judge alone can miss subtle misquotes.

Sourced from Docs by LangChain (MCP)

8How does this agent survive failures and support human review during a run that takes many minutes?Very often asked

The graph is compiled with a Postgres checkpointer, so state, including todos, messages and the in-state files, is saved per thread_id at every super-step. If a worker crashes or a tool times out, the run resumes from the last checkpoint rather than redoing earlier searches. For review, the plan step calls interrupt(), which pauses execution and surfaces the proposed todos to the client; the analyst approves or edits and the client resumes with Command(resume=...). Because the node re-executes from its start on resume, I keep side effects after the interrupt or make them idempotent. Checkpoints also enable time travel: with get_state_history I can fork from an earlier checkpoint to debug a bad delegation decision.

Sourced from Docs by LangChain (MCP)

9What does the graph state and data model look like for this agent?Very often asked

The state holds: - messages, with an append reducer; - the todo list from write_todos, where each item has content and a status (pending, in progress or completed); - the virtual filesystem, which maps paths such as notes/<topic>.md and final_report.md to their contents. I would add structured fields: an iteration counter for critique loops, the plan-approval decision and a list of verification results. Each note entry should carry the URL, fetch timestamp, the quoted excerpt and the claim it supports. Ideally it also has a reference to a fetch-log record written by the fetch tool itself. Outside the thread, PostgresStore holds cross-thread memories under namespace tuples, for example per user. The checkpointer stores snapshots of all of this per thread_id.

Sourced from Docs by LangChain (MCP)

10Why keep the research plan as a todo list in graph state rather than only in the model's reasoning?Very often asked

A plan inside the model's reasoning cannot be seen, edited or recovered. With write_todos, the plan becomes explicit state. It is checkpointed at every super-step, so it survives crashes, and it shows up in the stream so the analyst can watch progress. It also makes the approval interrupt meaningful, because the analyst is editing a concrete artifact. Status fields on each todo keep the orchestrator focused on what remains. That reduces drift on long runs where earlier context gets crowded out. Finally, the critique step can add new todos for unsupported claims, so re-research uses the same mechanism as the original plan instead of a separate ad hoc path.

Sourced from Docs by LangChain (MCP)

11How would you design the plan-approval interrupt, including the edit and reject paths?Very often asked

Before any delegation, a node calls interrupt() with a payload containing the proposed todos and the original question. The client shows this to the analyst. It then resumes with Command(resume=...) carrying a structured decision: approve, edit with a revised todo list, or reject with a reason. - On approve, we continue to delegation. - On edit, we write the analyst's todos into state and proceed. - On reject, we either end the run or loop back to planning with the feedback, capped by a retry limit. The decision should be validated against a schema, not free text. Code before the interrupt in that node reruns on resume, so the node should do nothing expensive or side-effecting before calling interrupt().

Sourced from Docs by LangChain (MCP)

12How do parallel subagents work here and what limits would you put on them?Very often asked

The orchestrator can emit several task tool calls in one turn for independent topics, and these run concurrently. Each one gets an isolated context, so they don't see each other's messages. They share the filesystem, which is why each subagent writes to its own topic-specific path to avoid collisions. Limits I would add: - a cap on concurrent subagents per thread and per tenant, to protect search and model rate limits; - a per-subagent budget on tool calls and tokens; - a timeout. Parallelism should only be used for independent topics. Dependent topics, where one needs another's findings, should run in sequence so the later subagent can read the earlier notes.

Sourced from Docs by LangChain (MCP)

13What schema would you use for a notes file so that it supports later verification?Very often asked

I would use a consistent markdown or structured format per finding. Each finding records: - the claim, in the subagent's words; - the exact quoted excerpt from the page; - the source URL; - the page title; - the fetch timestamp; - an ID linking to the fetch-log entry created by the fetch tool. The file also lists open questions and conflicting evidence separately. The key property is that every claim sits next to a verbatim quote and a fetch reference. The citation check can then confirm that the quote really appears in the fetched content and that the claim follows from it. Free-form summaries without quotes make that check much weaker and invite unsupported paraphrase.

Sourced from Docs by LangChain (MCP)

14How would you estimate cost and capacity for this agent?Very often asked

I would build a per-run model rather than guess figures. Count: - the typical number of todos; - searches and fetches per subagent; - tokens per fetched page that a subagent reads; - orchestrator turns; - critique rounds. Multiply by model token prices, and add search API calls. The main cost driver is subagents reading pages, which is why notes keep the orchestrator's context small. For capacity, multiply the expected concurrent threads by the parallel subagents per thread. Check that against model and search rate limits and against Postgres write load from per-super-step checkpoints. I would measure real distributions from LangSmith traces on a pilot and set budgets, such as maximum todos, tool calls and rounds, from observed percentiles.

Sourced from Docs by LangChain (MCP)

15What privacy concerns arise with long-term memories, and how do you address them?Very often asked

Memories persist across threads, so they can leak one user's data to another user or keep sensitive details longer than intended. Mitigations: - Namespace the store by tenant and user, such as (tenant_id, user_id, 'memories'), and enforce that namespace in server-side code, never from model input. - Only save durable, low-sensitivity learnings like source quality ratings and formatting preferences, not raw research content or personal data. - Apply a PII filter before writes. - Support listing and deleting memories per user to meet data-deletion obligations under laws such as India's DPDP Act. - Set retention limits. - Audit memory writes in traces, so reviewers can see what was stored and why.

Sourced from Docs by LangChain (MCP)

16What should you watch for regarding side effects when a run resumes after an interrupt or a crash?Very often asked

On resume after an interrupt, the node that called interrupt() re-executes from its start, not from the interrupt line. Any work before the interrupt in that node runs again. So keep expensive or side-effecting work out of that section, or put it in a separate earlier node. After a crash, execution resumes from the last checkpoint. Work in the super-step that was in progress may run again. Tools should therefore be idempotent where possible: - writes to notes/<topic>.md overwrite or append deterministically; - fetches are cached by URL; - memory writes use stable keys, so a repeat updates the entry instead of duplicating it.

Sourced from Docs by LangChain (MCP)

17How would you evaluate the quality of this research agent before and after changes?Very often asked

I would build a dataset of research questions with reference answers or key facts and run it in LangSmith. Metrics: - citation precision: the share of claims supported by fetched quotes, checked deterministically; - coverage of expected key facts, judged by an LLM evaluator with human spot checks; - the rate of claims removed in critique; - cost and latency per run; - plan approval and edit rates from real analysts. I would track regressions on every prompt, model or tool change. Online, I would sample production traces for human review. Any report found with an unsupported claim would be treated as a severity-one bug, because it breaks the core invariant.

Sourced from Docs by LangChain (MCP)

18How does the orchestrator avoid running out of context on a long research run?Very often asked

Several mechanisms help: - Subagents return only a short summary and a file path, so raw pages never enter the orchestrator's messages. - The orchestrator reads notes selectively with read_file when drafting each section, instead of loading everything at once. - The todo list gives a compact view of progress, so the orchestrator doesn't need to reread history. Deep Agents also provides summarisation middleware for long histories. Large tool results can be offloaded to files. For very large reports, the orchestrator can write the report section by section to final_report.md using edit_file, keeping each step's working set small.

Sourced from Docs by LangChain (MCP)

19What happens if a research subagent fails midway, for example from a timeout or tool errors?Very often asked

The task tool call returns an error or a partial summary to the orchestrator. Because notes are written to files as the subagent works, partial findings can survive. The orchestrator keeps the todo pending and can retry with the same or a narrower instruction, up to a retry limit. If the topic still fails, it marks the gap and writes the report without those claims. If the whole process crashes, the Postgres checkpointer lets the thread resume from the last saved super-step, so completed topics are not redone. Retries with backoff belong in tools for transient errors. Clear error messages, rather than empty results, stop the subagent from filling gaps with invented content.

Sourced from Docs by LangChain (MCP)

20How do you handle search API rate limits when many subagents run in parallel?Often asked

Put rate limiting in the tool layer, not in prompts. Use a shared token bucket per provider and API key, and add retries with exponential backoff and jitter on rate-limit responses. Cap concurrent subagents per thread and per tenant so one large run cannot starve others. Cache search results and fetched pages by normalised URL for a short window, so subagents researching overlapping topics don't refetch. If a tool keeps failing, return a clear error message to the subagent. It can then record the gap in its notes instead of inventing content. Because state is checkpointed, a run that stalls on limits can be resumed later without redoing completed topics.

Sourced from Docs by LangChain (MCP)

21How would you organise namespaces in PostgresStore for this agent?Often asked

Namespaces are tuples, so I would make them hierarchical. Examples: - (tenant_id, user_id, 'preferences') for report style and depth; - (tenant_id, 'source_quality') for shared ratings of domains, if the tenant agrees to sharing; - (tenant_id, user_id, 'past_topics') for summaries that help future planning. The /memories/ path in the agent's filesystem maps to these store entries. Optional semantic search lets the orchestrator retrieve relevant memories by meaning at the start of a thread. The tenant and user parts of the namespace are taken from the authenticated request context, never from the model. That prevents cross-tenant reads even if the model is manipulated.

Sourced from Docs by LangChain (MCP)

22How would you use time travel to debug a bad report?Often asked

Because the Postgres checkpointer saves state at every super-step, I can call get_state_history on the thread to list the checkpoints. I find the point where things went wrong, for example a weak plan or a subagent that wrote poor notes. I inspect the state there: todos, files and messages. To test a fix, I fork from that checkpoint. I use update_state to change the plan or a notes file and then resume, which creates a new branch without changing the original history. This lets me compare outputs from the same starting point, which is far cheaper than rerunning the whole research. Combined with LangSmith traces, I can tie each step to the exact tool calls and model outputs.

Sourced from Docs by LangChain (MCP)

23Which streaming modes would you use for the analyst's UI and why?Often asked

I would combine modes: - updates shows state changes per node, which is ideal for rendering the todo list as items move to completed; - messages streams LLM tokens with node metadata, so the UI can show the report being written live and label which agent is speaking; - custom lets tools emit progress events, such as 'fetched 3 sources for topic X', without putting them into state. I would avoid streaming full values to the browser on every step for long runs, because the filesystem in state can be large. debug mode is useful for engineers, not analysts. For subagent activity, the stream should carry enough metadata to group events by subagent.

Sourced from Docs by LangChain (MCP)

24Why use an orchestrator with subagents here rather than a swarm of agents handing off to each other?Often asked

Research needs one place that owns the plan, tracks completion and assembles a coherent report. That fits a supervisor or hierarchical pattern: the orchestrator delegates bounded tasks and gets summaries back. In a swarm, control passes between agents through handoffs. That suits conversational routing, but makes it harder to guarantee that every todo was done and that the final report is checked once, centrally. The orchestrator pattern also keeps subagent contexts isolated and disposable, which controls token use. The trade-off is that the orchestrator can become a bottleneck and a single point of reasoning failure. I mitigate that with the critique subagent and the deterministic citation check.

Sourced from Docs by LangChain (MCP)

25When would you implement a subagent as a LangGraph subgraph instead of a simple task-tool subagent?Often asked

A task-tool subagent defined with a name, system prompt and tools is enough when the subagent is just a model loop with tools. I would build a custom compiled graph, used as a subgraph, when the subagent needs deterministic structure. Examples are a fixed search-then-fetch-then-extract pipeline, its own conditional edges, or a Send-based fan-out over many URLs. A subgraph also lets me enforce steps in code, such as always running the quote-verification node before returning. That is stronger than asking the model to do it. The cost is more code to maintain and test. Deep Agents lets a compiled graph be registered as a subagent, so the orchestrator still calls it through the task tool.

Sourced from Docs by LangChain (MCP)

26How should the agent handle sources that contradict each other?Often asked

Subagents should record conflicting evidence explicitly in their notes, with quotes and URLs on both sides, rather than silently picking one. The orchestrator, when writing the report, presents the disagreement with both citations. Where the evidence allows, it explains the likely reason, such as different dates, definitions or methods. Source-quality memories can inform which sources to weight, but the report should not drop a cited counterpoint without saying so. If the conflict is central to the question, the critique step can add a todo to find a primary source. Every statement in the report, including a statement that sources disagree, still needs a fetched citation.

Sourced from Docs by LangChain (MCP)

27Web pages change. How do you keep citations meaningful over time?Often asked

Store what we actually saw. The fetch log records a timestamp and a content hash or snapshot, and the notes keep verbatim excerpts. The citation check verifies claims against that stored content, not a live refetch, so verification stays consistent within the run. In the report, citations can show the access date. If the report is regenerated later, a fresh run fetches again, and any claim whose quote no longer appears gets flagged. Snapshot retention should respect copyright and storage limits. Short excerpts plus a hash are often enough, rather than storing whole pages indefinitely.

Sourced from Docs by LangChain (MCP)

28What if the analyst sends a new message while a research run is still in progress on the same thread?Often asked

This is the double-texting problem. LangSmith Agent Server supports strategies for it: reject the new run, enqueue it after the current one, interrupt the current run, or roll it back and start the new one. For long research, I would default to reject or enqueue, so a quick follow-up doesn't throw away minutes of work. Corrections to the plan should go through the explicit approval interrupt instead. If we choose interrupt, checkpoints keep the completed work, and the new input can update the todos. The UI should make the current run status clear, so analysts know whether their message will be queued or will change the run.

Sourced from Docs by LangChain (MCP)

29How do you secure the filesystem tools the agents use?Often asked

By default, Deep Agents uses a virtual filesystem held in graph state, not the host disk, which already limits damage. If I configure a backend that reaches real storage, I scope it to a per-thread root and reject path traversal. I would also restrict which agent can write where: - subagents write only under notes/; - the orchestrator writes final_report.md; - /memories/ is routed to PostgresStore with writes validated and namespaced by tenant and user. File size limits prevent a subagent from dumping whole pages. Everything written is traced, so reviewers can audit what entered the notes and the report.

Sourced from Docs by LangChain (MCP)

30How would you choose models for the orchestrator, research subagents and critique subagent?Sometimes asked

Match the model to the role and measure. The orchestrator plans and synthesises, so it benefits from a strong reasoning model. Research subagents do many search and extract steps, so a cheaper, faster model with good tool calling may be enough. The critique subagent needs careful reading, so I would use a strong model there, and ideally a different one from the writer to reduce shared blind spots. Deep Agents allows a model per subagent. I would decide using the evaluation dataset: compare citation precision, coverage and cost per configuration rather than assuming one model is best everywhere. The deterministic citation check keeps the invariant safe whatever model is used.

Sourced from Docs by LangChain (MCP)

31When an unsupported claim is found, how do you decide between re-researching it and removing it?Sometimes asked

I weigh how important the claim is against cost and time. If the claim is central to answering the question, or the critique suggests a likely primary source, it becomes a re-research todo. If it is peripheral, speculative or already over the retry budget, I remove it. The orchestrator can make the call using a simple rubric in its prompt. A hard rule in code applies once the iteration limit is reached: remove anything still unsupported. The analyst can be told which claims were dropped, outside the report body. Removal is always safe for the invariant. Re-research improves completeness but adds latency and cost.

Sourced from Docs by LangChain (MCP)

32What are the risks of saving source-quality learnings to memory, and how do you manage them?Sometimes asked

Memories can harden mistakes. One bad experience with a domain could cause it to be ignored forever. A poisoned page could also try to get itself rated as trustworthy. To manage this: - Only the orchestrator writes memories, after the report is approved, never subagents reading raw pages. - Ratings are based on evidence, such as how often a source's quotes passed the citation check, rather than on model opinion. - Entries are timestamped, reviewed periodically and allowed to decay. - Memories guide which sources to try first; they never replace verification. - Users and admins can inspect and delete entries.

Sourced from Docs by LangChain (MCP)

33The Agent Server exposes an MCP endpoint at /mcp. What should you consider before enabling it for this agent?Sometimes asked

MCP makes the agent callable as a tool from other clients, so it widens the attack surface. I would require authentication and map callers to tenants, so memory namespaces and threads stay isolated. I would apply rate limits and budgets per caller, because each research run is expensive. The plan-approval interrupt needs thought. An MCP caller may not support human-in-the-loop, so I would either expose a variant with a pre-approved plan or document how the client resumes. I would return the report with its citations intact and log which caller started each run. Finally, I would only expose it if a real integration needs it.

Sourced from Docs by LangChain (MCP)

Objective questions 33

1Which checkpointer is appropriate for this agent in production?Asked almost every time
  1. AA Postgres checkpointerCorrect answer
  2. BNo checkpointer
  3. CA local JSON file
  4. DInMemorySaver

Why: Production runs need durable checkpoints that survive restarts, which a Postgres checkpointer provides. InMemorySaver is meant for development.

Sourced from Docs by LangChain (MCP)

2Which Deep Agents tool does the orchestrator use to record its research plan?Asked almost every time
  1. Aread_file
  2. Binterrupt
  3. Ctask
  4. Dwrite_todosCorrect answer

Why: write_todos records the plan as a todo list in graph state, where it can be seen in the stream and checkpointed.

Sourced from Docs by LangChain (MCP)

3Which Deep Agents tool spawns a subagent with an isolated context?Asked almost every time
  1. Awrite_file
  2. BtaskCorrect answer
  3. Cwrite_todos
  4. Dls

Why: The task tool delegates to a named subagent. The subagent runs with a fresh context and its own system prompt and tools.

Sourced from Docs by LangChain (MCP)

4Why do subagents write findings to notes/<topic>.md instead of keeping raw pages in messages?Asked almost every time
  1. ALangGraph forbids long messages
  2. BIt encrypts the content
  3. CFiles load faster in the browser
  4. DIt keeps bulky raw content out of message context and preserves sourced evidence for later verificationCorrect answer

Why: Notes offload large content from context. They also keep URLs and quoted excerpts, which the report and the citation check rely on.

Sourced from Docs by LangChain (MCP)

5How does a client continue a run paused by interrupt() after the analyst approves an edited plan?Asked almost every time
  1. ARestart the thread from START
  2. BCall update_state with the analyst's decision and start a new run on the same thread
  3. CInvoke the graph with Command(resume=...) carrying the decisionCorrect answer
  4. DSend a message containing the word 'approve'

Why: The workflow resumes the paused interrupt() with Command(resume=...), and the resume value becomes the interrupt's return. update_state is meant for editing or forking state in time travel, not for answering an interrupt.

Sourced from Docs by LangChain (MCP)

6What is the strongest evidence that a cited source was actually fetched?Asked almost every time
  1. AThe model includes the URL in the report
  2. BA fetch log written by the fetch tool, with the quote found in the stored contentCorrect answer
  3. CThe URL looks like a reputable domain
  4. DThe critique subagent says it seems fine

Why: Tool-written records are outside the model's control, and matching the quote against them can be checked deterministically. Model-written URLs can be hallucinated.

Sourced from Docs by LangChain (MCP)

7In this workflow, what happens to a claim that the citation check finds unsupported?Asked almost every time
  1. AIt is saved to /memories/
  2. BIt stays, marked with an asterisk
  3. CIt is routed back to the orchestrator as a new todo for re-research or removalCorrect answer
  4. DThe run is deleted

Why: Unsupported claims become new todos, so the orchestrator either finds real support or removes them. This preserves the invariant.

Sourced from Docs by LangChain (MCP)

8In LangGraph, how does a client continue a run that is paused by interrupt() inside a node?Very often asked
  1. ASend a Send object to the paused node
  2. BClear the checkpointer and restart
  3. CCall the graph again with a new thread_id
  4. DInvoke the graph with Command(resume=value) on the same thread_idCorrect answer

Why: interrupt() saves state through the checkpointer, and invoking with Command(resume=...) on the same thread_id resumes the paused node with that value.

Sourced from Docs by LangChain (MCP)

9In a Deep Agents setup, what does the orchestrator typically receive back when it delegates work with the task tool?Very often asked
  1. AThe subagent's final result, such as a short summaryCorrect answer
  2. BNothing; subagents only write to the store
  3. CThe subagent's full message history
  4. DEvery raw web page the subagent fetched

Why: The task tool runs the subagent in its own context and returns its final output, which keeps the orchestrator's context small.

Sourced from Docs by LangChain (MCP)

10In a LangGraph state schema, which reducer appends list updates to an existing list key instead of replacing it?Very often asked
  1. Aoperator.mul
  2. Bmax
  3. Coperator.eq
  4. Doperator.addCorrect answer

Why: Annotating a list key with operator.add makes LangGraph concatenate updates onto the existing value. Without a reducer, each update overwrites the value.

Sourced from Docs by LangChain (MCP)

11What does returning Send objects from a conditional edge do in LangGraph?Very often asked
  1. AFans out to a node with per-item state, enabling map-reduceCorrect answer
  2. BPersists state to Postgres
  3. CEnds the graph run
  4. DSends an email notification

Why: Each Send object invokes the target node with its own state payload. This is how LangGraph does parallel map-reduce fan-out.

Sourced from Docs by LangChain (MCP)

12How often does a LangGraph checkpointer save state for a thread?Very often asked
  1. AOnly when interrupt() is called
  2. BOnly at the end of a run
  3. CAt every super-stepCorrect answer
  4. DOnce per hour

Why: Checkpoints are saved at every super-step. That is what makes resuming after a failure and time travel possible.

Sourced from Docs by LangChain (MCP)

13Which identifier does a checkpointer use to separate one conversation's saved state from another's?Very often asked
  1. Arun_name
  2. Bthread_idCorrect answer
  3. Cnode_id
  4. Dnamespace tuple

Why: Checkpointed state is stored and retrieved per thread_id. Namespace tuples belong to stores, not checkpointers.

Sourced from Docs by LangChain (MCP)

14Which streaming mode streams LLM tokens along with node metadata?Very often asked
  1. Avalues
  2. Bupdates
  3. CmessagesCorrect answer
  4. Ddebug

Why: The messages mode streams LLM tokens with metadata about the node that produced them.

Sourced from Docs by LangChain (MCP)

15What does 'isolated context' mean for a research subagent in this workflow?Very often asked
  1. AIt runs on a separate server
  2. BIt starts without the orchestrator's message history and has its own prompt and toolsCorrect answer
  3. CIt cannot access any tools
  4. DIt shares all messages with other subagents

Why: Each subagent begins with a fresh context, so its intermediate work does not crowd the orchestrator's context or that of sibling subagents.

Sourced from Docs by LangChain (MCP)

16How can the orchestrator research several independent topics in parallel?Very often asked
  1. ABy calling the task tool for several topics in the same turnCorrect answer
  2. BBy creating a new thread for each topic
  3. CBy disabling the checkpointer
  4. DBy using InMemoryStore

Why: Multiple task tool calls issued in one turn let independent subagents run concurrently.

Sourced from Docs by LangChain (MCP)

17When a run resumes after interrupt(), where does execution restart in the paused node?Very often asked
  1. AAt END
  2. BAt the line after interrupt()
  3. CAt the beginning of that nodeCorrect answer
  4. DAt START of the graph

Why: The node that called interrupt() is re-executed from its start, so code before the interrupt runs again. That code should be idempotent.

Sourced from Docs by LangChain (MCP)

18Where are durable learnings such as source quality and user preferences saved?Very often asked
  1. AIn InMemorySaver
  2. BIn the thread's messages
  3. CUnder /memories/ in PostgresStoreCorrect answer
  4. DIn final_report.md

Why: The /memories/ path is backed by PostgresStore, so these learnings persist across threads. Checkpoints are per thread only.

Sourced from Docs by LangChain (MCP)

19Which measure best reduces prompt-injection risk from fetched pages?Very often asked
  1. AGive subagents broad tools so they can recover
  2. BTreat page content as untrusted, restrict subagent tools, and verify citations deterministicallyCorrect answer
  3. CLet fetched pages write to /memories/
  4. DShow raw HTML to the orchestrator

Why: Least-privilege tools and isolating untrusted content limit what an injection can do. Deterministic checks stop injected claims from passing.

Sourced from Docs by LangChain (MCP)

20Which component gives this agent memory that persists across different threads?Often asked
  1. AStreaming in values mode
  2. BInMemorySaver
  3. CA Store such as PostgresStore, organised by namespacesCorrect answer
  4. DThe todo list written by write_todos

Why: Checkpointers persist state per thread, while Stores like PostgresStore provide long-term memory shared across threads, organised by namespace tuples.

Sourced from Docs by LangChain (MCP)

21Which pair of methods supports time travel, letting you replay or fork from an earlier checkpoint?Often asked
  1. Aadd_node and add_edge
  2. Bcompile and draw
  3. Cget_state_history and update_stateCorrect answer
  4. Dstream and invoke

Why: get_state_history lists past checkpoints, and update_state lets you modify state and fork a new branch from a chosen checkpoint.

Sourced from Docs by LangChain (MCP)

22What does Command(goto=..., update=...) returned from a node do?Often asked
  1. AResumes an interrupted run
  2. BRoutes to another node and applies a state update from inside the nodeCorrect answer
  3. CDeletes the thread
  4. DStarts a new thread

Why: Command with goto and update combines routing and a state update in one return value. This is used for handoffs. Command(resume=...) is the form used for resuming.

Sourced from Docs by LangChain (MCP)

23Which streaming mode is best for showing per-node state changes, such as todo statuses changing?Often asked
  1. Amessages
  2. Bcustom
  3. CupdatesCorrect answer
  4. Dvalues

Why: updates emits the state delta each node returns. That is lighter than values, which emits the full state after each step.

Sourced from Docs by LangChain (MCP)

24How are items in a LangGraph store, such as PostgresStore, organised?Often asked
  1. ABy thread_id only
  2. BBy namespace tuplesCorrect answer
  3. CBy node name
  4. DBy checkpoint number

Why: Stores organise items under namespace tuples, which lets memories be grouped by tenant, user or purpose across threads.

Sourced from Docs by LangChain (MCP)

25What is a good way to stop the critique and re-research loop from running indefinitely?Often asked
  1. ARely on the model to stop
  2. BKeep an iteration counter in state with a maximum, and remove still-unsupported claims at the limitCorrect answer
  3. CDisable the critique subagent
  4. DLower the model temperature

Why: A counter in state that conditional routing checks gives a hard bound. Removing leftover unsupported claims keeps the report compliant.

Sourced from Docs by LangChain (MCP)

26What is the main difference between the checkpointer and the store in this agent?Often asked
  1. AThe store saves every super-step
  2. BThe checkpointer only works in-memory
  3. CThey are the same thing
  4. DThe checkpointer saves per-thread state; the store holds long-term memory shared across threadsCorrect answer

Why: Checkpointers save thread state for resuming and time travel, while stores give cross-thread memory organised by namespace.

Sourced from Docs by LangChain (MCP)

27How should memory namespaces be set to prevent cross-tenant leakage?Often asked
  1. AUse the thread_id as the only key
  2. BLet the model choose the namespace
  3. CDerive tenant and user parts from the authenticated request contextCorrect answer
  4. DUse a single global namespace

Why: Namespaces enforced on the server from authenticated identity cannot be manipulated by model output or by injected content.

Sourced from Docs by LangChain (MCP)

28Which multi-agent pattern has agents pass control directly to one another through handoffs, without a central coordinator?Often asked
  1. ASupervisor
  2. BSwarmCorrect answer
  3. CMap-reduce
  4. DSingle agent

Why: In a swarm, agents hand off control to each other. A supervisor centrally routes work, which is closer to this orchestrator design.

Sourced from Docs by LangChain (MCP)

29What does a subgraph mean in LangGraph?Often asked
  1. AA compiled graph used as a node within another graphCorrect answer
  2. BA chart of token usage
  3. CA backup of the checkpointer
  4. DA streaming mode

Why: Subgraphs let graphs be composed by adding one graph as a node in a parent graph.

Sourced from Docs by LangChain (MCP)

30Why should subagents return only a short summary and a file path to the orchestrator?Often asked
  1. ABecause the task tool cannot return text
  2. BTo hide findings from the analyst
  3. CTo avoid checkpointing
  4. DTo keep the orchestrator's context small while the detailed evidence stays in notes filesCorrect answer

Why: Compact returns protect the orchestrator's context window. It can read detailed notes with read_file when it writes the report.

Sourced from Docs by LangChain (MCP)

31At what path does LangSmith Agent Server expose an MCP endpoint for a deployed agent?Sometimes asked
  1. A/mcpCorrect answer
  2. B/tools
  3. C/agent/stream
  4. D/api/mcp/v1

Why: Agent Server exposes deployed agents over an API and an MCP endpoint at /mcp.

Sourced from Docs by LangChain (MCP)

32Which streaming mode would a tool use to emit progress events, like 'fetched 3 sources', that are not part of state?Sometimes asked
  1. AcustomCorrect answer
  2. Bupdates
  3. Cmessages
  4. Dvalues

Why: The custom mode streams arbitrary user-defined data emitted from nodes or tools.

Sourced from Docs by LangChain (MCP)

33What do START and END represent in a LangGraph StateGraph?Sometimes asked
  1. ASpecial nodes marking the graph's entry point and terminationCorrect answer
  2. BTimestamps of a run
  3. CCheckpoint IDs
  4. DStreaming modes

Why: Edges from START define where execution begins, and edges to END define where it finishes.

Sourced from Docs by LangChain (MCP)

Track your progress through every blueprint in your dashboard.

Start learning