← Claude Code & Certification

Introduction to Subagents — Claude Code Certification Study Guide

Table of Contents

Introduction to Subagents — Claude Code Certification Study Guide

Course: Anthropic “Introduction to Subagents” | 4 Modules Last updated: 2026-04-26


Table of Contents

  1. Module 1 — What Are Subagents?
  2. Module 2 — Creating a Subagent
  3. Module 3 — Designing Effective Subagents
  4. Module 4 — Using Subagents Effectively
  5. 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?

ReasonExplanation
Context isolationSubagent reads large files without polluting parent’s context window
Parallel executionMultiple subagents run simultaneously for independent tasks
SpecializationEach agent tuned for a specific role (reviewer, tester, researcher)
Context protectionMain session stays under token limits; subagents handle the heavy reads
Clean separationEach subtask has its own reasoning trace, reducing noise
Longer total workChain 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

TypeCapabilitiesBest For
generalFull tool access (read, write, bash, edit)Implementation tasks
exploreRead-only (Read, Grep, Glob)Codebase exploration
planArchitecture and design thinkingSystem design
code-reviewerRead, Grep, Glob + Bash (run tests)Security/quality review
testerFull access + test runner focusWriting and running test suites
debuggerFull access + diagnostic toolingInvestigating failures
researcherWeb search, file reading, synthesisGathering 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

FieldPurposeOptions / Notes
nameIdentifier used when spawning via subagent_typekebab-case string
descriptionOne-line summary; used for routing by the harnessPlain text, be specific about the role
allowed-toolsRestricts which tools the agent can useComma-separated tool names
modelWhich Claude model to useAny valid model ID; defaults to parent model
contextWhether agent inherits parent contextfork (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

Moderun_in_backgroundBehaviorUse When
ForegroundfalseParent waits for completion before continuingNext step depends on this result
BackgroundtrueParent continues; notified when agent finishesTasks 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: fork is the default and preferred for isolation
  • Always specify allowed-tools to enforce principle of least privilege
  • run_in_background: true enables parallel execution patterns
  • SendMessage only works on background agents that are still running
  • The description field 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 PromptDo NOT Include
Absolute file pathsReferences to “what we discussed”
Specific line numbersAssumptions about shared knowledge
Exact function/class namesVague instructions like “fix things”
Expected output formatOpen-ended exploration tasks
Success criteriaImplicit context from conversation
Error reporting instructionsAssumptions about project structure
Relevant constants or IDsReferences 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 RoleAllowed ToolsWhy Restricted
Explorer / AuditorRead, Grep, GlobRead-only — no side effects
Code ReviewerRead, Grep, Glob, BashNeeds to run tests to verify findings
ImplementerRead, Grep, Glob, Edit, Write, BashFull access for code changes
DocumentationRead, Grep, Glob, WriteReads code, writes docs only
ResearcherRead, Glob, Grep, WebSearch, WebFetchNeeds external info gathering
MonitorRead, BashChecks 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

ScenarioWhy Subagent is Right
Research that reads 20+ filesPrevents context pollution in main session
Multiple independent tasksParallel execution saves wall-clock time
Specialized review (security, perf, a11y)Dedicated context for that domain
Code generation that needs isolated testingTest in clean context before accepting result
Long-running background monitoringNon-blocking; parent continues other work
Task that would exhaust main session contextSubagent summarizes, parent stays lean
Work requiring domain expertise promptLoad specialized system prompt without polluting

When NOT to Use Subagents

ScenarioBetter Approach
Simple one-file questionRead the file directly in main session
Task that needs conversation historyStay 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 contextDo 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

PitfallSymptomFix
Agent prompt missing file pathsAgent returns “file not found” or nothingAlways include absolute paths, not relative
Spawning 20 agents simultaneouslyAPI rate limits, token budget exhaustedMax 3-5 parallel agents; queue the rest
Not validating agent resultsBad data propagated downstreamAlways check output before acting on it
Two parallel agents editing same fileLost writes, silent conflictsDefine strict file ownership boundaries in prompts
Agent silently fails, returns empty resultMissing data, no error contextInstruct agents to report errors and list files examined
Prompt references “what we discussed”Agent ignores or misinterprets taskRestate all context inline in the prompt
Background agent with result you need nowParent blocks waiting or misses resultUse run_in_background: false for blocking tasks
Agent exceeds file boundaryUnintended file modificationsUse worktree isolation for guaranteed boundaries
Passing large context inline in promptExpensive, slow spawnWrite context to file first; agent reads the file
Agent writes to wrong locationOutput lost or in unexpected placeSpecify 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
  • SendMessage only 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

PatternAgentsBackground?Use CaseKey Constraint
Fan-Out/Fan-InMultipleYesParallel independent researchNo shared file writes
PipelineSequentialNoSteps depend on previous outputEach completes before next
SpecialistSingleEitherRoute to domain expertMatch agent to task type
Background MonitorSingleYesWatch external processPolling, 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.md with YAML frontmatter
  • Required fields: name, description, allowed-tools, context
  • context: fork = isolated (default); context: inherit = shares parent context
  • description field 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
  • SendMessage only 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:

  1. Research three different authentication libraries
  2. Pick the best one based on research
  3. Implement it
  4. 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.