Claude Code subagents best practices are not about memorizing API flags. They are about understanding the failure modes — and designing your delegation patterns to avoid them. After collecting and analyzing hundreds of AGENTS.md files from production codebases, we have distilled the patterns that consistently work and the ones that look good on paper but fall apart under real workloads.
If you are new to subagents entirely, start with our subagents guide. This article assumes you understand the basics and focuses on optimization.
Browse real AGENTS.md examples from production codebases in our gallery.
The Core Failure Mode: Underspecified Agents
The single most common mistake is writing AGENTS.md entries that are too vague. Consider this pattern:
## research-agent
Researches topics and returns findings.
This gives the subagent no idea what “findings” means, what format to use, how deep to go, or what to do when it hits a dead end. The result is unpredictable output that requires the orchestrating agent to spend tokens interpreting and reformatting.
Compare it to this:
## research-agent
Researches a specific technical topic and returns a structured report.
### Input
You will receive a JSON object with:
- `topic`: the subject to research (string)
- `depth`: "overview" | "deep-dive"
- `sources`: array of URLs to prioritize, or empty for open research
### Output format
Return a markdown report with exactly these sections:
1. Summary (3-5 sentences)
2. Key findings (bullet list, max 10 items)
3. Gaps / unknowns (what you could not verify)
4. Sources used (URL list)
### Constraints
- Do not return more than 1,500 words total
- If `depth` is "overview", spend no more than 5 tool calls
- If a source is inaccessible, note it in Gaps rather than failing
The second version produces consistent, parseable output that the orchestrating agent can work with immediately.
Task Decomposition: How to Split Work
The best decompositions have these properties:
Clear boundaries. Each subagent owns a well-defined slice of the problem. Overlapping responsibilities cause agents to duplicate work or overwrite each other’s results.
Independent inputs. A good subtask does not depend on another subtask completing first (or if it does, that dependency is explicit and sequenced accordingly). Parallelism is only valuable when tasks genuinely do not block each other.
Bounded scope. A subagent that can go off on open-ended research will. Cap scope with explicit constraints: max tool calls, max output length, time-box the exploration.
Concrete success criteria. The agent needs to know when it is done. “Implement the feature” is not done-criteria. “Implement the feature so that npm test passes with no new test failures” is.
A practical decomposition template
When facing a large task, decompose it like this before delegating:
Task: [what needs to happen]
Subtasks:
1. [subtask A — independent]
2. [subtask B — independent]
3. [subtask C — depends on A and B output]
For each subtask:
- Input: [exactly what gets passed]
- Output: [exactly what gets returned]
- Constraint: [scope limit]
- Done when: [verifiable condition]
Writing this out forces you to identify hidden dependencies before they cause failures mid-execution.
Context Passing: The Right Amount of Information
Subagents only know what you tell them. But over-providing context is as harmful as under-providing it. Every token you pass is a token the subagent cannot use for actual work.
Pass summaries, not raw data
If the subagent needs to understand a codebase, do not dump the entire codebase into the prompt. Pass a structured summary:
## Codebase Context
- Language: TypeScript, Node.js 20
- Architecture: REST API with Express, PostgreSQL via Prisma
- Relevant files for this task:
- src/api/users.ts (user CRUD endpoints)
- src/lib/db.ts (database client and query helpers)
- prisma/schema.prisma (data model)
- Conventions: use named exports, snake_case for DB columns, camelCase in code
- Test command: npm test
This gives the subagent enough to work correctly without burning context on irrelevant parts of the codebase.
Structure the handoff
When passing results between agents in a sequential workflow, structure the handoff explicitly:
## Handoff from [previous-agent]
Status: completed
Output:
- Created 3 new API endpoints in src/api/payments.ts
- Added Zod schemas in src/schemas/payment.ts
- Tests are in src/api/__tests__/payments.test.ts
Issues encountered:
- Stripe webhook endpoint requires authentication middleware not yet implemented
Your task:
- Implement the missing auth middleware (see src/middleware/ for existing patterns)
- Wire it into the webhook endpoint
- Verify all payment tests pass
This prevents the second agent from re-reading everything the first agent already processed.
Parallel vs Sequential: When to Use Each
Use parallel subagents when:
- Tasks are genuinely independent (no shared state, no ordering requirement)
- Each task is large enough to justify the orchestration overhead
- You have context budget pressure and want to isolate work
Use sequential subagents when:
- Output of task A is required input to task B
- Tasks share state (same files, same database)
- You need to gate on success before proceeding (“only continue if tests pass”)
Use a hybrid when:
- Phase 1 has parallel tasks, Phase 2 aggregates their results
- Some tasks are independent, others chain off specific earlier results
The aggregator pattern
This is one of the most reliable multi-agent patterns:
Orchestrator
→ Spawns N parallel subagents (each handles one slice)
→ Waits for all to complete
→ Spawns 1 aggregator subagent (receives all N outputs)
→ Returns aggregator's result
The aggregator keeps the main context clean — it synthesizes the parallel work without the orchestrator having to process N separate outputs.
AGENTS.md Structural Best Practices
Use consistent headers
Every agent entry should have the same structure. This makes AGENTS.md scannable and helps the model parse entries reliably:
## [agent-name]
[One-line purpose]
### When to use
[The condition that triggers this agent]
### Input
[What it receives]
### Output
[What it returns, with format spec]
### Constraints
[Hard limits on behavior, scope, output size]
Separate concerns across files
For large projects, use multiple AGENTS.md files:
~/.claude/AGENTS.md → global agents available everywhere
./AGENTS.md → project-level agents
./packages/api/AGENTS.md → API-specific agents
./packages/frontend/AGENTS.md → Frontend-specific agents
Agents closer to the current directory take precedence, which lets you override global behavior for specific packages.
Keep entries short
The entire AGENTS.md file loads into context for every session. Each 100-line agent definition adds ~750 tokens of overhead. Keep each entry under 40 lines, and keep the total AGENTS.md under 300 lines. If you need longer specs, reference an external file:
## complex-migration-agent
Handles database schema migrations. See `docs/agents/migration-agent.md` for full spec.
The agent can read the referenced file itself. You are not required to inline everything.
Tool Permission Scoping
Subagents inherit tool permissions from the global config unless you override them. Scoping permissions tightly:
- Reduces the blast radius if the agent makes a wrong decision
- Constrains open-ended behavior (an agent that cannot browse the web stays focused)
- Makes behavior more predictable
For a code review agent, for example, you want read access to files but no write permissions and no shell execution. An agent with narrower permissions is an agent that is less likely to take irreversible actions.
Scope permissions in AGENTS.md:
## code-review-agent
Reviews pull request diffs and returns structured feedback.
### Permissions
- allowed: read_file, list_files
- denied: write_file, execute_bash, browser_navigate
Error Handling in Subagent Workflows
Subagents fail. The question is what your orchestration layer does when they do.
Explicit failure signals
Define how a subagent should signal failure:
### Failure behavior
If you cannot complete the task, return:
{
"status": "failed",
"reason": "brief explanation",
"completed_portion": "what was finished before failure",
"retry_possible": true/false
}
Do not guess or produce partial output without flagging it.
Retry logic
For non-deterministic failures (network issues, transient tool errors), a simple retry is often enough. For logic failures (agent misunderstood the task), retry with a corrected prompt — not the same one.
Graceful degradation
Design workflows so that a subagent failure does not collapse the entire pipeline. If an optional enrichment step fails, skip it and continue. If a required step fails, halt cleanly with a clear error rather than proceeding with garbage data.
Measuring Subagent Effectiveness
The metrics that actually matter:
Context budget consumed. If a subagent returns results that require significant re-processing in the main session, the context savings are smaller than you think. Measure how many tokens the returned output adds to your context.
First-attempt success rate. How often does a subagent complete its task correctly on the first invocation? A low success rate means your specs need work, not that subagents are the wrong tool.
Token efficiency. Total tokens consumed by the subagent vs. tokens the main session would have used doing the same work inline. The ratio should be better than 1:1 for subagents to be worth the coordination overhead.
Track these — even informally — for a week of real use. The results will tell you which agents need spec improvements and which are working well.
For more real-world AGENTS.md patterns, browse the Prompt Shelf gallery. For context management strategies that complement subagent use, see our CLAUDE.md token budget guide.