LCAE sample questions with answers

10 free practice questions for the LangChain Certified Agent Engineer exam. Try each one, then open the answer to see why the right option wins and every other option loses.

Question 1Building Agents

A team keeps skills in a store and edits a SKILL.md to fix a wrong step. Running locally, the fix appears on the very next run. On their LangSmith Deployment, new threads get the fixed instructions, but users continuing existing threads keep receiving the old skill list and wording. What explains the difference, and what is the documented fix?

  1. A.

    LangSmith Deployment disables the discovery step of SkillsMiddleware, so the skill list is frozen to whatever was bundled into the image

  2. B.

    Skills load once per thread and stay in state; the deployment's persistent checkpointer keeps that list for the thread, whereas the local runs had none. Reset skills_metadata to None to reload

  3. C.

    The deployment snapshots the store when a revision is built, so a new revision must be deployed before any thread can see the edited skill

  4. D.

    Provider-side prompt caching is replaying the previously cached system prompt, so removing the prompt caching middleware from the agent's stack would let the existing threads see the edited skill at once

Show answer

Answer: B

Skill metadata is cached in thread state; with a persistent checkpointer it survives for the thread's life until skills_metadata is reset to None.

  • A. Discovery clearly runs on the deployment, because new threads pick up the fixed skill; it is not disabled there.
  • B. Correct. Thread state holds the skill list; the deployment's checkpointer preserves it, so a reset to `None` is needed to reload.
  • C. New threads already see the edit, which rules out a store snapshot taken at build time; no redeploy is needed for a store change.
  • D. Prompt caching only reuses a prefix that is actually sent; the stale wording comes from skill metadata held in the thread's state.
Question 2Building Agents

A deep agent runs generated code in a sandbox and must also call an internal billing API that needs a bearer token. The provider offers no credential-injecting proxy. The security team accepts any design in which a prompt-injected agent still cannot obtain the token. Which design do the Deep Agents docs recommend?

  1. A.

    Upload the token to a file inside the sandbox and add a FilesystemPermission that denies reads of that path, so read_file can never return it

  2. B.

    Inject a narrowly scoped token that expires after fifteen minutes as a sandbox environment variable, so that any leaked value becomes useless to an attacker almost immediately

  3. C.

    Keep the token in a tool that runs in the host application outside the sandbox and calls the billing API, so the agent invokes it by name and never sees the credential

  4. D.

    Put the token in the agent's AGENTS.md memory with an instruction never to reveal it, since memory is injected only into the system prompt

Show answer

Answer: C

The recommended pattern keeps secrets in host-side tools; anything inside the sandbox is reachable by an injected agent.

  • A. Permissions do not govern sandbox backends, so a shell command through `execute` can still read the file.
  • B. Short-lived, scoped tokens limit the damage but remain readable by an injected agent; the docs say the warning applies to them too.
  • C. Correct. A host-side tool keeps the token outside the boundary; the agent uses the capability without ever holding the secret.
  • D. Memory is text the model reads directly, so the token would be in the hands of the manipulated agent.
Question 3Building Agents

A bank already runs a well-tested create_agent graph that reconciles transactions. A new deep agent for month-end close should hand reconciliation work to that existing graph through its task tool without rewriting it as a dictionary spec or redeploying it separately. How should the team register it?

  1. A.

    Register the graph as an async subagent with a url, because synchronous subagents can only be declared as dictionaries

  2. B.

    Add a dictionary subagent that copies the reconciliation agent's system prompt, since declarative subagents inherit a graph's tools and middleware

  3. C.

    Wrap the compiled graph in CompiledSubAgent with a name, a description and the graph as its runnable, and pass it in subagents

  4. D.

    Pass the compiled graph in the tools list; create_deep_agent detects graphs among tools and converts them into subagents automatically

Show answer

Answer: C

Reuse an existing graph as a synchronous deep agent subagent by wrapping it in CompiledSubAgent with a name, description and runnable.

  • A. Async subagents run on an Agent Protocol server as background tasks; synchronous subagents also accept `CompiledSubAgent`, so no separate deployment is needed.
  • B. A dictionary spec builds a new agent from its own fields; copying a prompt does not reuse the tested graph, its tools or its middleware.
  • C. `CompiledSubAgent` exists for prebuilt graphs, including ones made with `create_agent`; the graph needs a `messages` state key, which `create_agent` provides.
  • D. Tools are callables or tool objects; the harness does not auto-convert a graph in `tools` into a subagent.
Question 4Building Agents

A main agent delegates 'summarise chapter 1' to a reader subagent, then later delegates 'compare chapter 2 with what you read in chapter 1' to the same subagent. The second result says it has no information about chapter 1. The team assumed the subagent would remember its earlier task. What explains this, and how should the design change?

  1. A.

    The subagent needs a checkpointer of its own; without one, subagent memory lasts only until the parent's next model call

  2. B.

    Each task call starts a fresh, stateless subagent instance; the main agent must pass the needed context or a file path in the new task description

  3. C.

    Synchronous subagents remember only their last three tasks; the second call exceeded that window and dropped chapter 1

  4. D.

    The subagent's memory was cleared by summarisation of the main agent's history; raise the main agent's keep setting

Show answer

Answer: B

Synchronous subagents forget everything between task calls; carry continuity through the task description or files, or use async subagents.

  • A. Statelessness is by design for synchronous subagents; for stateful background workers the docs point to async subagents.
  • B. The overview says each invocation creates a new agent instance with fresh context, and synchronous subagents are stateless between invocations.
  • C. No such window exists; synchronous subagents keep no state between calls at all.
  • D. The parent's summarisation does not touch a subagent's context; the subagent had no memory of chapter 1 to begin with.
Question 5Building Agents

A research deep agent should remember each user's ongoing project notes from one conversation to the next, while its scratch files and offloaded tool results should disappear when a conversation ends. It currently uses the default backend, and notes vanish in every new conversation. Which backend configuration fits?

  1. A.

    Use FilesystemBackend on a shared directory, because local files are the only persistence deep agents support across threads

  2. B.

    A CompositeBackend with a StateBackend default and a route such as /memories/ to a StoreBackend, with the prompt saying what to save there

  3. C.

    Keep the StateBackend and add a checkpointer, because checkpoints make state files visible in every new conversation

  4. D.

    Replace the default with a StoreBackend for all paths, so that every file, including scratch files and offloaded results, persists across conversations

Show answer

Answer: B

Use CompositeBackend: ephemeral StateBackend by default, and a store-backed path for the notes that must outlive a conversation.

  • A. Store-backed routes are the documented cross-thread option; a shared directory would also mix users' notes.
  • B. The docs' long-term memory pattern routes `/memories/` to a store for cross-thread persistence while everything else stays thread-scoped in state.
  • C. Checkpoints persist state within a thread; files in `StateBackend` are not shared across threads.
  • D. This persists scratch data and offloaded results too, which the stem wants to discard, and internal files would accumulate in the store.
Question 6Building Agents

An agent is created with middleware=[audit, redact]. Both middleware implement before_model and after_model. While reading a trace to understand why audit logs unredacted text in its after_model hook, a developer needs the exact order in which these four hooks run around a single model call. What is that order?

  1. A.

    audit.before_model, audit.after_model, model call, redact.before_model, redact.after_model

  2. B.

    audit.before_model, redact.before_model, model call, audit.after_model, redact.after_model

  3. C.

    redact.before_model, audit.before_model, model call, audit.after_model, redact.after_model

  4. D.

    audit.before_model, redact.before_model, model call, redact.after_model, audit.after_model

Show answer

Answer: D

Before hooks run in list order and after hooks in reverse, so the first middleware's after_model runs last.

  • A. Hooks are grouped by phase around the model call, not run middleware-by-middleware.
  • B. This keeps list order for the after hooks; the docs state after hooks run in reverse order.
  • C. Before hooks run in list order, so `audit.before_model` runs first, not `redact.before_model`.
  • D. `before_*` hooks run first to last and `after_*` hooks run last to first, so `redact.after_model` runs before `audit.after_model`.
Question 7Building Agents

A developer adds SummarizationMiddleware(model=summary_model, keep=("messages", 20)) to a create_agent agent, with no other arguments. Weeks later, traces from very long conversations show no summarisation step at all, and the full history is still sent on every model call. What is the cause?

  1. A.

    The middleware needs a checkpointer before it can write its summary, so without one it quietly skips

  2. B.

    keep of twenty messages is treated as the trigger, so summaries appear only after the twentieth tool call

  3. C.

    Summarisation runs only on agents built with create_deep_agent, so on create_agent the middleware is ignored

  4. D.

    No trigger was given, and without a trigger the middleware never summarises automatically

Show answer

Answer: D

SummarizationMiddleware without a trigger does nothing automatically; always configure at least one trigger condition.

  • A. Summarisation updates in-run state; no checkpointer is needed for it to fire within a run.
  • B. `keep` defines what to preserve after summarising; it is not a trigger.
  • C. `SummarizationMiddleware` is LangChain prebuilt middleware for `create_agent`; deep agents simply include it by default.
  • D. The `trigger` option says that if it is not provided, summarisation will not trigger automatically.
Question 8Building Agents

Late in a long session, an engineer inspecting a deep agent's model input notices that earlier write_file tool calls no longer contain the full file content in their arguments; they show a pointer to the file on disk instead. Recent write_file calls still show full content. What does this indicate?

  1. A.

    Built-in offloading truncated older tool calls whose large content is already persisted, replacing it with a pointer to the file

  2. B.

    The backend failed to save those files, so the harness replaced their arguments with pointers as an error marker for a later retry

  3. C.

    ContextEditingMiddleware cleared the tool inputs because it is part of the default deep agents stack

  4. D.

    Summarisation has rewritten those tool calls, so the files they created were deleted to reclaim space

Show answer

Answer: A

Pointers in place of old write_file arguments are deep agents' input offloading: the content is on disk, so repeating it in context is waste.

  • A. Deep agents truncate older write and edit calls with large inputs once context grows, because the content already exists on the filesystem.
  • B. The pointer indicates content saved elsewhere, not a failure; the file exists at that path.
  • C. Context editing is not in the deep agents bare stack; the behaviour comes from built-in offloading.
  • D. Offloading edits what stays in context; it does not delete the files.
Question 9Building Agents

An agent uses ToolCallLimitMiddleware(tool_name="scrape_page", run_limit=3) to protect an expensive scraping API. In a trace, the fourth scrape_page call returns an error message, yet the run continues, the model calls other tools, and it finishes normally. The operations team wanted the run to stop with an exception at that point. What should they change?

  1. A.

    Replace it with ModelCallLimitMiddleware(run_limit=3), since only model-call limits can stop an agent run

  2. B.

    Move the middleware to the end of the list so it can stop the whole run instead of just the one tool call

  3. C.

    Set exit_behavior="error", because the default blocks exceeded calls with error messages and lets the model carry on

  4. D.

    Set thread_limit=3 as well, because a run limit on its own only warns and never actually blocks further calls to the tool

Show answer

Answer: C

Tool call limits default to continue; choose error to raise and stop, or end to stop gracefully when limiting a single tool.

  • A. A model-call limit caps model calls, not scraper usage, and tool-call limits can also stop a run when configured to.
  • B. List position does not change what the limiter does when a limit is reached.
  • C. The default `exit_behavior` is `continue`, which blocks exceeded calls with error messages; `error` raises `ToolCallLimitExceededError` and stops execution.
  • D. The run limit already blocked the fourth call; adding a thread limit changes the scope, not the stopping behaviour.
Question 10Building Agents

In the deep agents stack, MemoryMiddleware is placed after the provider prompt-caching middleware, and custom middleware passed in middleware= lands after PatchToolCallsMiddleware but before caching. A team asks why memory is not simply injected first, next to the base prompt. What is the documented reason for this ordering?

  1. A.

    Memory has to be loaded after caching because cached content cannot include any text read from files on the backend

  2. B.

    Memory is placed late so that its instructions override the developer's system prompt whenever the two contain conflicting instructions

  3. C.

    The order lets memory be summarised together with conversation history when the context window starts to fill up

  4. D.

    Updates to injected memory are then less likely to invalidate the cached prompt prefix, so caching keeps paying off on long runs

Show answer

Answer: D

Deep agents order middleware partly for caching: memory is injected late so edits to it do not break the cached prefix.

  • A. Cache eligibility is about stable prefixes, not about whether text came from files; static sections such as memory are described as cache-eligible.
  • B. The caller's `system_prompt` always sits at the front; late placement is a caching decision, not an override mechanism.
  • C. Summarisation compresses message history; memory is injected into the prompt and is not summarised with history.
  • D. The Customize page notes `MemoryMiddleware` runs after profile extras and prompt caching so memory updates are less likely to invalidate the cache prefix.

Keep going with 491 more LCAE questions

Free papers every day, in the real exam formats, with progress by exam domain. Unlock every paper and timed mock exam when you are ready.

LCAE sample questions with answers (10 free) · CertifyAIx