Claude Code Guide

The complete guide to Claude Code setup (Opus 4.6, Sonnet 4.6, Haiku 4.5). 1M token context window. 100+ hours saved. 25 hook events. Agent teams and task management. Production-tested patterns for skills, hooks, and MCP integration.

View the Project on GitHub ytrofr/claude-code-guide

Chapter 36: Agents and Subagents

Claude Code agents (subagents) are specialized AI workers you create as markdown files in .claude/agents/. Each agent gets its own context window, can use a specific model (sonnet, opus, haiku), has persistent memory across conversations, and can be restricted to specific tools. This guide covers 3 proven agent design patterns and production configuration.

Purpose: Create, configure, and use custom agents for specialized tasks Source: Anthropic Claude Code documentation + production patterns Difficulty: Intermediate Time: 30 minutes to set up first agent


Overview

Agents (subagents) are specialized Claude Code workers you spawn via the Task() tool. Each agent gets its own context window, can have a specific model, tools, and persistent memory.

When to use agents:

When NOT to use agents:


Agent File Structure

Agents live in .claude/agents/ as markdown files:

.claude/agents/
  deploy-agent.md
  database-agent.md
  test-engineer.md
  debug-specialist.md

Each file has YAML frontmatter + markdown body.

Project-Level vs User-Level Agents

Location Scope Use For
.claude/agents/ Current project only Project-specific agents (deploy, database, domain experts)
~/.claude/agents/ All your projects Cross-project agents (code-reviewer, security-scanner)

When both levels define an agent with the same name, project-level wins. Keep each agent at one level only to avoid confusion.

# Project-level (committed to git, shared with team)
mkdir -p .claude/agents

# User-level (personal, available in all projects)
mkdir -p ~/.claude/agents

Agent Frontmatter (All Fields)

---
name: deploy-agent
description: "Deployment specialist for GCP Cloud Run. Use when deploying to staging or production."
model: sonnet              # Optional: sonnet, opus, haiku (inherits from parent if omitted)
tools: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob']  # Optional: restrict available tools
memory: project            # Optional: project (per-project) or user (cross-project)
maxTurns: 15               # Optional: limit API round-trips (cost control)
---

# Deploy Agent

You are a deployment specialist...

## Your Responsibilities
- Deploy to GCP Cloud Run
- Verify traffic routing
- Run health checks

## Key Patterns
- Always route traffic after deployment
- Check health endpoint after deploy
...

Field Reference

Field Required Values Purpose
name Yes kebab-case identifier Agent name for Task() calls
description Yes What it does + “Use when…” Routing guidance
model No sonnet, opus, haiku Override model (default: parent)
tools No Array of tool names Restrict available tools
memory No project, user, or local Persistent memory (see below)
maxTurns No Number (e.g., 15) Max API round-trips

Model Selection

Model Use For Cost
haiku Quick searches, simple tasks Lowest
sonnet Most tasks (default) Medium
opus Complex reasoning, planning Highest

Important: Use valid model IDs only: sonnet, opus, haiku. Values like sonnet-4, claude-sonnet, etc. are invalid and will fail silently. You can also specify full model IDs like claude-sonnet-4-5-20250929 for version pinning.


Memory Persistence

The memory field enables agents to learn across conversations.

memory: project

Scoped to the current project. Agent remembers project-specific patterns.

memory: project

Use for: Most agents (deploy, database, testing, debugging). The agent builds knowledge about YOUR project’s patterns, common issues, and solutions.

memory: local

Personal memory, not committed to git. Agent remembers YOUR personal patterns.

memory: local

Use for: Personal workflow agents, experimental agents, developer-specific preferences. Local memory is stored in .claude/settings.local.json and not shared with the team.

memory: user

Cross-project memory. Agent remembers patterns across ALL your projects.

memory: user

Use for: Architecture agents, coding style agents — anything where cross-project knowledge is valuable.

No memory field

Agent starts fresh every conversation. No persistence.

Use for: Simple utility agents, one-off tasks.


Cost Control with maxTurns

Expensive agents (opus model, complex tasks) should have turn limits:

model: opus
maxTurns: 15 # Stops after 15 API round-trips

Guidelines:


CLI Agent Management

List all configured agents:

claude agents

This displays all agents from .claude/agents/ and ~/.claude/agents/ with their descriptions and model settings.


Spawning Agents

Use the Task() tool to spawn agents:

Task(
  subagent_type: "deploy-agent",
  description: "Deploy to staging",
  prompt: "Deploy the current branch to staging and verify health",
  model: "sonnet"  // Optional override
)

Parallel Execution

Spawn multiple independent agents simultaneously:

// In a single message, call multiple Task() tools:
Task(subagent_type: "test-engineer", prompt: "Run all tests")
Task(subagent_type: "database-agent", prompt: "Check schema consistency")
Task(subagent_type: "deploy-agent", prompt: "Verify staging health")

All three run in parallel and return results independently.

Background Agents

For long-running tasks:

Task(
  subagent_type: "database-agent",
  prompt: "Run comprehensive data validation",
  run_in_background: true
)

Check later with Read on the task’s output file path. (Note: TaskOutput was deprecated in v2.1.83.)


Tool Restrictions with Task(agent_type)

You can restrict which sub-agents an agent can spawn by using Task(agent_type) syntax in the tools field:

---
name: api-coordinator
description: "Coordinates API operations with intelligent routing."
tools:
  ["Read", "Write", "Edit", "Bash", "Task(shifts-agent)", "Task(beecom-agent)"]
---

This agent can only spawn shifts-agent and beecom-agent via Task(). Attempts to spawn other agent types will be blocked.

When to use: Agents that delegate to known specialists (API coordinator -> shifts/beecom, deploy -> gcp, data integrity -> accuracy).

When NOT to use: Agents that need flexibility to spawn any agent type (e.g., a branch policy enforcer that may need any specialist).

Examples

# Deploy agent can only delegate to GCP infrastructure agent
tools: ['Read', 'Write', 'Edit', 'Bash', 'Task(gcp-agent)']

# Data integrity agent can only delegate to accuracy specialist
tools: ['Read', 'Edit', 'Bash', 'Task(accuracy-agent)']

# Context orchestrator can only delegate to context agent
tools: ['Read', 'Task(context-agent)']

Benefits: Prevents wrong routing (an API coordinator accidentally spawning a deploy agent), reduces token waste from misrouted sub-agent calls, and makes agent responsibilities explicit.


Worktree Isolation (v2.1.50)

Agents can run in isolated git worktrees, preventing interference with the main working copy:

---
name: refactor-agent
model: sonnet
isolation: worktree
---

When isolation: worktree is set:

This enables parallel agent work on the same codebase without conflicts.


Creating Your First Agent

Step 1: Create the file

mkdir -p .claude/agents

Step 2: Write the agent

---
name: code-reviewer
description: "Reviews code for bugs, security issues, and best practices. Use when reviewing PRs or checking code quality."
model: sonnet
tools: ["Read", "Grep", "Glob"]
memory: project
---

# Code Reviewer

You are a code review specialist.

## Review Checklist

- Security vulnerabilities (OWASP top 10)
- Error handling completeness
- Edge cases
- Performance issues
- Code style consistency

## Output Format

For each issue found:

1. File and line number
2. Severity (critical/warning/info)
3. Description
4. Suggested fix

Step 3: Use it

Task(
  subagent_type: "code-reviewer",
  prompt: "Review the changes in src/auth/ for security issues"
)

Agent Design Patterns

1. Domain Expert Pattern

Agent knows one domain deeply:

name: database-agent
description: "Database operations specialist. Use when working with schemas, migrations, queries, or data integrity."
tools: ["Read", "Bash", "Grep"]
memory: project

2. Lightweight Scout Pattern

Quick exploration agent with minimal cost:

name: codebase-explorer
description: "Fast codebase exploration. Use when searching for files, patterns, or understanding structure."
model: haiku
tools: ["Read", "Grep", "Glob"]
maxTurns: 10

3. Expensive Expert Pattern

High-quality reasoning for critical tasks:

name: architecture-agent
description: "System architecture decisions. Use when planning major refactors or new features."
model: opus
memory: user # Cross-project architectural knowledge
maxTurns: 15

Monitoring Agents

Use hooks to track agent lifecycle:

{
  "SubagentStart": [
    {
      "hooks": [
        { "type": "command", "command": ".claude/hooks/subagent-monitor.sh" }
      ]
    }
  ],
  "SubagentStop": [
    {
      "hooks": [
        { "type": "command", "command": ".claude/hooks/subagent-monitor.sh" }
      ]
    }
  ]
}

See Chapter 13: Hooks for the monitor script implementation.


Tool Permission Models

Claude Code has two distinct tool permission mechanisms. Understanding the difference prevents common configuration mistakes.

allowed-tools (Frontmatter / Settings)

Used in skill or agent frontmatter. Restricts the agent to ONLY the listed tools – all other tools are unavailable.

---
name: read-only-agent
tools: ["Read", "Grep", "Glob"] # Can ONLY use these 3 tools
---

allowed_tools (Claude Agent SDK)

Used in the Claude Agent SDK (claude-sdk). Auto-approves the listed tools (no user permission prompt), but does NOT restrict access. All other tools remain available – they just require user approval.

# SDK: These tools run without permission prompts, but all tools are still AVAILABLE
agent = Agent(allowed_tools=["Read", "Grep", "Glob"])

disallowed_tools (Claude Agent SDK)

Used in the Claude Agent SDK only. Removes tools from the agent’s context entirely – the agent cannot use them at all, not even with user permission.

# SDK: These tools are completely invisible to the agent
agent = Agent(disallowed_tools=["Bash", "Write"])

Quick Reference

Mechanism Where Used Effect
tools (list) Agent frontmatter Agent can ONLY use listed tools
allowed_tools Claude SDK Auto-approve (no prompt), others still available
disallowed_tools Claude SDK Tools removed entirely from agent

Key insight: In frontmatter, tools: [...] restricts. In SDK, allowed_tools auto-approves but does NOT restrict. They are different behaviors despite similar names.


Query Classification for Agent Routing

When deciding how many agents to spawn and how to coordinate them, classify the incoming query:

Depth-First

When: Multiple perspectives needed on the same topic.

"Investigate slow AI queries"
  → database-agent (check query plans)
  → ai-agent (check prompt size)
  → monitoring-agent (check latency metrics)
  = 3 agents exploring DIFFERENT ANGLES of ONE problem

Breadth-First

When: Multiple independent sub-questions.

"Check all environments are healthy"
  → staging-agent (check staging)
  → production-agent (check production)
  → localhost-agent (check local)
  = 1 agent PER QUESTION, running in parallel

Straightforward

When: Focused lookup or single-domain task.

"Check employee count in database"
  → database-agent only
  = SINGLE agent, <5 tool calls

Subagent Budget Guidelines

Complexity Agents Tool Calls Each Total Budget
Simple 1 <5 ~5 calls
Standard 2-3 ~5 ~15 calls
Complex 3-5 ~10 ~50 calls
Very Complex 5-10 up to 15 ~100 calls

Rule: More subagents = more overhead. Only add agents when they provide distinct value. A single well-prompted agent often beats 3 poorly-scoped ones.

Source: Anthropic research_lead_agent.md, orchestrator_workers.ipynb


Agent Skills Preloading

The skills: field in agent frontmatter tells the agent which skills to load immediately when spawned, rather than discovering them during operation.

Frontmatter Syntax

---
name: database-agent
description: "Database operations specialist"
model: sonnet
memory: project
skills:
  - database-master-skill
  - database-column-standards-skill
---

When to Use Skills Preloading

Agent Type Recommended Skills Why
Database agent database-master-skill, column-standards Needs schema patterns immediately
Deploy agent deployment-master-skill, safe-deployment Must know deploy checklist upfront
Test engineer testing-master-skill, baseline-methodology Needs test patterns from start
Security agent compliance-skill, vulnerability-patterns Security context critical early

Benefits

Implementation Pattern

Match skills to agent domains. A database agent shouldn’t preload deployment skills:

# Good: Domain-aligned skills
skills:
  - database-master-skill
  - database-column-standards-skill

# Bad: Unrelated skills waste context
skills:
  - database-master-skill
  - deployment-master-skill  # Why would a DB agent need this?

Agent Permission Modes

The permissionMode: field controls how the agent handles permission prompts during execution.

Available Modes

Mode Behavior Best For
(default) Inherits parent session mode Most agents
plan Agent can only read/explore, never write Read-only agents (navigators, monitors)
acceptEdits Auto-accepts file edits, prompts for other actions Code-writing agents
bypassPermissions No permission prompts at all Fully trusted automation

Frontmatter Syntax

---
name: knowledge-navigator
description: "Navigate and search project knowledge"
model: haiku
memory: project
permissionMode: plan
---
# Read-only agents — can only explore, never modify
knowledge-navigator:    permissionMode: plan
blueprint-context:      permissionMode: plan
monitoring-agent:       permissionMode: plan

# Code-writing agents — auto-accept edits for efficiency
database-agent:         permissionMode: acceptEdits
deploy-agent:           permissionMode: acceptEdits
test-engineer:          permissionMode: acceptEdits

# Coordinator agents — need to orchestrate subagents
api-coordinator:        permissionMode: acceptEdits
data-integrity-guardian: permissionMode: acceptEdits

Safety Note

Never use bypassPermissions for agents that interact with external services (APIs, databases, deployments). Use acceptEdits as the maximum for production agents.


Global vs Project Agents

Agents can exist at two scope levels:

Scope Location Available To Memory
Project .claude/agents/ (in repo) This project only memory: project
Global ~/.claude/agents/ (home dir) ALL projects memory: user

When to Use Global Agents

Create global agents for capabilities that apply across all projects:

# ~/.claude/agents/architecture-agent.md
---
name: architecture-agent
description: "Cross-project architecture review and design patterns"
model: sonnet
memory: user
---
Review architecture decisions using universal patterns...

Good candidates for global agents:

Override Behavior

When both exist with the same name, project-level wins:

~/.claude/agents/security-agent.md     ← Generic security patterns
.claude/agents/security-agent.md       ← Project-specific security rules (WINS)

This lets you have a generic global agent with project-specific overrides. The global version handles other projects; the project version adds domain-specific rules.

Memory Scope Alignment

Match memory scope to agent scope:


“Fresh Eyes” QA Pattern

After generating complex output (multi-file changes, generated artifacts, deployments), spawn a verification subagent. The subagent has fresh context and will catch issues that the generating agent – which has been staring at the code – will miss.

// After generating code:
Task(
  subagent_type: "Explore",
  prompt: "Verify the changes in src/auth/ are consistent and follow project patterns. Check for typos, missing imports, and logic errors.",
  model: "haiku"  // Cheap verification
)

Why it works: The generating agent sees what it expects, not what is there. A fresh subagent has no bias from the generation process.

When to use:

Source: Anthropic pptx and doc-coauthoring skills both use this pattern.


Tips


Source-Derived Agent Patterns (v2.1.88)

These patterns come from analyzing Claude Code’s internal agent architecture.

Cancellation Hierarchy

Claude Code implements a parent-child AbortController hierarchy for agent management. When a parent agent aborts, all child agents cascade-abort automatically. Each child gets its own AbortController linked to the parent via signal.addEventListener('abort', () => child.abort()).

Key rule: Never share a single AbortController across independent agents. Each child gets its own linked controller.

Message Capping

In-memory message arrays are capped at 50 entries per agent. Full history persists to disk transcripts. Without this cap, Claude Code’s BQ analysis showed 292 concurrent agents consuming 36.8GB peak memory.

Cache-Preserving Fork

When forking a subagent, Claude Code copies the EXACT parent message history with identical placeholder tool results. Only the final directive differs. This means forked children share the parent’s prompt cache — significant cost savings for parallel agents.


Previous: 35: Skill Optimization Next: 37: Agent Teams