Skip to main content
Deep Agents can create subagents to delegate work. You can specify custom subagents in the subagents parameter. Subagents are useful for context quarantine (keeping the main agent’s context clean) and for providing specialized instructions.

Why use subagents?

Subagents solve the context bloat problem. When agents use tools with large outputs (web search, file reads, database queries), the context window fills up quickly with intermediate results. Subagents isolate this detailed work—the main agent receives only the final result, not the dozens of tool calls that produced it. When to use subagents:
  • ✅ Multi-step tasks that would clutter the main agent’s context
  • ✅ Specialized domains that need custom instructions or tools
  • ✅ Tasks requiring different model capabilities
  • ✅ When you want to keep the main agent focused on high-level coordination
When NOT to use subagents:
  • ❌ Simple, single-step tasks
  • ❌ When you need to maintain intermediate context
  • ❌ When the overhead outweighs benefits

Configuration

subagents should be a list of dictionaries or CompiledSubAgent objects. There are two types:

SubAgent (Dictionary-based)

For most use cases, define subagents as dictionaries with the following fields:
CLI users: You can also define subagents as AGENTS.md files on disk instead of in code. The name, description, and model fields map to YAML frontmatter, and the markdown body becomes the system_prompt. See Custom subagents for the file format.

CompiledSubAgent

For complex workflows, use a prebuilt LangGraph graph:

Using SubAgent

Using CompiledSubAgent

For more complex use cases, you can provide your custom subagents. You can create a custom subagent using LangChain’s create_agent or by making a custom LangGraph graph using the graph API. If you’re creating a custom LangGraph graph, make sure that the graph has a state key called "messages":

Streaming

When streaming tracing information agents’ names are available as lc_agent_name in metadata. When reviewing tracing information, you can use this metadata to differentiate which agent the data came from. The following example creates a deep agent with the name main-agent and a subagent with the name research-agent:
As you prompt your deepagents, all agent runs executed by a subagent or deep agent will have the agent name in their metadata. In this case the subagent with the name "research-agent", will have {'lc_agent_name': 'research-agent'} in any associated agent run metadata: LangSmith Example trace showing the metadata

Structured output

All subagents support structured output which you can use to validate the subagent’s output. You can set a desired structured output schema by passing it as the response_format argument to the call to create_agent(). When the model generates the structured data, it’s captured and validated. The structured object itself is not returned to the parent agent. When using structured output with subagents, include the structured data in the ToolMessage. For more information, see response format.

The general-purpose subagent

In addition to any user-defined subagents, Deep Agents have access to a general-purpose subagent at all times. This subagent:
  • Has the same system prompt as the main agent
  • Has access to all the same tools
  • Uses the same model (unless overridden)
  • Inherits skills from the main agent (when skills are configured)

Override the general-purpose subagent

Include a subagent with name="general-purpose" in your subagents list to replace the default. Use this to configure a different model, tools, or system prompt for the general-purpose subagent:
When you provide a subagent with the general-purpose name, the default general-purpose subagent is not added. Your spec fully replaces it.

When to use it

The general-purpose subagent is ideal for context isolation without specialized behavior. The main agent can delegate a complex multi-step task to this subagent and get a concise result back without bloat from intermediate tool calls.

Example

Instead of the main agent making 10 web searches and filling its context with results, it delegates to the general-purpose subagent: task(name="general-purpose", task="Research quantum computing trends"). The subagent performs all the searches internally and returns only a summary.

Skills inheritance

When configuring skills with create_deep_agent:
  • General-purpose subagent: Automatically inherits skills from the main agent
  • Custom subagents: Do NOT inherit skills by default—use the skills parameter to give them their own skills
Only subagents configured with skills get a SkillsMiddleware instance—custom subagents without a skills parameter do not. When present, skill state is fully isolated in both directions: the parent’s skills are not visible to the child, and the child’s skills are not propagated back to the parent.

Best practices

Write clear descriptions

The main agent uses descriptions to decide which subagent to call. Be specific: Good: "Analyzes financial data and generates investment insights with confidence scores" Bad: "Does finance stuff"

Keep system prompts detailed

Include specific guidance on how to use tools and format outputs:

Minimize tool sets

Only give subagents the tools they need. This improves focus and security:

Choose models by task

Different models excel at different tasks:

Return concise results

Instruct subagents to return summaries, not raw data:

Common patterns

Multiple specialized subagents

Create specialized subagents for different domains:
Workflow:
  1. Main agent creates high-level plan
  2. Delegates data collection to data-collector
  3. Passes results to data-analyzer
  4. Sends insights to report-writer
  5. Compiles final output
Each subagent works with clean context focused only on its task.

Context management

When you invoke a parent agent with runtime context, that context automatically propagates to all subagents. The parent’s full config (including context) is passed through to each subagent invocation internally. This means tools running inside any subagent can access the same context values you provided to the parent:

Per-subagent context

All subagents receive the same parent context. To pass configuration that is specific to a particular subagent, use namespaced keys: prefix context keys with the subagent’s name:
Then read the relevant keys inside tools:

Identifying which subagent called a tool

When the same tool is shared between the parent and multiple subagents, you can use the lc_agent_name metadata (the same value used in streaming) to determine which agent initiated the call:
You can combine both patterns—use namespaced context for agent-specific configuration and lc_agent_name metadata for branching tool behavior:

Troubleshooting

Subagent not being called

Problem: Main agent tries to do work itself instead of delegating. Solutions:
  1. Make descriptions more specific:
  2. Instruct main agent to delegate:

Context still getting bloated

Problem: Context fills up despite using subagents. Solutions:
  1. Instruct subagent to return concise results:
  2. Use filesystem for large data:

Wrong subagent being selected

Problem: Main agent calls inappropriate subagent for the task. Solution: Differentiate subagents clearly in descriptions: