Introduction to Subagents — Claude Code Certification Study Guide
Table of Contents
- Introduction to Subagents — Claude Code Certification Study Guide
- Table of Contents
- Module 1 — What Are Subagents?
- Module 2 — Creating a Subagent
- Module 3 — Designing Effective Subagents
- The Self-Contained Prompt Requirement
- Prompt Design Principles
- Complete Prompt Template
- Structured Output Templates — More Examples
- Error Reporting Requirements
- Tool Access Restrictions (Principle of Least Privilege)
- File Ownership Boundaries (Critical for Parallel Agents)
- Worktree Isolation — How Git Worktrees Work
- Key Exam Points
- Module 4 — Using Subagents Effectively
- Quick Reference
Introduction to Subagents — Claude Code Certification Study Guide
Course: Anthropic “Introduction to Subagents” | 4 Modules Last updated: 2026-04-26
Table of Contents
- Module 1 — What Are Subagents?
- Module 2 — Creating a Subagent
- Module 3 — Designing Effective Subagents
- Module 4 — Using Subagents Effectively
- Quick Reference
Module 1 — What Are Subagents?
Core Definition
A subagent is a separate Claude instance spawned from a parent Claude Code session. Each subagent:
- Has its own isolated context window — it does NOT share the parent’s conversation history
- Receives a prompt describing its specific task when spawned
- Returns a summary to the parent when complete
- Terminates after the task is finished
The Parent-Child Relationship
┌─────────────────────────────────────────────────────────────────┐
│ Subagent Architecture │
│ │
│ Parent Claude (main session, manages the workflow) │
│ │ │
│ ├── Subagent A (task: research auth patterns) │
│ │ Context: isolated, starts empty │
│ │ Returns: summary of findings ──────────────────┐ │
│ │ │ │
│ ├── Subagent B (task: review payments module) │ │
│ │ Context: isolated, starts empty │ │
│ │ Returns: list of issues ─────────────────────── ┤ │
│ │ │ │
│ └── Subagent C (task: write tests for auth) │ │
│ Context: isolated, starts empty │ │
│ Returns: test suite written ─────────────────── ┘ │
│ │
│ Parent receives all summaries and synthesizes results │
└─────────────────────────────────────────────────────────────────┘
Subagent Lifecycle
spawn ──► receive prompt ──► execute task (tools, reads, writes) ──► return result ──► terminate
│ │
│◄─────────────────── context window exists only during this window ───────────────────►│
The context window is created at spawn and discarded at termination. The only persistent output is what the agent writes to files or returns in its summary text.
Why Use Subagents?
| Reason | Explanation |
|---|---|
| Context isolation | Subagent reads large files without polluting parent’s context window |
| Parallel execution | Multiple subagents run simultaneously for independent tasks |
| Specialization | Each agent tuned for a specific role (reviewer, tester, researcher) |
| Context protection | Main session stays under token limits; subagents handle the heavy reads |
| Clean separation | Each subtask has its own reasoning trace, reducing noise |
| Longer total work | Chain of agents can do more total work than one session allows |
Context Window Management — The Core Problem
┌──────────────────────────────────────────────────────────────────┐
│ Without Subagents (Context Pollution) │
│ │
│ Main session context (200k tokens): │
│ ████████████████████████████████████████████████████ │
│ │conversation│read 20 files│analysis│read 30 more│ ...NO ROOM │
│ │
│ Result: main session runs out of context before the task ends │
└──────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────┐
│ With Subagents (Context Efficiency) │
│ │
│ Main session context: │
│ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ │conversation│[summary from agent A]│[summary from agent B]│ │
│ │
│ Subagent A context: reads 20 files → summarizes → terminates │
│ Subagent B context: reads 30 files → summarizes → terminates │
│ │
│ Result: main session stays lean; total work capacity multiplied │
└──────────────────────────────────────────────────────────────────┘
Subagent Inputs and Outputs
Inputs (what a subagent receives):
- The prompt text — the ONLY connection to parent context
- Tool access as defined by
allowed-tools - Access to the filesystem (same as parent, unless worktree isolated)
Outputs (what a subagent produces):
- Text summary returned to parent (the agent’s final message)
- Files written to disk (persists after termination)
- No other shared state with parent or sibling agents
Available Agent Types
| Type | Capabilities | Best For |
|---|---|---|
general | Full tool access (read, write, bash, edit) | Implementation tasks |
explore | Read-only (Read, Grep, Glob) | Codebase exploration |
plan | Architecture and design thinking | System design |
code-reviewer | Read, Grep, Glob + Bash (run tests) | Security/quality review |
tester | Full access + test runner focus | Writing and running test suites |
debugger | Full access + diagnostic tooling | Investigating failures |
researcher | Web search, file reading, synthesis | Gathering external knowledge |
Custom agent types are defined in .claude/agents/ — see Module 2.
Key Exam Points
- Subagents do NOT inherit parent context — you must provide all needed context in the prompt
- A subagent’s context window is independent and discarded after termination
- The summary returned to parent is the only text output that persists
- Files written by the subagent persist on disk after the agent terminates
- Subagents do not share state with sibling subagents
Module 2 — Creating a Subagent
The /agents Command
The /agents command creates custom agent definitions stored as markdown files.
- Location:
.claude/agents/agent-name.md - Each file defines one reusable agent type
- Frontmatter (YAML between
---delimiters) configures the agent - Body is the system prompt given to the agent at spawn
Agent Definition File Structure
---
name: agent-name
description: One-line description of what this agent does
allowed-tools: Read, Grep, Glob, Bash
model: claude-sonnet-4-5 # optional — defaults to parent model
context: fork # fork (isolated) or inherit (shares context)
---
# Agent Name
You are a [role]. Your job is to [purpose].
When given a task:
1. Step one — what to do first
2. Step two — how to proceed
3. Step three — how to finish
Output format:
[Describe exactly what format the response should take]
Error reporting:
[Describe how to handle and report failures]
Key Definition Fields
| Field | Purpose | Options / Notes |
|---|---|---|
name | Identifier used when spawning via subagent_type | kebab-case string |
description | One-line summary; used for routing by the harness | Plain text, be specific about the role |
allowed-tools | Restricts which tools the agent can use | Comma-separated tool names |
model | Which Claude model to use | Any valid model ID; defaults to parent model |
context | Whether agent inherits parent context | fork (isolated) or inherit |
Spawning via the Agent Tool (Programmatic)
Agent({
description: "Short task description for routing",
subagent_type: "code-reviewer", // built-in or custom agent name
prompt: "Review the auth module in src/auth/ for security issues.
Focus on: input validation, SQL injection, session handling.
Return: list of issues with severity and file:line references.",
run_in_background: false // true = non-blocking background execution
})
Foreground vs Background Agents
| Mode | run_in_background | Behavior | Use When |
|---|---|---|---|
| Foreground | false | Parent waits for completion before continuing | Next step depends on this result |
| Background | true | Parent continues; notified when agent finishes | Tasks are independent |
Use foreground when you need the result before proceeding (pipeline pattern). Use background when tasks are independent and you want parallel execution.
Sending Messages to Running Agents (SendMessage)
Use SendMessage to communicate with a background agent that is still running. This is useful for:
- Providing additional context mid-task
- Cancelling or redirecting the agent
- Asking for intermediate status
SendMessage({
agent_id: "agent-abc123",
message: "Also check the payment module when you're done with auth."
})
Important rules about SendMessage:
- Only works on background agents (
run_in_background: true) - Foreground agents cannot receive messages while running — they block the parent
- The agent receives the message as a new user turn in its context
- There is no guarantee the agent has reached a point where it can act on the message
// Pattern: spawn background agent, then refine mid-flight
let agentId = Agent({
description: "Reviewing codebase",
subagent_type: "code-reviewer",
prompt: "Review src/auth/ for security issues.",
run_in_background: true
})
// ... parent does other work ...
// Refine the scope while agent is still running
SendMessage({
agent_id: agentId,
message: "When you finish auth, also check src/payments/ before returning your report."
})
Custom Agent Examples
Security Auditor
---
name: security-auditor
description: Scans code for OWASP Top 10 vulnerabilities and security anti-patterns
allowed-tools: Read, Grep, Glob
context: fork
---
# Security Auditor
You are a security engineer specializing in application security and the OWASP Top 10.
Given a codebase path, you scan for vulnerabilities.
Process:
1. Glob for all source files in the given path (*.py, *.ts, *.js, *.go)
2. Read each file and check for:
- SQL injection (string concatenation in queries)
- XSS (unescaped output, innerHTML assignment)
- Hardcoded secrets (API keys, passwords, tokens in code)
- Insecure deserialization
- Broken authentication (JWT none algorithm, weak session tokens)
- Path traversal (user input used directly in file paths)
- Command injection (shell=True, exec/eval with user input)
3. For each finding, record: file path, line number, severity, description, recommended fix
Output format:
## Security Audit Report
### Critical Findings
- [CRITICAL] path/file.ts:42 — SQL injection via string concatenation
Fix: Use parameterized queries or ORM
### High Findings
- [HIGH] path/file.py:87 — Hardcoded API key in source code
Fix: Move to environment variable
### Summary
Total: X critical, Y high, Z medium, W low
Files scanned: N
Error handling: If a file cannot be read, log "SKIPPED: path/file — reason" and continue.
Test Writer
---
name: test-writer
description: Writes comprehensive unit tests for a given module or function
allowed-tools: Read, Grep, Glob, Write, Bash
context: fork
---
# Test Writer
You are a senior engineer who writes thorough, readable unit tests.
Given a source file or module path, you write tests that achieve high coverage.
Process:
1. Read the source file(s) to understand the API surface
2. Identify: all public functions, methods, classes, and their signatures
3. For each public API, design tests for:
- Happy path (expected input → expected output)
- Edge cases (empty input, boundary values, null/undefined)
- Error cases (invalid input, expected exceptions)
4. Write tests using the project's existing test framework
(check package.json, pytest.ini, or Cargo.toml to detect the framework)
5. Run tests with Bash to verify they pass
6. Report any tests that cannot pass with explanation
Output:
- Write test file to: {source_file_path.replace('.py', '_test.py')} or equivalent
- Final summary: N tests written, N passing, N failing (with failure explanations)
Migration Planner
---
name: migration-planner
description: Analyzes a codebase and produces a migration plan for a given change
allowed-tools: Read, Grep, Glob
context: fork
---
# Migration Planner
You are a senior architect who plans safe, incremental migrations.
Given a target change (e.g., "migrate from REST to GraphQL") and a codebase path:
Process:
1. Explore the codebase structure (Glob for key files, Read entry points)
2. Identify all affected components (callers, dependents, shared utilities)
3. Assess blast radius: which files must change, which might change, which are safe
4. Design a phased migration plan:
- Phase 1: Non-breaking preparation (add new alongside old)
- Phase 2: Incremental migration (migrate component by component)
- Phase 3: Cutover (switch traffic/usage to new system)
- Phase 4: Cleanup (remove old system)
5. Identify risks and mitigation strategies for each phase
Output format:
## Migration Plan: [change description]
### Blast Radius
- Must change: [N files, list top 5]
- May change: [N files, list top 5]
- Safe: [rest of codebase]
### Phases
[Phase table with description, files affected, rollback plan, estimated effort]
### Risks
[Risk table with severity, description, mitigation]
### Recommended Order
[Ordered list of specific files/components to migrate first]
API Documenter
---
name: api-documenter
description: Generates OpenAPI/markdown documentation from source code
allowed-tools: Read, Grep, Glob, Write
context: fork
---
# API Documenter
You are a technical writer who generates accurate API documentation from source code.
Given a module or router path, you produce documentation that developers actually want to read.
Process:
1. Glob for route/controller/handler files
2. For each endpoint, extract:
- HTTP method and path
- Request parameters (path, query, body) with types and validation rules
- Response format and status codes
- Authentication requirements
- JSDoc/docstring comments if present
3. Infer from code if comments are absent
4. Generate a single markdown file with all endpoints
Output: Write to docs/api/{module-name}.md
Endpoint template per API:
### POST /api/users
Creates a new user account.
**Auth:** Required (Bearer token)
**Request Body:**
| Field | Type | Required | Description |
|----------|--------|----------|--------------------|
| email | string | yes | User email address |
| password | string | yes | Min 8 characters |
**Responses:**
- `201 Created` — user object `{id, email, createdAt}`
- `400 Bad Request` — validation error
- `409 Conflict` — email already exists
Key Exam Points
- Agent definition files live in
.claude/agents/as markdown with YAML frontmatter context: forkis the default and preferred for isolation- Always specify
allowed-toolsto enforce principle of least privilege run_in_background: trueenables parallel execution patternsSendMessageonly works on background agents that are still running- The
descriptionfield is used for routing — make it specific
Module 3 — Designing Effective Subagents
The Self-Contained Prompt Requirement
Agents have NO context from the parent conversation. Every prompt must be self-contained:
| Include in Prompt | Do NOT Include |
|---|---|
| Absolute file paths | References to “what we discussed” |
| Specific line numbers | Assumptions about shared knowledge |
| Exact function/class names | Vague instructions like “fix things” |
| Expected output format | Open-ended exploration tasks |
| Success criteria | Implicit context from conversation |
| Error reporting instructions | Assumptions about project structure |
| Relevant constants or IDs | References to earlier agent results |
Prompt Design Principles
Self-contained — assume zero context:
Good: "Review /Users/project/src/auth/login.ts lines 45-120 for SQL injection vulnerabilities."
Bad: "Review the login file we were discussing for security issues."
Specific — include exact references:
Good: "Check the UserService.createUser() method in src/services/user-service.ts"
Bad: "Check the user creation code"
Bounded — define clear output format:
Good: "Return a JSON array: [{file, line, severity, description, suggestion}]"
Bad: "Tell me what you find"
Actionable — specify the action, not just the topic:
Good: "Read all .ts files in src/auth/, identify unused exports, write a list to STDOUT"
Bad: "Research which exports might be unused"
Error-aware — tell the agent what to do when things go wrong:
Good: "If any file cannot be read, log 'SKIPPED: {path} — {reason}' and continue with remaining files."
Bad: (no error handling instruction — agent may silently fail or stop early)
Complete Prompt Template
Task: [One-sentence description of what to accomplish]
Context:
- Repository root: /Users/alice/project
- Target module: src/payments/
- Related files: src/auth/session.ts (dependency)
Scope: [What to look at, what to ignore]
Steps:
1. [First action — be specific]
2. [Second action — be specific]
3. [Third action — be specific]
Output format:
## Summary
[1-2 sentence overview of what was found]
## Findings
- [severity: HIGH/MED/LOW] file:line — description — suggested fix
- ...
## Stats
- Files examined: N
- Issues found: N (X high, Y medium, Z low)
## Blockers
[Anything that prevented full analysis, or "None"]
Error handling:
- If a file cannot be read: log "SKIPPED: {path}" and continue
- If a dependency is missing: note it in Blockers and continue with what's available
- Do NOT silently skip findings or fail without reporting why
Structured Output Templates — More Examples
Code Review Template:
## Code Review: {module}
### Critical Issues (must fix before merge)
- [CRITICAL] src/auth.ts:42 — SQL injection via string concat
Current: `"SELECT * FROM users WHERE id = " + userId`
Fix: Use parameterized query: `db.query("SELECT * FROM users WHERE id = ?", [userId])`
### Warnings (should fix)
- [WARN] src/api.ts:88 — No input validation on user-supplied filename
### Notes (consider fixing)
- [NOTE] src/utils.ts:15 — Magic number 86400 should be named constant
### Summary
3 critical, 1 warning, 1 note across 4 files reviewed
Research Template:
## Research Report: {topic}
### Key Findings
1. [Finding 1 — specific and actionable]
2. [Finding 2]
### Options Considered
| Option | Pros | Cons | Recommendation |
|--------|------|------|----------------|
| A | ... | ... | ✓ Recommended |
| B | ... | ... | Not recommended|
### Recommended Approach
[Specific recommendation with rationale]
### Sources
- [file paths or URLs examined]
Error Reporting Requirements
Instruct agents explicitly on how to handle and report failures:
If you encounter errors:
- State what you attempted
- State the exact error message or failure mode
- State what you could not complete as a result
- Suggest a fix or workaround if one is obvious
Do NOT silently skip files or ignore failures.
Do NOT return an empty result — always explain what happened.
What silent failure looks like (bad):
Agent returns: "## Summary\nNo issues found."
Reality: Agent couldn't open any files due to wrong path and gave up silently
What good error reporting looks like:
Agent returns:
"## Summary
Could not complete analysis — path does not exist.
## Blockers
- FAILED: /Users/project/src/auth/ — directory not found
- Attempted paths: /Users/project/src/auth/, /Users/project/auth/
- Suggestion: Verify the path. Repository may be at /Users/project/backend/src/auth/"
Tool Access Restrictions (Principle of Least Privilege)
| Agent Role | Allowed Tools | Why Restricted |
|---|---|---|
| Explorer / Auditor | Read, Grep, Glob | Read-only — no side effects |
| Code Reviewer | Read, Grep, Glob, Bash | Needs to run tests to verify findings |
| Implementer | Read, Grep, Glob, Edit, Write, Bash | Full access for code changes |
| Documentation | Read, Grep, Glob, Write | Reads code, writes docs only |
| Researcher | Read, Glob, Grep, WebSearch, WebFetch | Needs external info gathering |
| Monitor | Read, Bash | Checks status, no writes needed |
Why restrict tools?
- Read-only agents cannot accidentally modify files
- Restricting Bash prevents unintended command execution
- Limiting Write prevents agents from creating files in wrong locations
- Minimal tool surface = smaller attack surface for prompt injection
File Ownership Boundaries (Critical for Parallel Agents)
When running multiple agents in parallel, each agent MUST own exclusive file sets:
┌────────────────────────────────────────────────────────────────┐
│ File Ownership for Parallel Agents │
│ │
│ Agent A Agent B Agent C │
│ owns: owns: owns: │
│ src/auth/** src/payments/** src/notifications/** │
│ │
│ SAFE: SAFE: SAFE: │
│ auth/login.ts payments/api.ts notif/sender.ts │
│ auth/session.ts payments/db.ts notif/queue.ts │
│ │
│ NEVER: NEVER: NEVER: │
│ payments/api.ts auth/login.ts auth/session.ts │
│ (would conflict with Agent B) (conflicts with Agent A) │
└────────────────────────────────────────────────────────────────┘
Lost writes happen silently:
Agent A reads user-service.ts → adds function A → writes file
Agent B reads user-service.ts → adds function B → writes file ← overwrites A's addition
Result: function A is LOST, no error reported
Enforce boundaries in the prompt:
"You may ONLY edit files under src/auth/.
Do NOT touch src/payments/, src/shared/, or any other directories.
If a file you need to edit is outside src/auth/, stop and report it as a blocker."
Worktree Isolation — How Git Worktrees Work
For safe parallel editing, use isolation: "worktree" in agent config. This creates a separate git worktree — a separate directory with its own working tree on a new branch.
┌────────────────────────────────────────────────────────────────┐
│ Git Worktree Isolation │
│ │
│ Main repo: /Users/alice/project (branch: main) │
│ │
│ Agent A worktree: │
│ Directory: /Users/alice/project-worktrees/agent-a/ │
│ Branch: agent-a/auth-refactor │
│ Changes: src/auth/login.ts (isolated) │
│ │
│ Agent B worktree: │
│ Directory: /Users/alice/project-worktrees/agent-b/ │
│ Branch: agent-b/payment-refactor │
│ Changes: src/payments/api.ts (isolated) │
│ │
│ After agents complete: │
│ 1. Review each agent's diff on its branch │
│ 2. Merge agent-a/auth-refactor → main │
│ 3. Merge agent-b/payment-refactor → main │
│ 4. Resolve any merge conflicts (unlikely if boundaries held) │
│ 5. Clean up worktrees: git worktree remove │
└────────────────────────────────────────────────────────────────┘
Worktree merge workflow:
# After agents complete, merge their branches
git merge agent-a/auth-refactor
git merge agent-b/payment-refactor
# If there are conflicts (shouldn't happen with good boundaries):
git mergetool
# Clean up worktrees
git worktree remove /Users/alice/project-worktrees/agent-a
git worktree remove /Users/alice/project-worktrees/agent-b
# Delete temporary branches
git branch -d agent-a/auth-refactor
git branch -d agent-b/payment-refactor
When to use worktree isolation:
- Parallel agents that MUST edit overlapping areas of the codebase
- Large refactors where file boundary enforcement is impractical
- When you want guaranteed isolation even if an agent exceeds its file boundary
When file boundary prompts are sufficient:
- Agents own clearly separate modules with no shared files
- Small-scope tasks where overlap is unlikely
- Exploration/read-only agents (no write conflicts possible)
Key Exam Points
- Every agent prompt must be fully self-contained — no inherited context
- Define output format explicitly to enable reliable result parsing
- Instruct agents to report errors clearly, never silently fail
- Use principle of least privilege for tool access
- File boundaries are mandatory for parallel write agents
- Worktree isolation uses separate git branches and directories per agent
- Worktree merge happens after all agents complete
Module 4 — Using Subagents Effectively
When TO Use Subagents
| Scenario | Why Subagent is Right |
|---|---|
| Research that reads 20+ files | Prevents context pollution in main session |
| Multiple independent tasks | Parallel execution saves wall-clock time |
| Specialized review (security, perf, a11y) | Dedicated context for that domain |
| Code generation that needs isolated testing | Test in clean context before accepting result |
| Long-running background monitoring | Non-blocking; parent continues other work |
| Task that would exhaust main session context | Subagent summarizes, parent stays lean |
| Work requiring domain expertise prompt | Load specialized system prompt without polluting |
When NOT to Use Subagents
| Scenario | Better Approach |
|---|---|
| Simple one-file question | Read the file directly in main session |
| Task that needs conversation history | Stay in main session where history is available |
| Very short task (fewer than 5 tool calls) | Overhead of spawning outweighs benefit |
| Tight feedback loop (iterative editing) | Stay in main session for faster iteration |
| Task needs partial results from parent context | Do it in-session where you have the context |
Rule of thumb: If the task is under 5 tool calls, just do it in the main session. Spawning has fixed overhead (context setup, prompt transmission, result parsing).
Cost and Token Analysis
When subagents SAVE tokens:
Scenario: Summarize 50 files for a refactor plan
Without subagents:
Main session reads 50 files = 500k input tokens
Main session stays polluted for the rest of the conversation
Total: 500k input tokens + all future conversation in polluted context
With a subagent:
Subagent reads 50 files (500k tokens) → summarizes to 2k tokens
Main session receives 2k token summary, stays lean
Total: 502k tokens, but main session is clean for future work
When subagents WASTE tokens:
Scenario: Check if a single function has a bug
Without subagents: 1 Read call = ~2k tokens
With subagent: spawn overhead + prompt + Read + return = ~8k tokens
Net waste: ~6k tokens for no benefit
Cost model (approximate):
Fixed spawn cost: ~2k tokens (prompt transmission overhead)
Minimum worthwhile: Tasks that would otherwise consume >10k tokens in main session
Break-even point: ~5 tool calls or ~10k tokens of work
Execution Patterns
Fan-Out / Fan-In (Parallel Research)
┌────────────────────────────────────────────────────────────────┐
│ Fan-Out / Fan-In Pattern │
│ │
│ Main session │
│ │ │
│ ├── SPAWN (background): Agent A ─ research auth libs │
│ ├── SPAWN (background): Agent B ─ research payment APIs │
│ └── SPAWN (background): Agent C ─ research notification │
│ ↓ all three run concurrently │
│ ┌──────────────────────────────────────────────┐ │
│ │ WAIT for all three to complete │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ └── SYNTHESIZE: read all three summaries → produce plan │
└────────────────────────────────────────────────────────────────┘
When to use: multiple independent research tasks can run simultaneously.
Prompt template for fan-out research agent:
Research Task: [specific topic]
Repository: /Users/project
Scope: src/[specific-module]/
Your job:
1. Read all relevant files in scope
2. Identify: [specific things to find]
3. Return a concise summary (max 500 words) covering:
- Current approach used
- Key dependencies (library names and versions)
- Patterns or anti-patterns observed
- Any obvious issues
Do NOT implement any changes. This is a read-only research task.
Pipeline (Sequential Handoff)
┌────────────────────────────────────────────────────────────────┐
│ Pipeline Pattern │
│ │
│ Agent A (gather requirements) ← run_in_background: false │
│ │ returns: requirements.md written to disk │
│ ▼ │
│ Agent B (generate code) ← run_in_background: false │
│ │ input: read requirements.md │
│ │ returns: code written to src/ │
│ ▼ │
│ Agent C (write tests) ← run_in_background: false │
│ │ input: read src/ to understand code │
│ │ returns: tests written to tests/ │
│ ▼ │
│ Main session (review + integrate) │
└────────────────────────────────────────────────────────────────┘
Key: Pipeline agents are foreground (run_in_background: false). Each must complete before the next starts.
Passing state between pipeline agents: Use the filesystem.
// Agent A writes its output to disk
Agent A prompt: "...Write your analysis to /Users/project/plans/requirements.md"
// Agent B reads Agent A's output
Agent B prompt: "Read /Users/project/plans/requirements.md for requirements,
then implement the code in /Users/project/src/..."
// Never pass large outputs as inline text in prompts — use files
Specialist Delegation
┌────────────────────────────────────────────────────────────────┐
│ Specialist Delegation Pattern │
│ │
│ Main session receives task │
│ │ │
│ ├── Is it a security concern? ──► spawn security-auditor │
│ │ (OWASP Top 10, auth issues) │
│ │ │
│ ├── Is it a performance issue? ──► spawn perf-analyzer │
│ │ (query analysis, profiling) │
│ │ │
│ ├── Is it a test failure? ──► spawn debugger │
│ │ (error trace analysis) │
│ │ │
│ └── Is it a docs gap? ──► spawn api-documenter │
│ (API documentation) │
└────────────────────────────────────────────────────────────────┘
Routing logic: The parent classifies the task and selects the most specialized agent type. This keeps main session logic clean and lets specialists use task-specific system prompts.
Background Monitoring
┌────────────────────────────────────────────────────────────────┐
│ Background Monitor Pattern │
│ │
│ Main session spawns monitor agent (run_in_background: true) │
│ │ │ │
│ │ continues other work │ polls CI/CD status │
│ │ (adds features, etc.) │ checks build logs │
│ │ │ watches for completion │
│ │ │ │
│ │◄─── notification ────────┘ "Build failed at step 3. │
│ on completion Error: test_auth.py:42" │
└────────────────────────────────────────────────────────────────┘
Monitor agent prompt template:
Monitor Task: Check CI/CD pipeline status for PR #142
Instructions:
1. Run: gh pr checks 142 --repo owner/repo
2. If all checks pass: report "PR #142 — all checks passing"
3. If any check fails: report the failing check name and the last 20 lines of its log
4. If still running: wait 30 seconds and check again (max 10 retries)
Return your final status report when checks either all pass or one fails.
Multi-Agent Coordination Patterns
Task List Coordination
When multiple agents work on related tasks, use a shared task list file:
// Main session creates task list before spawning agents
// File: /Users/project/plans/tasks.md
## Pending
- [ ] task-auth: Refactor authentication module (Agent A owns this)
- [ ] task-payments: Update payment API client (Agent B owns this)
- [ ] task-tests: Write tests for refactored modules (Agent C, after A+B done)
// Agents update task list when they start and finish:
Agent A prompt:
"When you begin: edit /Users/project/plans/tasks.md,
change '- [ ] task-auth' to '- [x] task-auth (in progress)'
When you finish: change to '- [x] task-auth (complete)'"
Result Aggregation
After parallel agents complete, the parent aggregates results:
// Parent spawns 3 parallel review agents
let agentA = Agent({...code review...})
let agentB = Agent({...security audit...})
let agentC = Agent({...performance analysis...})
// After all return, parent reads their file outputs
// Each agent was instructed to write to a specific file:
// /project/reviews/code-review.md
// /project/reviews/security-audit.md
// /project/reviews/perf-analysis.md
// Parent synthesizes:
"Read the three reports at:
- /project/reviews/code-review.md
- /project/reviews/security-audit.md
- /project/reviews/perf-analysis.md
Produce a single executive summary covering critical issues across all three."
Debugging Subagents
When an agent returns bad, incomplete, or unexpected results:
Step 1: Check if the prompt was self-contained
Did the prompt include:
[ ] Absolute file paths?
[ ] All context needed without the conversation history?
[ ] Clear output format instructions?
[ ] Error handling instructions?
Step 2: Check file paths
The most common failure: wrong paths.
Test manually: does the path exist? Is it absolute?
Step 3: Check tool access
Did the agent have the tools it needed?
An explore agent (Read, Grep, Glob) cannot run Bash commands.
A Read-only agent cannot write files.
Step 4: Reduce scope and re-spawn
Instead of: "Review all of src/"
Try: "Review src/auth/login.ts only"
Confirm the agent can do the narrow task, then expand.
Step 5: Request verbose error reporting
Add to prompt: "Before returning, list every file you attempted to read,
whether you succeeded, and any errors encountered."
Step 6: Check for silent failure
If agent returns "no issues found" unexpectedly:
- Was the scope too broad? Agent may have given up early.
- Were paths wrong? Agent may have found nothing because it looked in wrong place.
- Add: "If you found fewer than 3 files to examine, report this as an anomaly."
Common Pitfalls and Fixes
| Pitfall | Symptom | Fix |
|---|---|---|
| Agent prompt missing file paths | Agent returns “file not found” or nothing | Always include absolute paths, not relative |
| Spawning 20 agents simultaneously | API rate limits, token budget exhausted | Max 3-5 parallel agents; queue the rest |
| Not validating agent results | Bad data propagated downstream | Always check output before acting on it |
| Two parallel agents editing same file | Lost writes, silent conflicts | Define strict file ownership boundaries in prompts |
| Agent silently fails, returns empty result | Missing data, no error context | Instruct agents to report errors and list files examined |
| Prompt references “what we discussed” | Agent ignores or misinterprets task | Restate all context inline in the prompt |
| Background agent with result you need now | Parent blocks waiting or misses result | Use run_in_background: false for blocking tasks |
| Agent exceeds file boundary | Unintended file modifications | Use worktree isolation for guaranteed boundaries |
| Passing large context inline in prompt | Expensive, slow spawn | Write context to file first; agent reads the file |
| Agent writes to wrong location | Output lost or in unexpected place | Specify exact output paths in the prompt |
Resource Considerations
┌────────────────────────────────────────────────────────────────┐
│ Token Cost Model │
│ │
│ Each subagent consumes: │
│ ┌──────────────────┬─────────────────────────────────────┐ │
│ │ Cost component │ Approximate size │ │
│ ├──────────────────┼─────────────────────────────────────┤ │
│ │ System prompt │ 1k–5k tokens (agent definition) │ │
│ │ Task prompt │ 0.5k–3k tokens (your instructions) │ │
│ │ Tool calls │ 1k–50k tokens (depends on task) │ │
│ │ Agent output │ 0.5k–5k tokens (summary returned) │ │
│ └──────────────────┴─────────────────────────────────────┘ │
│ │
│ Rules of thumb: │
│ • Spawning cost ≥ ~3k tokens minimum │
│ • Tasks under 5 tool calls: don't bother, stay in session │
│ • Background agents still consume API quota while running │
│ • Prefer fewer, better-scoped agents over many small agents │
└────────────────────────────────────────────────────────────────┘
Key Exam Points
- Under 5 tool calls = don’t bother with a subagent
- Fan-out/Fan-in is the most common parallel pattern
- Pipeline chains require foreground agents (
run_in_background: false) - Background agents use
run_in_background: true - Always validate agent output before acting on it
- Use the filesystem to pass state between pipeline agents
SendMessageonly works on still-running background agents- Worktree isolation guarantees no file conflicts between parallel agents
Quick Reference
Agent Tool Invocation
Agent({
description: "...", // routing hint, shown in logs
subagent_type: "...", // agent type or custom name from .claude/agents/
prompt: "...", // self-contained task description (critical)
run_in_background: false // true for parallel, false for pipeline/blocking
})
SendMessage Invocation
SendMessage({
agent_id: "agent-abc123", // ID returned from Agent() call
message: "Additional instruction" // Sent as new user turn to running agent
})
// Only works on background agents that are still running
Agent Definition Template
---
name: my-agent
description: What this agent does in one line — be specific
allowed-tools: Read, Grep, Glob
model: claude-sonnet-4-5
context: fork
---
# My Agent
[Role statement — who the agent is and what it specializes in]
Process:
1. [First step — be specific about what to look at]
2. [Second step — be specific about what to do]
3. [Third step — how to finish and what to report]
Output format:
[Exact format of the agent's response]
Error handling:
[What to do when files are missing, commands fail, etc.]
Decision Tree: Use Subagent?
Is the task > 5 tool calls OR > 10k tokens of work?
No ──► do it in main session (overhead not worth it)
Yes ──► Does it need conversation history?
Yes ──► do it in main session
No ──► spawn a subagent
Is it independent of other parallel tasks?
Yes ──► run_in_background: true (parallel)
No ──► run_in_background: false (pipeline)
Do parallel agents write to overlapping files?
Yes ──► use isolation: worktree
No ──► use file boundary prompts
Execution Pattern Summary
| Pattern | Agents | Background? | Use Case | Key Constraint |
|---|---|---|---|---|
| Fan-Out/Fan-In | Multiple | Yes | Parallel independent research | No shared file writes |
| Pipeline | Sequential | No | Steps depend on previous output | Each completes before next |
| Specialist | Single | Either | Route to domain expert | Match agent to task type |
| Background Monitor | Single | Yes | Watch external process | Polling, no time pressure |
Certification Checklist
Core Concepts
- Subagents have isolated context windows (no shared history)
- Agent context discarded at termination; only files and summary persist
- Prompts must be fully self-contained (absolute paths, explicit context)
Creating Agents
- Definition files:
.claude/agents/agent-name.mdwith YAML frontmatter - Required fields:
name,description,allowed-tools,context -
context: fork= isolated (default);context: inherit= shares parent context -
descriptionfield is used for routing — make it specific
Design Principles
- Least-privilege tool access per agent role
- File ownership boundaries enforced for parallel write agents
- Output format defined explicitly in prompt
- Error handling instructions included in prompt
Isolation
- Worktree isolation: separate git branch + directory per agent
- Worktree merge after agents complete; resolve conflicts if any
- File boundary prompts sufficient when modules don’t overlap
Execution Patterns
- Fan-out/Fan-in: parallel background agents + synthesize results
- Pipeline: foreground agents in sequence, state via filesystem
- Specialist: route to domain-specific agent type
- Background monitor: watch external process without blocking
Communication
- Background agents:
run_in_background: true -
SendMessageonly works on still-running background agents - Pass state between pipeline agents via files (not inline text)
Cost and Quality
- Overhead test: fewer than 5 tool calls = use main session
- Fixed spawn cost ≈ 3k tokens minimum
- Always validate agent output before acting on it
- When agent returns unexpected empty result: check paths, scope, and tool access
Practice Exercises
Exercise 1 — Design an Agent
Design an agent definition for a “dependency auditor” that reads package.json and package-lock.json, identifies outdated or vulnerable dependencies (using npm audit output from Bash), and produces a report sorted by severity.
Key decisions to make: which tools to allow, what output format to specify, how to handle the case where npm audit returns no output.
Exercise 2 — Choose the Pattern
A team wants to:
- Research three different authentication libraries
- Pick the best one based on research
- Implement it
- Write tests
Which pattern applies? What is the run_in_background setting for each agent?
Answer: Step 1 = fan-out (3 parallel research agents, background). Step 2 = main session synthesizes. Step 3 = pipeline agent (foreground). Step 4 = pipeline agent (foreground, reads step 3 output).
Exercise 3 — Identify the Pitfall
An agent prompt says: “Review the file we were looking at earlier and fix the bug.” What is wrong, and how do you fix it?
Answer: The prompt references conversation context the agent doesn’t have. Fix: “Review /absolute/path/to/file.ts. The bug is on line 47 — the userId variable is used before it is initialized. Fix the initialization and ensure userId is always defined before the guard clause.”
Exercise 4 — File Conflict Prevention
Two parallel agents both need to update src/shared/constants.ts. How do you handle this safely?
Answer: Either (1) make one agent run foreground first, then the second reads its result; or (2) use worktree isolation so each edits their own branch copy, then merge; or (3) extract the constants needed by each agent into separate files before spawning, so they have no overlap.