Custom Subagent Design Patterns

Custom subagents are Markdown files with YAML frontmatter that define reusable, version-controlled AI workers in Claude Code. Stored in .claude/agents/ (project) or ~/.claude/agents/ (user), they encode specialist behavior — system prompt, tool access, model tier, memory scope, and lifecycle hooks — into a single file that can be shared via Git.

The Five Core Design Decisions

When building a custom subagent, five decisions determine its behavior:

1. Description (Routing Signal)

The description field is the most important field. Claude reads it to decide when to automatically delegate. A weak description means manual @-mention every time; a strong one means Claude routes proactively.

  • Weak: "Reviews code"
  • Strong: "Expert code reviewer. Use proactively after any code changes. Analyzes for quality, security, and maintainability."

2. Tool Surface (Least Privilege)

Grant only the tools the worker needs. The tools allowlist and disallowedTools denylist together enforce least-privilege:

tools: Read, Grep, Glob, Bash  # read-only reviewer
disallowedTools: Write, Edit    # alternative: block writes, inherit everything else

For conditional control (e.g., allow Bash but only SELECT queries), use PreToolUse hooks with a validation script.

3. Model Tier (Cost Routing)

Match the model to the task’s cognitive demand:

  • haiku — fast, cheap; ideal for search, exploration, simple formatting
  • sonnet — balanced; ideal for code review, analysis, most engineering tasks
  • opus — expensive; reserve for complex architectural reasoning

Defaulting to inherit means the subagent inherits the parent session’s model — convenient but potentially over-provisioned.

4. Memory Scope (Institutional Knowledge)

The memory: field gives the agent a persistent directory that accumulates knowledge across sessions:

memory: project   # writes to .claude/agent-memory/<name>/MEMORY.md

The agent reads up to 200 lines of MEMORY.md at startup and updates it after completing tasks. Over time, the agent builds codebase-specific knowledge (patterns, anti-patterns, architecture decisions) without that knowledge inflating live session context.

5. MCP Server Scoping

For agents that need external tools (browser automation, database clients, search), scope the MCP server to the agent rather than the parent session. This prevents the server’s tool descriptions from consuming parent context:

mcpServers:
  - playwright:
      type: stdio
      command: npx
      args: ["-y", "@playwright/mcp@latest"]

Canonical Pattern Library

Read-Only Specialist

---
name: code-reviewer
description: Reviews code quality and security. Use proactively after code changes.
tools: Read, Grep, Glob, Bash
model: sonnet
memory: project
---
You are a senior code reviewer...

Background Test Runner

---
name: test-runner
description: Runs test suite and reports only failing tests with error messages.
tools: Read, Bash
model: haiku
background: true
---
Run the test suite. Return only failures with error messages and reproduction steps.

Hook-Validated DB Reader

---
name: db-reader
description: Execute read-only database queries for analysis and reporting.
tools: Bash
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/validate-readonly-query.sh"
---
Execute SELECT queries only. Do not modify data.

MCP-Scoped Browser Tester

---
name: browser-tester
description: Tests features in a real browser. Use for UI testing and visual verification.
mcpServers:
  - playwright:
      type: stdio
      command: npx
      args: ["-y", "@playwright/mcp@latest"]
---
Test the specified feature in a browser. Return screenshots and pass/fail status.

Worktree-Isolated Experimenter

---
name: experimenter
description: Tries risky refactors in an isolated git worktree. Use for exploratory changes.
isolation: worktree
model: sonnet
---
Implement the requested refactor in this isolated worktree. Summarize what changed and whether it works.

The /agents Command

The /agents command opens a tabbed management UI:

  • Running tab — live agents with open/stop controls
  • Library tab — create, edit, delete, and inspect all agents

The Generate with Claude option lets you describe the agent in plain English; Claude produces the name, description, and system prompt. This lowers the barrier for non-YAML users while producing structurally correct configurations.

Invocation Hierarchy

Three escalating levels of control:

MethodGuaranteesScope
Natural language (“Use the code-reviewer agent…”)Claude decidesOne task
@-mention (@code-reviewer ...)Guarantees delegationOne task
claude --agent code-reviewerSession-wideFull session

For a session-wide default on a specific project, set agent in .claude/settings.json.

Fork Mode vs. Named Subagents

Fork mode (CLAUDE_CODE_FORK_SUBAGENT=1) creates a subagent that inherits the parent’s full conversation history. Compare:

Named SubagentFork
ContextFresh (task prompt only)Full parent history
CostHigher startup (no cache sharing)Lower (shared prompt cache)
IsolationStrongNone
Use whenSide task is self-containedTask needs full background
  • Claude SubAgents — the core architecture, dispatch patterns, and why to use subagents
  • Claude Code — extensibility architecture including the /agents command
  • Claude Skills — runs in parent context; complementary mechanism to subagents
  • Context Engineering — per-agent context scoping as a design discipline
  • MCPmcpServers scoping to isolate heavy tools to specific workers
  • Agent Memory Systems — subagent memory: field for persistent institutional knowledge
  • LLM Observability — tracking per-agent model tier and token spend

References