Claude Code Foundations of Context Engineering Created: 13 Apr 2026 Updated: 13 Apr 2026

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:

  1. Distract the model — it pays attention to irrelevant file contents instead of focusing on the migration logic
  2. Consume token budget — less room for the actual reasoning and planning you need
  3. 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:

  1. A custom system prompt — instructions that define its behavior and expertise
  2. Specific tool access — you can restrict which tools the subagent can use
  3. Independent permissions — the subagent operates within its own permission boundaries
  4. 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:

ModeBehaviorWhen to Use
ForegroundBlocks the main conversation until the subagent completesWhen you need the result before continuing
BackgroundRuns concurrently while the main conversation continuesWhen 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.

# In Claude Code, you can invoke the Explore subagent by asking:
"Use the Explore agent to find all files that import the UserService class"

# Or use @-mention syntax:
@Explore "Find all usages of the deprecated calculateTotal function"

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:

# In Claude Code, type:
/agents

# Claude will ask you:
# 1. What should the agent be called?
# 2. What should it do? (becomes the description and system prompt)
# 3. What tools should it have access to?
# 4. Where should it be saved? (project or user scope)

The Subagent File Format

Every custom subagent is a .md file with YAML frontmatter at the top. Here is the structure:

---
name: agent-name
description: A short description of what this agent does (used for automatic delegation)
model: sonnet
tools:
- Read
- Grep
- Glob
- Bash
---

# System Prompt

You are a specialist agent. Your job is to...

## Rules

1. Always do X before Y
2. Never modify files directly
3. Report findings in a structured format

Frontmatter Fields Reference

The YAML frontmatter supports the following fields:

FieldRequiredDescription
nameYesThe agent's identifier. Used for @-mentions and CLI invocation.
descriptionYesWhat the agent does. Claude uses this to decide when to delegate automatically.
modelNoWhich model to use: sonnet, opus, haiku, a full model ID, or inherit (default).
toolsNoAllowlist of tools. Only these tools will be available to the agent.
disallowedToolsNoDenylist of tools. All tools except these will be available.
permissionModeNoControls the agent's permission level (e.g., how it handles tool approval).
maxTurnsNoMaximum number of LLM turns before the agent stops.
memoryNoPersistent memory configuration with scopes: user, project, local.
backgroundNoIf true, the agent runs in the background by default.
isolationNoSet to worktree to give the agent an isolated copy of the repository.
hooksNoLifecycle hooks (e.g., PreToolUse) to validate or filter tool calls.
initialPromptNoThe 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):

  1. Managed settings — configured by your organization (highest priority)
  2. CLI --agents flag — passed directly when starting Claude Code
  3. Project scope.claude/agents/ directory in your project (shared via Git)
  4. User scope~/.claude/agents/ directory (personal, applies to all projects)
  5. 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.

---
name: code-reviewer
description: Reviews code for bugs, style issues, and best practices. Read-only — never modifies files.
model: sonnet
tools:
- Read
- Grep
- Glob
- Bash(grep:*)
- Bash(find:*)
- Bash(wc:*)
---

You are a senior code reviewer. Your job is to review code for:

1. Bugs and logic errors
2. Security vulnerabilities (OWASP Top 10)
3. Code style and readability issues
4. Performance concerns

## Rules

- Never suggest modifying files directly — only report findings
- Categorize issues by severity: Critical, Warning, Info
- Include file paths and line numbers for every finding
- Provide a summary at the end with total counts per severity

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.

---
name: test-writer
description: Writes unit and integration tests for the codebase. Analyzes source code and creates comprehensive test suites.
model: sonnet
tools:
- Read
- Write
- Edit
- Grep
- Glob
- Bash
---

You are a testing specialist. Your job is to write comprehensive tests.

## Process

1. First, read the source file to understand the code
2. Identify all public functions, edge cases, and error paths
3. Write tests that cover: happy path, edge cases, error handling
4. Use the project's existing test framework and patterns

## Rules

- Only create or modify files in test directories
- Follow existing naming conventions for test files
- Each test should have a clear, descriptive name
- Include comments explaining what each test validates

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.

---
name: db-reader
description: Queries the database for information. Read-only — blocks any write operations.
model: sonnet
tools:
- Bash
- Read
hooks:
PreToolUse:
- matcher: Bash
hooks:
- type: command
command: |
if echo "$TOOL_INPUT" | grep -iE '(INSERT|UPDATE|DELETE|DROP|ALTER|TRUNCATE|CREATE)' > /dev/null; then
echo '{"decision": "block", "reason": "Write operations are not allowed"}'
else
echo '{"decision": "approve"}'
fi
---

You are a database analyst. You can query the database to answer questions about data.

## Rules

- Only use SELECT queries — never modify data
- Always use LIMIT clauses to avoid returning too many rows
- Explain your query logic before running it
- Format results in readable tables

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.

# Just ask naturally. Claude will route to the code-reviewer agent:
"Review the authentication module for security issues"

# Claude will route to the test-writer agent:
"Write tests for the PaymentService class"

Method 2: Natural Language Naming

You can mention the agent by name in your prompt:

"Ask the code-reviewer to check src/auth/ for vulnerabilities"
"Have the test-writer create tests for the new API endpoints"

Method 3: @-Mention Syntax

For explicit delegation, use the @ syntax followed by the agent's name in quotes:

@"code-reviewer" "Review the changes in the last commit"
@"test-writer" "Write integration tests for the UserController"

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:

# Start Claude Code as the code-reviewer agent for the entire session:
claude --agent code-reviewer

# The entire session will use the code-reviewer's system prompt and tool restrictions

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:

claude --agents '{
"quick-reviewer": {
"description": "Quick code review for a single file",
"prompt": "Review the given file for obvious bugs. Be concise.",
"tools": ["Read", "Grep", "Glob"],
"model": "haiku"
}
}'

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.

---
name: researcher
description: Searches the codebase for information
tools:
- Read
- Grep
- Glob
---

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.

---
name: safe-editor
description: Edits code but cannot run shell commands
disallowedTools:
- Bash
---

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:

tools:
- Bash(grep:*) # Only allow grep commands
- Bash(find:*) # Only allow find commands
- Bash(cat:*) # Only allow cat commands

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:

ScopeStorage LocationShared 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
---
name: code-reviewer
description: Reviews code with persistent memory of past findings
memory:
- project
- user
---

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.

---
name: refactorer
description: Performs large-scale refactoring in an isolated worktree
isolation: worktree
tools:
- Read
- Write
- Edit
- Grep
- Glob
- Bash
---

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.

# Instead of flooding your main context:
"Search all files for deprecated API calls and give me a summary"

# Claude delegates to a subagent that:
# 1. Searches through hundreds of files (generates thousands of tokens internally)
# 2. Compiles a summary of findings
# 3. Returns ONLY the summary to the main conversation

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.

# Ask Claude to research in parallel:
"I need to understand this bug. In parallel:
1. Search for all recent changes to the auth module
2. Check the error logs for related failures
3. Find the test coverage for the affected functions"

# Claude can dispatch three background subagents, each working independently

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.

# Step 1: Explore agent analyzes the codebase
# Step 2: Main conversation creates a plan based on the analysis
# Step 3: Test-writer agent creates tests based on the plan
# Each step runs in a clean context

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 safetyThe task requires context from earlier in the conversation
The task is self-contained and does not need conversation historyIt is a quick, simple change
You want to run multiple tasks in parallelYou 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

.claude/
agents/
code-reviewer.md # Read-only code review
test-writer.md # Creates and updates tests
db-reader.md # Safe database queries
researcher.md # Codebase exploration

Workflow Example

Here is how you might use these agents together during a typical development session:

  1. 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.
  2. 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.
  3. Make changes: In the main conversation, implement the fixes based on the reviewer's report.
  4. 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.
  5. 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:

  1. Subagents run in isolated context windows — they do not inherit the main conversation's history
  2. Each subagent gets a custom system prompt, tool restrictions, and can use a different model
  3. Custom subagents are defined as Markdown files with YAML frontmatter stored in .claude/agents/
  4. Use tool allowlists/denylists to enforce safety boundaries
  5. Delegate high-volume, self-contained tasks to subagents to keep your main context clean
  6. Subagents cannot spawn other subagents — only the main conversation can delegate


Share this lesson: