Subagents: Specialized AI Workers for Complex Tasks
General Swe
Stop flooding your main context with test output. Delegate to a test-runner subagent and get back only the failures.
Data Sci
Create a read-only database subagent that can query but never modify your production data.
Subagents: Specialized AI Workers for Complex Tasks
TL;DR
- Subagents are specialists. Each runs in its own context with custom prompts, specific tools, and independent permissions—like hiring contractors for specific jobs.
- Three built-in subagents handle common needs: Explore (codebase search), Bash (shell commands), Browser (web automation). They auto-activate when needed.
- Context isolation is the win. Test output, logs, and research stay in subagent context. Your main conversation stays clean.
You ask your agent to run the test suite. It dumps 500 lines of output into your conversation. You scroll. And scroll. The three lines you actually need—the failing test names—are buried somewhere in the middle. Meanwhile, your agent's context window is now half-full of test logs it'll never reference again.
Subagents fix this. Instead of running everything in one conversation, your agent delegates the test run to a specialist that captures all the noise and returns only: "3 tests failed in auth.test.ts. Error: Expected 200, got 401." Clean context. Clear results.
Where things stand: Cursor, Claude Code, and Gemini CLI all support subagents. Cursor has 3 built-in subagents plus custom ones. Claude Code lets you create custom subagents in .claude/agents/. Gemini CLI includes codebase_investigator, cli_help, and custom subagents. Same concept, same benefits—context isolation and task specialization.
What Are Subagents?
Subagents are specialized AI assistants that your main agent can delegate tasks to. Think of them as expert contractors: when you need a specific job done, you hire the right specialist, they do the work, and they report back with results.
How they work
- Your main agent encounters a task that matches a subagent's expertise (e.g., "run all tests and report failures").
- Delegation happens — the main agent spawns a subagent with a clear task description and relevant context.
- Subagent works independently — it has its own context window, system prompt, and tool access. It can run dozens of operations without cluttering your main conversation.
- Result returns — when done, the subagent sends a summary back to the main agent. The verbose intermediate work stays in the subagent's context.
The "aha" here: Subagents aren't a new concept—they're the Unix philosophy applied to AI. Each subagent does one thing well, takes input, returns output, and doesn't pollute the caller's state. If you've ever piped
grep | sort | uniqin a terminal, you already understand the mental model.
Why subagents matter
| Problem | How subagents solve it |
|---|---|
| Context bloat — Test output, logs, and documentation dumps consume your context window. | Subagents isolate verbose operations. Only the summary returns to your main conversation. |
| Tool restrictions — You want some tasks to be read-only (research) and others to be read-write (implementation). | Each subagent can have different tool access. Your read-only researcher can't accidentally modify code. |
| Specialized prompts — A code reviewer needs different instructions than a debugger or data analyst. | Each subagent has its own system prompt optimized for its domain. |
| Cost control — Running everything with the most capable model is expensive. | Route simple tasks to faster, cheaper models (e.g., Haiku for exploration, Sonnet for implementation). |
Built-In Subagents
All major agent platforms include subagents that automatically handle common, context-heavy operations:
1. Explore (Cursor, Claude Code, Gemini CLI)
Purpose: Fast, read-only codebase exploration.
- Model: Haiku 4.5 (fast, low-cost) or configurable.
- Tools: Read-only (Read, Grep, Glob). No Edit or Write.
- When it activates: "Find all places we use the deprecated API" or "How does the auth system work?"
Why it's a subagent: Codebase exploration generates huge amounts of intermediate output (file lists, search results, code snippets). Running this in the main context would consume thousands of tokens for information you don't need to see. The Explore subagent does all the searching, filters the results, and returns only the relevant summary.
Thoroughness levels (Cursor, Claude Code):
When invoking Explore, the agent specifies:
- Quick — Targeted lookups, minimal exploration.
- Medium — Balanced exploration (default).
- Very thorough — Comprehensive analysis across multiple locations.
2. Bash (Cursor, Claude Code)
Purpose: Run shell commands and filter verbose output.
- Model: Inherits from main conversation.
- Tools: Bash (shell command execution).
- When it activates: "Run the test suite and report failures" or "Deploy to staging."
Why it's a subagent: Command output is often verbose (test logs, build output, deployment status). The Bash subagent runs the commands, captures all output, and returns only what you need to know (e.g., "3 tests failed; here are the error messages").
3. Browser (Cursor, Claude Code)
Purpose: Web automation via MCP browser tools.
- Model: Inherits from main conversation.
- Tools: Browser automation (navigate, click, screenshot).
- When it activates: "Go to the staging app, log in, and verify the checkout flow."
Why it's a subagent: Browser interactions produce noisy DOM snapshots and screenshots. The Browser subagent navigates, interacts, and filters the results down to "checkout flow works" or "found error on payment page."
Gemini CLI: Domain-Specific Built-Ins
- Codebase Investigator — Deep codebase analysis and reverse engineering. Maps dependencies, analyzes architecture.
- CLI Help Agent — Expert knowledge about Gemini CLI itself (commands, configuration, docs).
- Generalist Agent — Routes tasks to the appropriate specialized subagent.
Configuration (Gemini CLI example):
{
"experimental": {
"codebaseInvestigatorSettings": {
"enabled": true,
"maxNumTurns": 20,
"model": "gemini-3.1-pro"
}
}
}
Creating Custom Subagents
Beyond built-in subagents, you can create your own for specialized workflows.
Where to store subagents
| Location | Scope | When to use |
|---|---|---|
Project (.cursor/agents/, .claude/agents/, .gemini/agents/) | Current project only | Team-specific workflows (code review, security audit). Check into version control. |
User (~/.cursor/agents/, ~/.claude/agents/, ~/.gemini/agents/) | All your projects | Personal subagents you use across projects (data analysis, debugging). |
CLI flag (--agents) | Current session only | Quick testing or automation scripts. Not saved to disk. |
Priority: Project subagents override user subagents when names conflict.
File format: Markdown + YAML frontmatter
Subagents are Markdown files with YAML frontmatter (metadata) and a Markdown body (system prompt).
Example: .cursor/agents/code-reviewer.md
---
name: code-reviewer
description: Reviews code for quality, security, and best practices. Use proactively after code changes.
tools: Read, Grep, Glob, Bash
model: sonnet # Sonnet 4.6
---
You are a senior code reviewer ensuring high standards.
When invoked:
1. Run `git diff` to see recent changes
2. Focus on modified files
3. Begin review immediately
Review checklist:
- Code clarity and readability
- Proper error handling
- No exposed secrets or API keys
- Input validation
- Test coverage
- Performance considerations
Provide feedback by priority:
- **Critical** (must fix before merge)
- **Warning** (should fix)
- **Suggestion** (consider improving)
Include specific examples of how to fix issues.
Required fields:
name— Unique identifier (lowercase, hyphens). Used to invoke the subagent.description— When to use this subagent. The main agent reads this to decide when to delegate.
Optional fields:
tools— Which tools the subagent can use. Defaults to all tools if omitted.disallowedTools— Tools to block (e.g.,Edit, Writefor read-only subagents).model— Which model to use:sonnet(Sonnet 4.6),opus(Opus 4.6),haiku(Haiku 4.5), orinherit(default: use main agent's model).permissionMode— Permission behavior:default,acceptEdits,dontAsk,bypassPermissions,plan.maxTurns— Maximum number of agentic turns before the subagent stops.skills— Skills to load into the subagent's context at startup.mcpServers— MCP servers available to this subagent.hooks— Lifecycle hooks scoped to this subagent (validation, logging, post-processing).memory— Persistent memory scope:user,project, orlocal(enables cross-session learning).
Quick start: Create a subagent
Option 1: Use the interactive command (Cursor, Claude Code)
/agents
Select Create new agent, choose scope (user or project), and either:
- Generate with Claude — Describe what you want; the agent writes the subagent file.
- Create manually — Write the frontmatter and prompt yourself.
Option 2: Write the file manually
Create a Markdown file in .cursor/agents/ (project) or ~/.cursor/agents/ (user):
touch .cursor/agents/test-runner.md
Add frontmatter and system prompt:
---
name: test-runner
description: Test automation expert. Use proactively after code changes to run tests and fix failures.
tools: Bash, Read, Edit
---
You are a test automation expert. When you see code changes, proactively run appropriate tests.
If tests fail:
1. Analyze failure output
2. Identify root cause
3. Fix the issue while preserving test intent
4. Re-run to verify
Report results:
- Number of tests passed/failed
- Summary of failures
- Changes made to fix issues
Save the file. The subagent is available immediately (no restart needed in Cursor/Claude Code; restart required in Gemini CLI).
Option 3: Use CLI flags (for automation)
cursor --agents '{
"db-analyst": {
"description": "SQL expert for database queries and analysis",
"prompt": "You are a database analyst. Write efficient SQL queries and explain results clearly.",
"tools": ["Bash", "Read"],
"model": "haiku" // Haiku 4.5
}
}'
The subagent exists only for that session.
Using Subagents
Automatic delegation
Agents automatically delegate based on:
- Task description — "Run all tests" matches a test-runner subagent.
- Subagent descriptions — The main agent reads the
descriptionfield to decide if a subagent is relevant. - Current context — Available tools, permissions, and task complexity.
To encourage proactive delegation, include "use proactively" in your subagent's description:
description: 'Test runner. Use proactively after code changes to run tests and report failures.'
Explicit invocation
You can request a specific subagent by name:
Use the code-reviewer subagent to review my recent changes
Have the debugger subagent investigate this error
Run the test-runner subagent on the API module
Or use slash syntax (if supported):
/code-reviewer check the auth module
/debugger fix the failing test
Foreground vs. background
Subagents run in one of two modes:
| Mode | Behavior | Best for |
|---|---|---|
| Foreground | Blocks until complete. Permission prompts and clarifying questions pass through to you. | Sequential tasks where you need the output before proceeding. |
| Background | Returns immediately. Runs concurrently while you continue working. | Long-running tasks or parallel workstreams (e.g., "run tests while I review code"). |
Background behavior:
Before launching, the agent prompts for any tool permissions the subagent will need. Once running, it inherits these permissions and auto-denies anything not pre-approved. MCP tools are not available in background subagents.
Control background mode:
- Ask: "Run this in the background"
- Shortcut: Ctrl+B (Cursor, Claude Code) to background a running task
- Disable: Set
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1environment variable
Resuming subagents
Each subagent invocation creates a new instance with fresh context. To continue an existing subagent's work (instead of starting over), ask the main agent to resume it.
Why resume?
Resumed subagents retain their full conversation history (tool calls, results, reasoning). The subagent picks up exactly where it stopped.
How to resume:
Use the code-reviewer subagent to review the auth module
[Subagent completes]
Continue that code review and now analyze the authorization logic
[Main agent resumes the subagent with full context]
The main agent receives the subagent's ID when it completes. You can also find IDs in transcript files at ~/.claude/projects/{project}/{sessionId}/subagents/agent-{agentId}.jsonl.
Common Patterns
1. Context isolation for verbose operations
Problem: Running tests produces 500 lines of output. Most of it is noise; you only care about failures.
Solution: Test-runner subagent.
---
name: test-runner
description: Runs tests and reports only failures with error messages.
tools: Bash
---
Run the test suite. If tests fail, report:
- Which tests failed
- Error messages and stack traces
- Root cause if obvious
Do not report passing tests. Keep output concise.
Result: The subagent runs the tests, captures all output, and returns: "3 tests failed in auth.test.ts. Error: 'Expected 200, got 401.'" Your main context stays clean.
2. Read-only enforcement
Problem: You want an agent to analyze your database schema but never modify data.
Solution: Read-only database subagent with tool restrictions.
---
name: db-reader
description: Execute read-only database queries for analysis and reporting.
tools: Bash
disallowedTools: Edit, Write
---
You are a database analyst with read-only access. Execute SELECT queries to answer questions about the data.
You cannot modify data. If asked to INSERT, UPDATE, DELETE, or modify schema, explain that you only have read access.
Add a validation hook to block write operations:
hooks:
PreToolUse:
- matcher: 'Bash'
hooks:
- type: command
command: './scripts/validate-readonly-query.sh'
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
# Block SQL write operations
if echo "$COMMAND" | grep -iE '\b(INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|TRUNCATE)\b' > /dev/null; then
echo "Blocked: Only SELECT queries allowed." >&2
exit 2
fi
exit 0Make it executable: chmod +x ./scripts/validate-readonly-query.sh
Result: The subagent can query the database but cannot modify it. Attempted write operations fail with a clear error message.
3. Parallel research
Problem: You need to understand three modules (auth, payments, notifications) to plan a feature. Sequential research takes forever.
Solution: Spawn multiple Explore subagents in parallel.
Research the authentication, payments, and notifications modules in parallel using separate subagents
Each subagent explores its area independently. When all complete, the main agent synthesizes the findings into a coherent plan.
Cost warning: Parallel subagents consume more tokens. Each has its own context window and returns detailed results. Use for independent investigations where speed matters.
4. Chained workflows
Problem: You need a multi-step process: review code → fix issues → run tests → deploy.
Solution: Chain subagents in sequence.
Use the code-reviewer subagent to find issues, then use the debugger subagent to fix them, then use the test-runner subagent to verify, then use the deploy subagent to ship it
Each subagent completes its task and returns results to the main agent, which passes relevant context to the next subagent.
5. Persistent memory (learning subagents)
Problem: Your code-reviewer subagent encounters the same issues repeatedly (e.g., "always validate input with zod, not manual checks").
Solution: Enable persistent memory.
---
name: code-reviewer
description: Reviews code for quality and best practices
memory: user
---
You are a code reviewer. As you review code, update your agent memory with patterns, conventions, and recurring issues you discover.
Before reviewing, check your memory for known patterns. After reviewing, save new learnings.
Result: The subagent maintains a MEMORY.md file at ~/.claude/agent-memory/code-reviewer/. Over time, it builds institutional knowledge: "This project uses zod for validation. Flag manual validation as an issue."
Memory scopes:
user— Shared across all your projects (~/.claude/agent-memory/<name>/).project— Project-specific, shareable via version control (.claude/agent-memory/<name>/).local— Project-specific, not checked into version control (.claude/agent-memory-local/<name>/).
Related Lessons
Subagents work best when combined with other agent capabilities:
- Model Context Protocol (MCP) — MCP servers expose tools (database queries, GitHub actions, Slack messages). Subagents can use those MCP tools in isolated contexts—e.g., a read-only database subagent that connects via the Postgres MCP server but can never run write queries.
- AGENTS.md — When a subagent needs to build, test, or deploy your project, it reads AGENTS.md for the commands. Your test-runner subagent doesn't guess
npm testvspnpm test—it reads AGENTS.md and runs the right one.
When to Use Subagents vs. Main Conversation
| Use main conversation when… | Use subagents when… |
|---|---|
| The task needs frequent back-and-forth or iterative refinement. | The task produces verbose output you don't need to see. |
| Multiple phases share significant context (planning → implementation → testing). | You want to enforce specific tool restrictions or permissions. |
| You're making a quick, targeted change. | The work is self-contained and can return a summary. |
| Latency matters. | Context isolation matters more than speed (subagents start fresh). |
Rule of thumb: If you find yourself thinking "I don't need to see all this test output" or "I want this to be read-only," use a subagent.
Real-World Examples
Example 1: Engineering team at a SaaS company
Problem: Code reviews take too long. Engineers manually check for common issues (hardcoded secrets, missing error handling, no tests).
Solution: Custom code-reviewer subagent in .cursor/agents/.
---
name: code-reviewer
description: Reviews code for quality, security, and best practices. Use proactively after code changes.
tools: Read, Grep, Glob, Bash
model: sonnet # Sonnet 4.6
---
Run `git diff` to see recent changes. Focus on modified files.
Review checklist:
- No hardcoded secrets or API keys
- Proper error handling
- Input validation
- Test coverage
- Performance considerations
Provide feedback by priority: Critical, Warning, Suggestion.
Result: Engineers run /code-reviewer before opening a PR. The subagent catches common issues in seconds. PR review time drops by 40%.
Example 2: Data science team
Problem: Analysts need to query the data warehouse but accidentally run DELETE queries that corrupt data.
Solution: db-reader subagent with read-only enforcement.
---
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'
---
You are a database analyst with read-only access. Execute SELECT queries to answer questions.
You cannot modify data. If asked to INSERT, UPDATE, or DELETE, explain that you only have read access.
Result: Analysts query the database safely. Attempted write operations fail with a clear error. No more accidental data corruption.
Example 3: Open-source maintainer
Problem: Contributors don't follow the project's code style (functional components, early returns, no any).
Solution: style-enforcer subagent with project-specific memory.
---
name: style-enforcer
description: Enforces project code style and conventions. Use proactively on new contributions.
tools: Read, Edit
memory: project
---
Enforce project style:
- Functional components, early returns
- No `any` types
- Use `zod` for validation
- Wrap API routes in `try/catch`
Check your memory for additional conventions. Update your memory when you discover new patterns.
Result: The subagent learns project conventions over time. New contributors get consistent, automated style feedback before human review.
Quick Check
You want an agent to query your production database for analysis but you're worried about accidental data corruption. What's the best approach?
Common Pitfalls
1. Creating too many generic subagents
Mistake: You create 50 subagents with vague descriptions like "general helper" or "does coding tasks."
Fix: Each subagent should have a single, clear responsibility. If you can't describe when to use it in one sentence, it's too generic.
2. Not updating descriptions
Mistake: Your subagent's description says "reviews code" but it actually does security audits, performance analysis, and architectural reviews.
Fix: The description field is how the main agent decides when to delegate. Be specific: "Security auditor. Use when implementing auth, payments, or handling sensitive data."
3. Expecting subagents to "figure it out"
Mistake: You delegate a vague task ("make the app better") to a subagent and expect it to succeed.
Fix: Subagents are specialists, not mind readers. Give them clear, bounded tasks: "Find all hardcoded API keys in the codebase and flag them."
4. Ignoring tool restrictions
Mistake: You want a read-only subagent but forget to set disallowedTools: Edit, Write. It modifies code anyway.
Fix: Always explicitly configure tool access for subagents with security implications. Use tools (allowlist) or disallowedTools (denylist).
5. Not using persistent memory
Mistake: Your subagent encounters the same issues repeatedly but has no memory, so it gives the same feedback every time.
Fix: Enable memory: user or memory: project for subagents that should learn over time (code reviewers, debuggers, security auditors).
You ask the agent to 'run all tests and report failures.' Your main conversation fills with 500 lines of test output. You scroll forever to find the 3 failures. The agent's context is now bloated with test logs.
Click "With subagents" to see the difference →
Quick Check
When should you use a subagent instead of running the task in your main conversation?
Do This Next
- Try a built-in subagent. Ask your agent: "Use the Explore subagent to find all places we call the deprecated API." Watch how it delegates and returns only the summary.
- Create your first custom subagent. Pick a task you do often (code review, test running, database queries). Use
/agents(Cursor/Claude Code) or write a file in.cursor/agents/. Make it read-only (disallowedTools: Edit, Write) to start safe. - Add persistent memory. If you created a code-reviewer subagent, add
memory: userso it learns your project's conventions over time. - Chain subagents. Try a multi-step workflow: "Use the code-reviewer to find issues, then use the debugger to fix them, then use the test-runner to verify."
- Share with your team. If you created a project subagent (
.cursor/agents/), check it into version control. Let your team use and improve it.
By experience tier:
- 1–3 years: Start by observing built-in subagents in action. Ask your agent to "explore how the auth system works" and notice how it delegates to the Explore subagent. You'll see the summary without the 50 file reads it took to get there.
- 4–7 years: Create your first custom subagent—a test runner is the easiest win. Save it in
.cursor/agents/or.claude/agents/. Make it read-only to start (disallowedTools: Edit, Write). - 8–15 years: Build a code-reviewer subagent with your team's specific conventions. Enable
memory: projectso it learns your patterns over time. Check it into version control so the whole team benefits. - 15–20 years: Design subagent architectures for your org. Which subagents should be shared (code review, security)? Which are team-specific? Create templates and governance around tool permissions.
- 20–30 years: Think of subagents as your team's institutional knowledge, codified. A well-configured code-reviewer subagent with persistent memory is your team's code review standards, executable and consistent. That's a different kind of documentation.
- 30+ years: You've seen the pattern before: specialized workers with clear interfaces and bounded responsibilities. That's microservices. That's Unix philosophy. Subagents are the same principle applied to AI workflows. The architecture instincts you've built over decades apply directly.
Resources
- Cursor subagents: cursor.com/docs/context/subagents
- Claude Code subagents: code.claude.com/docs/en/sub-agents
- Gemini CLI subagents: geminicli.com/docs/core/subagents
- Hooks for validation: Cursor hooks docs
- Agent Skills (complementary): See Agent Skills Mastery for reusable procedures