Context Isolation with Subagents
In the previous strategies we covered how to write context into memory files, how Claude Code retrieves context intelligently, and how compression keeps the context window from overflowing. All three strategies operate inside a single conversation — one context window shared by every task you give to Claude.
But what happens when a single conversation tries to do too many things at once? You ask Claude to search through fifty files for a security vulnerability, and suddenly the context is flooded with search results. You then ask it to refactor a component, but the model is now distracted by irrelevant file contents from the previous task. This is context confusion in action — and compression alone cannot always solve it.
The fourth strategy is context isolation: instead of running everything in one context window, you delegate specific tasks to subagents — specialized AI assistants that each run in their own, independent context window. When a subagent finishes, only its final result flows back to your main conversation. The thousands of intermediate tokens it consumed stay behind, isolated from your primary context.
This article explains what subagents are, why context isolation matters, how Claude Code implements subagents, and how you can create your own custom subagents to keep your conversations clean and effective.
1. Why Context Isolation Matters
The Problem: Context Contamination
Imagine you are debugging a complex issue. You ask Claude to search through your codebase for all usages of a deprecated API. Claude calls its search tools, reads dozens of files, and returns a list of affected locations. Your context window now contains tens of thousands of tokens of file contents, search results, and tool call outputs.
Next, you ask Claude to write a migration plan. But the model is now working with a context window that is mostly filled with raw file contents from the search. This leftover context can:
- Distract the model — it pays attention to irrelevant file contents instead of focusing on the migration logic
- Consume token budget — less room for the actual reasoning and planning you need
- Cause confusion — old search results may conflict with the new task's requirements
We introduced these failure modes in the context engineering article: context confusion (irrelevant context steers the response) and context poisoning (incorrect or outdated information corrupts future outputs). Context isolation is a structural solution to both problems.
The Solution: Divide and Isolate
Instead of running every task in one shared context, you split tasks across independent context windows. Each subagent gets its own fresh context, performs its task, and sends back only the result. The main conversation never sees the intermediate noise.
Think of it like delegating work in a team. You do not need to sit in every meeting your team members attend. You give them a task, they do the research, and they report back with a summary. Your own working memory stays clean and focused.
Key insight: Subagents receive only their own system prompt (plus basic environment details like the working directory). They do not inherit the full Claude Code system prompt or the main conversation history. Each subagent invocation creates a new instance with completely fresh context.
2. What Are Subagents?
Definition
A subagent in Claude Code is a specialized AI assistant that handles a specific type of task. Each subagent runs in its own context window with:
- A custom system prompt — instructions that define its behavior and expertise
- Specific tool access — you can restrict which tools the subagent can use
- Independent permissions — the subagent operates within its own permission boundaries
- Its own model selection — you can choose a different model for the subagent (e.g., Haiku for fast read-only tasks)
When the main conversation delegates a task to a subagent, Claude Code creates a new instance, loads the subagent's system prompt, and lets it work independently. When the subagent finishes, its final response is passed back to the main conversation as a single message.
Foreground vs. Background Execution
Subagents can run in two modes:
| Mode | Behavior | When to Use |
|---|---|---|
| Foreground | Blocks the main conversation until the subagent completes | When you need the result before continuing |
| Background | Runs concurrently while the main conversation continues | When the task is independent and results can be merged later |
You can press Ctrl+B to send a currently running foreground subagent to the background.
Key Constraint
There is one important rule to remember: subagents cannot spawn other subagents. Only the main conversation can delegate to subagents. This prevents uncontrolled chains of delegation and keeps the architecture simple and predictable.
3. Built-in Subagents
Claude Code ships with several built-in subagents that are always available. You do not need to configure anything to use them.
Explore
The Explore subagent is designed for fast, read-only codebase exploration. It uses the Haiku model (which is faster and cheaper than Sonnet or Opus) and only has access to read-only tools like file reading and search. Use it when you need to answer questions about your codebase without modifying anything.
Plan
The Plan subagent helps you create structured implementation plans. It can research your codebase, analyze dependencies, and produce a step-by-step plan — all in an isolated context that keeps the planning artifacts separate from your main conversation.
General-Purpose
The built-in general-purpose subagent inherits the tools from the main conversation. It is useful for offloading a side task without creating a custom subagent — just delegate the task and get a clean result back.
4. Creating Custom Subagents
The real power of context isolation comes from creating your own subagents. A custom subagent is defined as a Markdown file with YAML frontmatter. The frontmatter configures the subagent's metadata (name, tools, model), and the Markdown body becomes the subagent's system prompt.
Creating a Subagent with the /agents Command
The fastest way to create a new subagent is to use the built-in /agents slash command inside Claude Code. It will guide you through an interactive setup process:
The Subagent File Format
Every custom subagent is a .md file with YAML frontmatter at the top. Here is the structure:
Frontmatter Fields Reference
The YAML frontmatter supports the following fields:
| Field | Required | Description |
|---|---|---|
name | Yes | The agent's identifier. Used for @-mentions and CLI invocation. |
description | Yes | What the agent does. Claude uses this to decide when to delegate automatically. |
model | No | Which model to use: sonnet, opus, haiku, a full model ID, or inherit (default). |
tools | No | Allowlist of tools. Only these tools will be available to the agent. |
disallowedTools | No | Denylist of tools. All tools except these will be available. |
permissionMode | No | Controls the agent's permission level (e.g., how it handles tool approval). |
maxTurns | No | Maximum number of LLM turns before the agent stops. |
memory | No | Persistent memory configuration with scopes: user, project, local. |
background | No | If true, the agent runs in the background by default. |
isolation | No | Set to worktree to give the agent an isolated copy of the repository. |
hooks | No | Lifecycle hooks (e.g., PreToolUse) to validate or filter tool calls. |
initialPrompt | No | The first message sent to the agent when it starts. |
Where Subagent Files Live
Subagent files are loaded from multiple locations, in priority order (highest first):
- Managed settings — configured by your organization (highest priority)
- CLI
--agentsflag — passed directly when starting Claude Code - Project scope —
.claude/agents/directory in your project (shared via Git) - User scope —
~/.claude/agents/directory (personal, applies to all projects) - Plugin agents — provided by installed plugins (lowest priority)
For most use cases, you will store subagents in the project scope (.claude/agents/) so they are shared with your team, or in the user scope (~/.claude/agents/) for personal agents that apply across all your projects.
5. Practical Examples
Let us walk through several practical subagent configurations. Each example shows a complete .md file that you can save into your .claude/agents/ directory and start using immediately.
Example 1: Code Reviewer (Read-Only)
This subagent reviews code without modifying anything. It only has access to read-only tools, which means it cannot accidentally change your files. This is a perfect example of using tool restrictions for safety.
Example 2: Test Writer
This subagent focuses exclusively on writing tests. It has access to file editing tools but is instructed to only create or modify test files.
Example 3: Database Reader (with Hooks)
This subagent can read from a database but uses a PreToolUse hook to prevent any write operations. Hooks add a safety layer by validating tool calls before they execute.
6. Delegating to Subagents
Once you have defined subagents, there are four ways to invoke them:
Method 1: Automatic Delegation
Claude reads the description field of all available subagents. When you give a task that matches a subagent's description, Claude will automatically delegate to it. This is the most seamless approach — you do not need to remember agent names.
Method 2: Natural Language Naming
You can mention the agent by name in your prompt:
Method 3: @-Mention Syntax
For explicit delegation, use the @ syntax followed by the agent's name in quotes:
Method 4: Session-Wide Agent (CLI Flag)
If you want an entire Claude Code session to run as a specific agent, use the --agent CLI flag:
CLI-Defined Subagents
You can also define subagents directly from the command line without creating a file, using the --agents flag (note the plural). This is useful for quick, one-off configurations:
7. Tool Control: Allowlists and Denylists
Controlling which tools a subagent can access is one of the most important aspects of context isolation. There are two approaches:
Allowlist (tools field)
When you specify a tools array, the subagent can only use those tools. Everything else is blocked. This is the safer, more restrictive approach.
Denylist (disallowedTools field)
When you specify disallowedTools, the subagent inherits all tools from the main conversation except the ones listed. This is more permissive — use it when you want to block a few specific tools.
If you specify neither tools nor disallowedTools, the subagent inherits all tools from the main conversation by default.
Fine-Grained Bash Control
You can restrict Bash access to specific commands using a prefix pattern:
This is useful when you want a subagent to use shell commands for searching but prevent it from running arbitrary scripts.
8. Persistent Memory for Subagents
By default, subagents are stateless — each invocation starts with a fresh context. But you can give subagents persistent memory so they can learn and improve across sessions.
Memory Scopes
The memory field in the frontmatter supports three scopes:
| Scope | Storage Location | Shared Across Projects? |
|---|---|---|
user | ~/.claude/agent-memory/ | Yes — applies to all projects |
project | .claude/agent-memory/ | No — project-specific, shareable via Git |
local | .claude/agent-memory-local/ | No — personal and local only |
With persistent memory enabled, the code reviewer can remember patterns it has flagged before, project-specific conventions it has learned, and avoid repeating the same suggestions.
9. Worktree Isolation
For subagents that modify files, there is an additional level of isolation: worktree isolation. When you set isolation: worktree in the frontmatter, Claude Code creates an isolated copy of your repository (using git worktree) for the subagent to work in.
This means the subagent can freely modify files without affecting your working directory. If the refactoring goes wrong, your original files are untouched. This is especially useful for risky operations like large-scale refactoring or experimental changes.
10. Common Patterns
Pattern 1: Isolate High-Volume Operations
When a task generates a lot of output (searching through hundreds of files, reading large logs, analyzing test results), delegate it to a subagent. The main conversation receives only the summary.
Pattern 2: Parallel Research
You can run multiple subagents in the background simultaneously. Each researches a different aspect of a problem, and their results are merged in the main conversation.
Pattern 3: Sequential Chaining
Use one subagent's output as input for the next. This creates a pipeline where each step runs in isolation but the results flow forward.
Pattern 4: Safety-Restricted Operations
Create subagents with strict tool restrictions for operations where you want to prevent accidental modifications. The code-reviewer and db-reader examples above both follow this pattern.
11. When to Use Subagents vs. the Main Conversation
Subagents are powerful, but they are not the right choice for every task. Here is a decision guide:
| Use Subagents When… | Use the Main Conversation When… |
|---|---|
| The task generates a lot of output (search results, logs, file contents) | You need iterative back-and-forth refinement |
| You want to restrict tool access for safety | The task requires context from earlier in the conversation |
| The task is self-contained and does not need conversation history | It is a quick, simple change |
| You want to run multiple tasks in parallel | You need to see intermediate results and adjust direction |
| You want to use a different model (e.g., Haiku for fast lookups) | The task builds on shared context across multiple phases |
Rule of thumb: If the task would flood your context with information you do not need for the rest of the conversation, use a subagent. If you need to iterate on the results interactively, keep it in the main conversation.
12. Putting It All Together
Let us build a practical team of subagents for a typical web application project. Create these files in your project's .claude/agents/ directory:
Project Structure
Workflow Example
Here is how you might use these agents together during a typical development session:
- Start with research: "Use the researcher agent to find all authentication-related code" — the researcher explores the codebase in its own context and returns a summary.
- Review the code: "Ask the code-reviewer to check the auth module for security issues" — the reviewer analyzes the code in its own isolated context and reports findings.
- Make changes: In the main conversation, implement the fixes based on the reviewer's report.
- Write tests: "Have the test-writer create tests for the updated auth module" — the test writer works in its own context, reading the updated files and generating tests.
- Verify data: "Ask the db-reader to check if any user sessions are affected" — the database reader safely queries the database without risk of modifying data.
At each step, the subagent works in isolation. Your main conversation stays clean and focused, containing only the summaries and results you need to make decisions.
Summary
Context isolation with subagents is the fourth strategy in our context engineering toolkit. While writing context, retrieving context, and compressing context all operate within a single context window, subagents give you the ability to create multiple independent context windows that work in parallel or sequence without contaminating each other.
The key takeaways:
- Subagents run in isolated context windows — they do not inherit the main conversation's history
- Each subagent gets a custom system prompt, tool restrictions, and can use a different model
- Custom subagents are defined as Markdown files with YAML frontmatter stored in
.claude/agents/ - Use tool allowlists/denylists to enforce safety boundaries
- Delegate high-volume, self-contained tasks to subagents to keep your main context clean
- Subagents cannot spawn other subagents — only the main conversation can delegate