Skip to content

Autonomous Subagent Workflows ​

What you'll learn

  • Subagents are specialized AI workers that handle side tasks in their own context windows, keeping your main conversation clean and focused on architecture
  • A fleet of three to five subagents (researcher, linter, reviewer, test-runner, documenter) handles the repetitive work that eats up your attention and your context window
  • Custom subagents are defined once in .claude/agents/ and reused across every session and every project that shares the same conventions
  • The skill is not in building complex multi-agent systems. It's in identifying which tasks are worth delegating and which are better kept in the main conversation

The problem ​

Your Claude Code session is 80 messages deep. You started building a feature 45 minutes ago, but the conversation is now a landfill: search results from exploring the codebase, lint output from three different runs, git diffs from checking what changed, and a long tangent where the agent explained how your ORM works, which you already knew. Your context window is full of noise, and the agent is starting to forget the specification you gave it 30 messages ago.

This is context pollution. Every tool call the agent makes adds to the conversation history. Research, linting, file searches, and git archaeology are all necessary work, but they produce output you don't need to see again. When that output shares a context window with the implementation you care about, it competes for the agent's attention. The result: the agent loses track of the spec, repeats work you already did, and makes decisions that contradict decisions it made earlier in the session.

Subagents solve this by moving side work into separate context windows. A subagent researches your codebase and returns a three-sentence summary instead of 200 lines of search results. A subagent lints the changed files and returns "3 issues in auth.py, 1 in models.py" instead of 40 lines of linter output. Your main conversation stays clean. The agent stays focused on the spec.

Options & when to use each ​

ApproachWhat it doesWhen it falls shortWhen to use it
Do everything in the main conversationOne agent, one context window, everything inlineContext pollution. After 30+ tool calls, the agent forgets earlier instructions. Research output buries implementation contextQuick tasks under 10 tool calls. "Find this bug" not "build this feature"
Built-in Explore subagentClaude Code's built-in codebase explorer. Read-only, fast, returns summariesOnly does research. Can't lint, can't run tests, can't write code"Find where auth logic lives in this codebase" before starting a feature
Built-in general-purpose subagentFull tool access in a separate context windowSame model cost as the parent. No domain-specific instructions unless you add them to the promptComplex research that needs both reading and running commands
Custom subagents with tailored toolsPurpose-built workers with restricted tool access and specialized system promptsRequires upfront setup: writing a markdown file and defining tool patternsRepeatable work you delegate across multiple sessions: linting, PR review, test running, documentation generation

Custom subagents are the pattern that compounds. You write a linter agent once and every future session benefits. You write a PR reviewer once and every PR gets reviewed with the same standards. The upfront cost is 10 minutes per agent. The payoff is every session thereafter.

Build it ​

Step 1: Create a research subagent ​

Research is the most common delegation target: it produces a lot of output (file contents, search results, grep matches) but you only need the conclusions. Create .claude/agents/researcher.md:

markdown
---
name: researcher
description: Explores codebases to answer specific questions. Use me when you need to understand how something works, find where something lives, or trace a dependency chain. I return concise summaries, not raw search results.
tools:
  - Read
  - Glob
  - Grep
  - Bash(git log *)
model: claude-haiku-4-5-20251001
---

# Researcher

You research codebases and return concise answers. You never modify files.

## Process
1. Read the research question carefully. Identify what you need to find.
2. Use Glob and Grep to locate relevant files. Be systematic: start broad,
   narrow down.
3. Read the files you find. Understand what they do.
4. Return a summary answering the original question. Structure it as:
   - **Answer:** [Direct answer in one to three sentences]
   - **Key files:** [List of files with one-line descriptions of what each does]
   - **Gotchas:** [Anything surprising or non-obvious you found]

## Rules
- Return summaries, not raw output. The parent doesn't need to see every
  grep match or file content.
- If the answer is "this codebase doesn't have X," say so directly.
  Don't pad the response.
- If you're not confident you found the right thing, say so and explain why.

Trigger it from your main session:

text
Use the researcher subagent to find how authentication middleware is
implemented in this project. I need to know: where the middleware lives,
what it checks, and how it passes user info to route handlers.

The parent agent spawns the researcher, which explores the codebase in its own context window and returns the summary. Your main conversation gets three lines of summary instead of 80 lines of grep results and file contents.

Step 2: Create a linter subagent ​

Linting is the most mechanical delegation target: predictable output, no judgment calls, always the same commands. Create .claude/agents/linter.md:

markdown
---
name: linter
description: Runs project linters and reports issues. Use me after any code change to check for linting or formatting problems. I never fix code, I only report.
tools:
  - Read
  - Bash(ruff check *)
  - Bash(ruff format --check *)
  - Bash(npm run lint)
  - Bash(npx eslint *)
  - Bash(npx prettier --check *)
model: claude-haiku-4-5-20251001
---

# Linter

You run linting checks and report results. You do not fix code.

## Process
1. Check which linters the project uses. Look at pyproject.toml, package.json,
   Makefile, or CI config for linting commands.
2. Run the linting commands. Run format-checking commands.
3. Report results as: file, line, rule/error code, message.
4. Summarize: total issues, files affected, severity breakdown.

## Rules
- Never fix lint issues. That's a separate agent's job, or the parent's.
- If a linter isn't installed, say so. Don't try to install it.
- Report zero issues as "All checks passed" with the commands you ran.

Trigger it after any code change:

text
Run the linter on all changed files.

The linter spins up, runs the checks, and reports. Your main conversation gets a three-line summary instead of scrolling through ruff output.

Step 3: Create a PR reviewer subagent ​

Code review benefits from a separate context window: the reviewer sees the diff without the context of why you made each change, which is exactly what you want from a reviewer. Create .claude/agents/pr-reviewer.md:

markdown
---
name: pr-reviewer
description: Reviews pull requests for code quality, security issues, and convention violations. Use me before merging any PR. I never modify code.
tools:
  - Read
  - Grep
  - Glob
  - Bash(git diff *)
  - Bash(git log *)
model: claude-sonnet-4-20250514
---

# PR Reviewer

You review code changes and report issues. You are read-only. You never
modify code, commit, or push.

## Review checklist
1. **Security:** hardcoded secrets, injection vectors, unsafe deserialization,
   missing input validation
2. **Correctness:** logic errors, off-by-one, null/undefined handling,
   missing error handling
3. **Conventions:** does the code follow project conventions from CLAUDE.md?
4. **Tests:** are new paths covered? are edge cases tested?
5. **Performance:** N+1 queries, unnecessary I/O, blocking operations

## Output format
For each issue:
- **File:line** | **Severity:** critical/high/medium/low
- **Category:** security/correctness/convention/testing/performance
- **What's wrong:** [specific description]
- **Suggested fix:** [concrete change]

End with a summary: total issues by severity, overall assessment, and whether
the PR is safe to merge, merge with fixes, or should not merge.

Step 4: Wire subagents into your workflow ​

Once you have a fleet of subagents, integrate them into your build process. Create a workflow prompt:

text
I'm about to build a feature. Here's the plan:

1. First, use the researcher subagent to find all files related to [topic].
   I need to know the existing patterns before I add new code.
2. Build the feature according to the spec in specs/[feature].md.
3. After building, run the linter subagent on all changed files.
4. After linting passes, run the pr-reviewer subagent on the diff.
   Fix all critical and high-severity issues.
5. Run the test suite and confirm all tests pass.

Do not skip steps. Do not combine steps. Report after each step before
proceeding to the next.

This gives the parent agent a clear pipeline: research, build, lint, review, test. Each step that produces noise runs in a subagent's context window. The parent stays focused on the build step. You get the benefits of a CI pipeline without leaving your terminal.

Step 5: Use background agents for long-running work ​

Some tasks take minutes: running a full test suite, building a Docker image, processing a large dataset. Use background agents so you can keep working while they run. In Claude Code:

text
Run the full test suite as a background agent. Notify me when it completes.
While that runs, I'll continue working on the next feature.

Background agents run independently and report back when done. This is the difference between staring at a progress bar for three minutes and getting three minutes of actual work done while the tests run in the background.

What goes wrong ​

MistakeHow you notice itThe fix
Subagent doesn't get spawned because description is too vagueThe parent agent does the work itself instead of delegatingThe description field is the trigger. Write it as "Use me when [specific condition]" not "I do [general thing]." "Use me when you need to find where code lives in this project" triggers delegation. "I research code" doesn't
Subagent gets zero tools and fails immediately"No tools available" error from the subagentThe tools field is deny-by-default. If you omit it, the agent gets nothing. Every agent needs at least Read to function. Add it explicitly
Subagent's Bash pattern is too broadSubagent runs commands you didn't intend. A linter that has Bash(*) could run rm -rfUse specific patterns: Bash(ruff check *) not Bash(*). List each command the agent needs. If you can't list them, the agent shouldn't have Bash access
Subagent returns raw output instead of a summaryYour main conversation gets 200 lines of grep results that bury the implementation contextWrite "return summaries, not raw output" into the agent's system prompt. The subagent needs to be told explicitly that its job is to synthesize, not to relay
Subagent uses an expensive model for simple workLinting costs as much as architectural workSet model: claude-haiku-4-5-20251001 for mechanical tasks (linting, formatting checks, test running). Reserve Sonnet or Opus for reasoning work (review, research)
Subagent files are lost when switching machinesYour custom agents work on your laptop but not on the cloud machinePut shared agents in the project's .claude/agents/ directory and commit them. Put personal agents in ~/.claude/agents/. If both exist with the same name, the project version wins
Too many subagents, too little actual workYou spend more time configuring agents than building with themStart with one subagent (researcher). Use it for a week. Add a second when you notice yourself thinking "I wish I didn't have to see the lint output every time." Three to five subagents is a mature fleet. More than five means you're spending more time managing agents than writing code

Confirm it worked ​

Build and test your subagent fleet:

bash
# 1. Create the researcher subagent (Step 1)
mkdir -p .claude/agents
# Write .claude/agents/researcher.md with the content from Step 1

# 2. Verify Claude Code can find it
claude
# Ask: "What custom subagents are available?"
# Verify: researcher appears in the list

# 3. Run a real research task
# "Use the researcher subagent to find how error handling works in this project.
#  I need to know: where errors are defined, how they're caught, and what the
#  error response format is."

# Verify: the response is a summary (not raw grep output). It answers the
# question. It lists key files with descriptions.

# 4. Create the linter subagent (Step 2)
# Write .claude/agents/linter.md

# 5. Make a small code change, then run the linter
# "Run the linter on all changed files."
# Verify: lint results reported as a summary, not raw linter output.

# 6. Run the full workflow (Step 4) on a small feature
# Use the researcher, build, lint, review pipeline.
# Verify: each step completes. The main conversation stays focused. No step
# produces more than 10 lines of output in the main context window.

# Success: research and lint output no longer pollute your main context.
# Better success: you ran the researcher, got a useful answer, built the feature,
#   linted it, and reviewed it without once scrolling past 50 lines of tool output.
# Best success: three days from now, you spawn the researcher subagent without
#   thinking about it because it's become part of how you work.

Subagents pay for themselves when they keep your context window clean enough that the agent remembers the spec from the start of the session to the end. If your agent is forgetting things, check whether research and lint output is competing with implementation context. Move that work to subagents and try again.

Next: Apply all three patterns to a real project. Write a spec, stress-test it with the alignment interview, and build it with a fleet of autonomous subagents. Your first end-to-end workflow run will feel slower than your old approach. Your tenth will be faster. Your hundredth will be how you start every project.