Skip to main content
Build the harness around your goal. 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.
For the full parameter list, see the 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.
As you add tools, subagents, and backends, use LangSmith to trace how each piece behaves together. Follow the observability quickstart to get set up, and see Going to production for deployment on LangSmith.We recommend you also set up LangSmith Engine, which monitors your traces, detects issues, and proposes fixes.

Model

Pass a model string in provider:model format, or an initialized model instance. See supported models for all providers and suggested models for tested recommendations.
Use the provider:model format (for example openai:gpt-5.5) to quickly switch between models.
👉 Read the OpenAI chat model integration docs
Chat models automatically retry transient API failures (with exponential backoff). For defaults, limits, and code samples for tuning max_retries / timeout live on the LangChain Models page.

Tools

In addition to built-in tools for planning, file management, and subagent spawning, you can provide custom tools:

MCP tools

Deep Agents fully support Model Context Protocol (MCP) tools. You can load tools from any MCP server—databases, APIs, file systems, and more—and pass them directly to create_deep_agent.
Install langchain-mcp-adapters to connect to MCP servers:
For detailed configuration options including stdio servers, OAuth authentication, tool filtering, and stateful sessions, see the full MCP guide.

System prompt

Deep Agents ship with a built-in base system prompt that teaches the agent how to use the harness scaffolding (planning, filesystem tools, subagents). Pass system_prompt= to prepend your own instructions before that base prompt:
When middleware adds special tools, like the filesystem tools, it appends its own guidance to the system prompt at runtime.
SystemPromptConfig requires deepagents>=0.7.0a6.
For full control over prompt assembly, pass a SystemPromptConfig dict with prefix, base, and suffix keys:
  • prefix: text placed before the base prompt (same as passing a bare string).
  • base: replaces the built-in base prompt. Omit the key to keep the built-in base, or set it to None to drop the base entirely.
  • suffix: text placed after the base prompt.
Parts are assembled in order: prefix -> base -> suffix -> any model-specific profile suffix. Each part accepts a str or a SystemMessage (to preserve cache_control markers for Anthropic prompt caching).
For model-specific system prompt customization, such as replacing the base prompt or appending a suffix for a particular provider, use a harness profile.
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.
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 the middleware argument of create_deep_agent. Each instance is merged into the default stack by matching its .name against the defaults already in the stack: a match replaces the default instance in place, and anything that does not match is inserted after PatchToolCallsMiddleware. See Override a default middleware instance. By default, Deep Agents have access to the following middleware:

Default stack (main agent)

From first to last:
  1. TodoListMiddleware: Tracks and manages todo lists for organizing agent tasks and work.
  2. SkillsMiddleware: Only when you pass skills. Injected immediately after the todo middleware and before filesystem middleware so skill metadata is available before file tools run.
  3. FilesystemMiddleware: Handles file system operations such as reading, writing, and navigating directories. When you pass permissions, filesystem permissions enforcement is included here so it can evaluate every tool the agent might call.
  4. SubAgentMiddleware: Spawns and coordinates subagents for delegating tasks to specialized agents.
  5. SummarizationMiddleware: Condenses message history to stay within context limits when conversations grow long (via create_summarization_middleware).
  6. 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.
  7. AsyncSubAgentMiddleware: Only when you configure async subagents.
  8. Your middleware argument: Optional middleware you pass as the middleware argument is merged after Patch but before the rest of the stack. An instance whose .name matches one of the defaults above replaces that default in place instead of duplicating it; anything else lands here. See Override a default middleware instance.
  9. Harness profile extras: Provider-specific middleware from the resolved model profile, if any.
  10. Excluded-tool filtering: When the harness profile lists excluded tools, middleware removes those tools from the agent.
  11. Prompt caching (AnthropicPromptCachingMiddleware and BedrockPromptCachingMiddleware): 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.
  12. MemoryMiddleware: Only when you pass memory.
    MemoryMiddleware is 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 the create_deep_agent implementation comments.
  13. HumanInTheLoopMiddleware: Only when you pass interrupt_on. Pauses for human approval or input at configured tool calls.

Default stack (synchronous subagents)

The built-in general-purpose subagent and each declarative synchronous SubAgent graph use a stack that create_deep_agent builds in code. It matches the main agent in broad shape (todo list, filesystem, summarization, Patch, profile extras, Anthropic and Bedrock caching, optional permissions) but differs in two ways:
  • Skills run after PatchToolCallsMiddleware on these inner agents (on the main agent, skills run before filesystem middleware when skills is set).
  • There is no SubAgentMiddleware inside a subagent graph (only the parent agent exposes the task tool).
When a declarative subagent sets 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. The deepagents 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 Official integrations and Community integrations.

Custom middleware

You can provide additional middleware to extend functionality, add tools, or implement custom hooks:
Do not mutate attributes after initializationIf you need to track values across hook invocations (for example, counters or accumulated data), use graph state. Graph state is scoped to a thread by design, so updates are safe under concurrency.Do this:
Do not do this:
Mutation in place, such as modifying self.x in before_agent or changing other shared values in hooks, can lead to subtle bugs and race conditions because many operations run concurrently (subagents, parallel tools, and parallel invocations on different threads).For full details on extending state with custom properties, see Custom middleware - Custom state schema.If you must use mutation in custom middleware, consider what happens when subagents, parallel tools, or concurrent agent invocations run at the same time.

Override a default middleware instance

Overriding a default middleware by matching .name requires deepagents>=0.7.0a3.
Pass a middleware instance whose .name matches an entry in the default stack, such as SummarizationMiddleware, to replace that default in place instead of appending a duplicate. Any middleware you pass whose .name does not match a default is not replaced, it lands after the last core middleware entry and before the profile, prompt-caching, and memory. See Default stack (main agent) for the full 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.
The general-purpose subagent, which Deep Agents adds automatically, inherits overrides for its default middleware from the main agent, without carrying over middleware that’s specific to the main agent. Declarative subagents defined via 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 subagent’s own default stack, the same way middleware= is matched against the main agent’s.

Examples

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.
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.
Override FilesystemMiddleware with a system_prompt to replace the filesystem-specific instructions it appends to the system prompt in place of the dynamically generated default.
As with any FilesystemMiddleware override, pass the same backend (and permissions, if applicable) used elsewhere, since the override is not merged with the default.
Override SubAgentMiddleware with a task_description to replace the task tool’s description, for example to steer the model on when to delegate. The override replaces the default stack outright, so redeclare the same backend and subagents passed to create_deep_agent. The auto-added general-purpose subagent is not included unless you add an equivalent entry yourself.
task_description also supports an available_agents template placeholder that is filled in with the subagent name and description list; see the SubAgentMiddleware reference for details. For a narrower change that only rewords the task tool description without replacing the subagent stack, use a harness profile’s tool_description_overrides instead; see Profiles.

Interpreters

Use interpreters to add an eval 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.
For setup, programmatic tool calling, subagent orchestration, and limits, see Interpreters.

Subagents

To isolate detailed work and avoid context bloat, use subagents:
For more information, see 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 a StateBackend. If you are using skills or memory, you must add the expected skill or memory files to the backend before creating the agent.
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.
For more information, see Backends.

Sandboxes

Sandboxes are specialized backends that run agent code in an isolated environment with their own filesystem and an execute 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:
For more information, see Sandboxes.

Human-in-the-loop

Some tool operations may be sensitive and require human approval before execution. You can configure the approval for each tool:
You can configure interrupt for agents and subagents on tool call as well as from within tool calls. For more information, see Human-in-the-loop.

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 or planning, 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 to create_deep_agent:

Memory

Use AGENTS.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:

Profiles

A harness profile is a reusable bundle of per-model configuration that create_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.
See Profiles for registration keys, merge semantics, and plugin packaging. A narrower companion API, provider profiles, packages model-construction arguments (API keys, timeouts, retry settings) for a provider.

Structured output

Deep Agents support structured output. You can set a desired structured output schema by passing it as the response_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.
For more information and examples, see response format.

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.