create_deep_agent gives you a production-ready foundation: connect it to your data, shape its behavior, and add the capabilities your use case needs.
Full function signature
Full function signature
create_deep_agent API reference. To compose a fully custom harness from scratch, see Configure the harness or follow the step-by-step Build a deep agent from scratch guide.
Model
Pass amodel string in provider:model format, or an initialized model instance. See supported models for all providers and suggested models for tested recommendations.
- OpenAI
- Anthropic
- Azure
- Google Gemini
- AWS Bedrock
- HuggingFace
- Other
Tools
In addition to built-in tools for file management and subagent spawning, you can provide custom tools:MCP tools
Install LangChain with themcp extra to connect to MCP servers:
System prompt
Passsystem_prompt= to give the agent your own instructions:
Besides a string, the main agent also accepts a
SystemMessage with structured content blocks; Deep Agents preserve those blocks (subagent dictionary specs remain strings).Subagent prompts
Subagent prompts
Declarative subagents resolve profile overlays against their own model, then apply the resolved profile’s
base_system_prompt / system_prompt_suffix to the subagent’s authored system_prompt. A profile that ships only a system_prompt_suffix (the common case for built-in Anthropic / OpenAI profiles) appends to the authored prompt. A profile that sets base_system_prompt replaces it outright.General-purpose subagent prompt
General-purpose subagent prompt
The auto-added general-purpose subagent resolves its base prompt as
general_purpose_subagent.system_prompt (if set) -> HarnessProfile.base_system_prompt (if set) -> SDK general-purpose default, with the profile suffix layered on top. When both override fields are set, the general-purpose-specific one wins so a caller tuning both fields never sees their GP override silently dropped:Middleware
Deep Agents support any middleware, including the built-in middleware listed below, prebuilt middleware from LangChain, provider-specific middleware, and custom middleware you write yourself. Pass middleware to themiddleware argument of create_deep_agent. Each instance is merged into the Deep Agents stack by matching its .name against built-in entries already in the stack: a match replaces that instance in place, and anything that does not match is inserted after PatchToolCallsMiddleware. See Override a default middleware instance.
Deep Agents stack
create_deep_agent builds middleware in a fixed order. The bare stack is what you get with only a model. The full stack is the complete assembly order, including slots that appear only when you pass optional arguments or when the resolved harness profile contributes them.
Bare stack
With only amodel (no other optional arguments), the main agent typically includes:
FilesystemMiddlewareSubAgentMiddleware(because the general-purpose subagent is auto-added unless a harness profile disables it)SummarizationMiddlewarePatchToolCallsMiddleware- Prompt caching middleware (always registered; each entry no-ops on models it does not support)
- Harness profile extras and excluded-tool filtering, if the resolved model profile defines them
Full stack
From first to last:-
SkillsMiddleware: Only when you passskills. Injected before filesystem middleware so skill metadata is available before file tools run. -
FilesystemMiddleware: Handles file system operations such as reading, writing, and navigating directories. When you passpermissions, filesystem permissions enforcement is included here so it can evaluate every tool the agent might call. -
SubAgentMiddleware: Only when at least one synchronous subagent is available. Spawns and coordinates subagents for delegating tasks. Included in the bare stack because the general-purpose subagent is auto-added by default; omit it by disabling that subagent and passing no synchronoussubagents. See Running without subagents. -
SummarizationMiddleware: Condenses message history to stay within context limits when conversations grow long (via create_summarization_middleware). -
PatchToolCallsMiddleware: Repairs dangling tool calls in message history when a run resumes after an interruption or receives malformed tool-call arguments. Runs before Anthropic prompt caching and the tail stack below. -
AsyncSubAgentMiddleware: Only when you configure async subagents. -
Your middleware argument: Optional middleware you pass as the
middlewareargument is merged after Patch but before the rest of the stack. An instance whose.namematches one of the built-in entries above replaces that instance in place instead of duplicating it; anything else lands here. See Override a default middleware instance. - Harness profile extras: Provider-specific middleware from the resolved model profile, if any.
- Excluded-tool filtering: When the harness profile lists excluded tools, middleware removes those tools from the agent.
-
Prompt caching (
AnthropicPromptCachingMiddlewareandBedrockPromptCachingMiddleware): Both are always registered and run after Patch and after your middleware so the cached prefix matches what is actually sent to the model. Each no-ops on models it does not support (unsupported_model_behavior="ignore"), so the Anthropic middleware applies on Anthropic models and the Bedrock middleware on AWS Bedrock models with cache support. -
MemoryMiddleware: Only when you passmemory.MemoryMiddlewareis placed after profile extras and the prompt caching middleware so updates to injected memory are less likely to invalidate the cache prefix. The same ordering concern is called out in thecreate_deep_agentimplementation comments. -
HumanInTheLoopMiddleware: Only when you passinterrupt_on. Pauses for human approval or input at configured tool calls.
Synchronous subagent stack
The built-in general-purpose subagent and each declarative synchronousSubAgent graph use a stack that create_deep_agent builds in code. It matches the main agent in broad shape (filesystem, summarization, Patch, profile extras, Anthropic and Bedrock caching, optional permissions) but differs in two ways:
- Skills run after
PatchToolCallsMiddlewareon these inner agents (on the main agent, skills run before filesystem middleware whenskillsis set). - There is no
SubAgentMiddlewareinside a subagent graph (only the parent agent exposes thetasktool).
interrupt_on, that value is forwarded to create_agent for the subagent, which wires up human-in-the-loop handling for the configured tool calls.
Prebuilt middleware
LangChain exposes additional prebuilt middleware that let you add-on various features, such as retries, fallbacks, or PII detection. See Prebuilt middleware for more. Thedeepagents library also exposes create_summarization_tool_middleware, enabling agents to trigger summarization at opportune times—such as between tasks—instead of at fixed token intervals. For more detail, see Summarization.
Provider-specific middleware
For provider-specific middleware that is optimized for specific LLM providers, see Middleware integrations.Custom middleware
You can provide additional middleware to extend functionality, add tools, or implement custom hooks:Override a default middleware instance
Overriding a default middleware by matching
.name requires deepagents>=0.7..name matches an entry in the Deep Agents stack, such as SummarizationMiddleware, to replace that built-in instance in place instead of appending a duplicate. Any middleware you pass whose .name does not match a built-in entry is not replaced, it lands after the last core middleware entry and before the profile, prompt-caching, and memory. See Full stack for the complete ordering.
An override replaces the default middleware instance, it is not merged with it. That means your replacement must be fully configured with any settings it needs. This is especially important for
FilesystemMiddleware: if you override it, you must pass the backend (and permissions, if applicable) directly to your custom instance, since it won’t inherit the backend= and permissions= passed to create_deep_agent(). To restrict the available filesystem tools, pass a tools allowlist to your custom FilesystemMiddleware instance; see Virtual filesystem access for the “Restricting filesystem tools” example.subagents= do not inherit the main agent’s middleware customization. Pass the override directly in that subagent’s own middleware field to apply it there; that field is matched against the synchronous subagent stack, the same way middleware= is matched against the main agent’s.
Examples
Adjust when summarization triggers
Adjust when summarization triggers
Override
SummarizationMiddleware with custom trigger and keep thresholds to compact conversation history earlier or later than the default, and control how many recent messages survive each compaction.trigger also accepts ("fraction", ...) for a percentage of the model’s context window, and a list of thresholds combines them with OR semantics. See the SummarizationMiddleware reference for the full set of options.Update the prompt cache TTL
Update the prompt cache TTL
Override
AnthropicPromptCachingMiddleware to extend the cache lifetime beyond the default 5m TTL, useful for agents with long gaps between turns. See Prompt caching for how caching is applied by default.Restrict the enabled filesystem tools
Restrict the enabled filesystem tools
The
tools allowlist on FilesystemMiddleware requires deepagents>=0.7.FilesystemMiddleware with a tools allowlist to expose only a subset of the filesystem tools to the model, instead of the full default set.Customize how the skill catalog appears in the system prompt
Customize how the skill catalog appears in the system prompt
Override Do not also pass
SkillsMiddleware with a custom system_prompt= template to control how
the auto-generated skill catalog is framed — for example, to add surrounding context,
reorder sections, or place routing hints (priorities, category bias) in the same
block as the catalog. The template must include the {skills_locations},
{skills_list}, and {skills_load_warnings} slots, which the middleware substitutes
on every turn — so the catalog stays in sync automatically as skills are added,
renamed, or removed.The example below places routing hints alongside the catalog:skills= to create_deep_agent in this case: the override instance
already owns backend and sources. Any missing slot ({skills_locations},
{skills_list}, {skills_load_warnings}) raises ValueError at construction time.Suppress the auto-generated skill catalog
Suppress the auto-generated skill catalog
Override Skill names, paths, and any hand-written hints in
SkillsMiddleware with system_prompt=None to load skills without
appending a skills section to the system prompt at all. Skills remain in
state["skills_metadata"] and skill files stay reachable through the filesystem
tools, so callers who prefer to write their own description block (for example, a
compact hand-written routing summary) in create_deep_agent(system_prompt=...) can
add exactly the guidance they need without the built-in one.create_deep_agent’s system_prompt
are the caller’s responsibility to keep in sync when skills change.Interpreters
Use interpreters to add aneval tool that runs JavaScript in a scoped QuickJS runtime. Interpreters are useful when the agent needs to compose tools programmatically, batch work, handle errors in code, or transform structured data without a full shell environment.
Subagents
To isolate detailed work and avoid context bloat, use subagents:Backends
Tools for a deep agent can make use of virtual file systems to store, access, and edit files. By default, deep agents use aStateBackend.
If you are using skills or memory, you must add the expected skill or memory files to the backend before creating the agent.
- StateBackend
- FilesystemBackend
- LocalShellBackend
- StoreBackend
- ContextHubBackend
- CompositeBackend
A thread-scoped filesystem backend stored in
langgraph state.Files persist across turns within a thread (via your checkpointer) and are not shared across threads.Sandboxes
Sandboxes are specialized backends that run agent code in an isolated environment with their own filesystem and anexecute tool for shell commands.
Use a sandbox backend when you want your deep agent to write files, install dependencies, and run commands without changing anything on your local machine.
You configure sandboxes by passing a sandbox backend to backend when creating your deep agent:
- LangSmith
- Daytona
- E2B
- Modal
- Runloop
- Vercel
Human-in-the-loop
Some tool operations may be sensitive and require human approval before execution. You can configure the approval for each tool:Skills
You can use skills to provide your deep agent with new capabilities and expertise. While tools tend to cover lower level functionality like native file system actions, skills can contain detailed instructions on how to complete tasks, reference info, and other assets, such as templates. These files are only loaded by the agent when the agent has determined that the skill is useful for the current prompt. This progressive disclosure reduces the amount of tokens and context the agent has to consider upon startup. For example skills, see Deep Agents example skills. To add skills to your deep agent, pass them as an argument tocreate_deep_agent:
- StateBackend
- StoreBackend
- FilesystemBackend
Memory
UseAGENTS.md files to provide extra context to your deep agent.
You can pass one or more file paths to the memory parameter when creating your deep agent:
- StateBackend
- StoreBackend
- FilesystemBackend
Profiles
A harness profile is a reusable bundle of per-model configuration thatcreate_deep_agent applies automatically when the matching model is selected. Profiles are the right tool when you want behaviour that follows the model—not the call site—such as a system prompt suffix tuned for Claude’s instruction style, tool descriptions rewritten for GPT, or extra middleware that only makes sense with a specific provider.
A single profile can carry: a custom base system prompt (base_system_prompt), an appended suffix (system_prompt_suffix), tool description overrides, tools or middleware to exclude, additional middleware to inject, and edits to the auto-added general-purpose subagent.
Structured output
Deep Agents support structured output. You can set a desired structured output schema by passing it as theresponse_format argument to the call to create_deep_agent().
When the model generates the structured data, it’s captured, validated, and returned in the ‘structured_response’ key of the deep agent’s state.
View example trace
Open a public LangSmith run for this example.
Advanced
create_deep_agent pre-assembles a middleware stack on top of create_agent. To build a fully custom agent—choosing exactly which capabilities to include—see Configure the harness.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

