All posts
AI AgentsJuly 21, 2026ยท 14 min read

Claude Code Subagents: What We Learned Running 18 of Them in Production

Every subagent guide demonstrates with the same code-reviewer toy example. We run 18 subagents in production: the real directory listing, the 6/11/1 model split, how they hand off work through files, and the failure modes we hit.

Mert BaturAuthor
Claude Code subagents process diagram: one main session fanning out to worker agents that write research.md, brief.md, en.md and meta.json
On this page

Claude Code Subagents: What We Learned Running 18 of Them in Production

Eighteen Claude Code subagents ship every post on this site, including this one. Six run on Opus, eleven on Sonnet, one on Haiku. The researcher agent alone has accumulated 74 memory files since we started. None of them talk to each other. That last part surprised us most: a subagent never sees your conversation, and it never sees another subagent's conversation either. So the entire pipeline is built around files on disk instead. Here's the fleet, the model split, the memory setup, and the things that broke on the way.

The short version:

  • A subagent runs in its own context window with its own system prompt, tools, and permissions.
  • We run 18 subagents: 6 on Opus, 11 on Sonnet, 1 on Haiku.
  • Agents hand off through files on disk, never through shared context.
  • As of v2.1.198 the /agents creation wizard is gone. Write the file yourself.

What Is a Claude Code Subagent?

A Claude Code subagent is a specialized assistant that runs in its own context window with a custom system prompt, specific tool access, and independent permissions. It does a side task without flooding your main conversation, then returns only its summary. Definitions live as Markdown files with YAML frontmatter in .claude/agents/, documented in Anthropic's subagent reference.

Claude delegates to one automatically. It reads the description field on every subagent it can see, and when a task matches, it hands the work over without asking you first. As of v2.1.198 those subagents run in the background by default, so the delegation often happens while you keep typing. You can also call one by name when you want a specific worker on a specific job.

Three built-ins ship with Claude Code: Explore for read-only codebase search, Plan for planning work, and general-purpose for everything else.

One naming detail that trips up older guides and older config files: the tool that spawns a subagent is called Agent, not Task. It was renamed in v2.1.63, and the docs confirm existing Task(...) references still work as aliases. We use Agent throughout this post.

The rest of this is not a reference. Anthropic's docs already do that job better than we could, at roughly 8,000 words with version annotations running down to v2.1.212. What follows is what eighteen of these look like when they run every day.

Our 18-Agent Fleet: What a Real Setup Looks Like on Disk

Our .claude/agents/ directory holds 18 subagent definition files, each a Markdown file with YAML frontmatter. Together they run the whole content pipeline for this site: research, briefing, writing, validation, translation into nine languages, image generation, and publishing. Six run on Opus, eleven on Sonnet, one on Haiku.

Every subagent guide on the first page of Google demonstrates with the same code-reviewer example copied out of the docs. Here is what eighteen of them look like when they actually ship work.

text
.claude/agents/
โ”œโ”€โ”€ abc-link-checker.md
โ”œโ”€โ”€ brief-creator.md
โ”œโ”€โ”€ content-gap-finder.md
โ”œโ”€โ”€ content-refresher.md
โ”œโ”€โ”€ content-writer.md
โ”œโ”€โ”€ image-handler.md
โ”œโ”€โ”€ language-translator.md
โ”œโ”€โ”€ payload-publisher.md
โ”œโ”€โ”€ pipeline-manager.md
โ”œโ”€โ”€ rank-checker.md
โ”œโ”€โ”€ rescue-diagnoser.md
โ”œโ”€โ”€ rescue-prioritizer.md
โ”œโ”€โ”€ researcher.md
โ”œโ”€โ”€ sanity-publisher.md
โ”œโ”€โ”€ seo-auditor.md
โ”œโ”€โ”€ sitemap-checker.md
โ”œโ”€โ”€ translation-coordinator.md
โ””โ”€โ”€ validator.md

They group into four jobs. Content production runs researcher into brief-creator into content-writer into validator. Distribution covers translation-coordinator, language-translator, image-handler, payload-publisher and sanity-publisher. Maintenance is content-refresher, rank-checker, rescue-diagnoser, rescue-prioritizer, seo-auditor, sitemap-checker and abc-link-checker. Coordination is pipeline-manager and content-gap-finder.

Two of those files, copied verbatim off disk, carry the whole cost argument:

yaml
# .claude/agents/researcher.md
name: researcher
tools: Read, Write, Glob, Grep, WebSearch, WebFetch, Bash
model: opus
memory: project
skills:
  - seo
  - competitor-analysis
yaml
# .claude/agents/sitemap-checker.md
name: sitemap-checker
tools: Read, Write, Edit, Glob, Grep, WebFetch
model: haiku

Same mechanism, roughly ten times the cost per token. One is an Opus agent with web access and persistent memory that decides what a post should argue. The other is a Haiku agent that fetches a sitemap and writes a JSON file. Nothing in the subagent format forces you to pay Opus rates for the second job, and most fleets we've seen do exactly that by default.

The skills: field on researcher preloads two skill definitions into that subagent's system prompt at spawn time, which is how it knows our SEO conventions without being told each run. If you haven't written one yet, we covered how to write a Claude skill separately, and this post won't repeat it.

If you want a browsable catalogue of definitions to copy from, the community awesome-claude-code-subagents collection is the one people are actually searching for. Read it for shapes, not for currency: some entries predate the Agent rename.

How Do You Create a Subagent? (The /agents Wizard Is Gone)

You create a Claude Code subagent by writing a Markdown file into .claude/agents/ yourself, or by asking Claude to write it for you. As of v2.1.198 the /agents command no longer opens the interactive creation wizard. Running it now just prints a reminder pointing you at the directory.

  1. Create the file. .claude/agents/{name}.md for a project subagent that ships in version control, or ~/.claude/agents/{name}.md for one that follows you across projects.
  2. Write name and description. The description decides more than anything else in the file, because it is what Claude matches against when choosing whether to delegate. Write it as a routing rule, not a job title.
  3. Set tools and model. tools is an allowlist; omit it and the subagent inherits the main conversation's tools. model overrides your session model.
  4. Write the system prompt as the Markdown body below the frontmatter. Subagents receive only this prompt plus basic environment details, not the full Claude Code system prompt.
  5. Invoke it. Automatically, by letting the description match, or explicitly by asking for it by name.
markdown
---
name: changelog-writer
description: Writes release notes from merged pull requests. Use when the user asks for a changelog, release notes, or a summary of what shipped.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You write release notes. Read the merged PRs since the last tag with `git log`,
group them into Added / Changed / Fixed, and write one line per change in past
tense. Never invent a change that is not in the log. Return only the markdown.

Several currently-ranking guides still tell readers to run /agents to open the management interface. That instruction is dead. One more gotcha the docs are explicit about: the file watcher covers only directories that existed when the session started, so the first agent file in a brand-new agents/ directory needs a Claude Code restart before it loads.

VersionWhat changedWhat it means for you
v2.1.63Task tool renamed to AgentTask(...) still works as an alias, so older agent files keep running
v2.1.172A subagent can spawn its own subagentsNesting works, at a fixed depth of five that you cannot configure
v2.1.198/agents no longer opens the creation wizardAsk Claude to write the file, or edit .claude/agents/ yourself
v2.1.198Subagents run in the background by defaultClaude uses the foreground only when it needs the result to continue
v2.1.208An unresolvable tools list refuses to launchYou get an error naming the bad entries instead of a silent empty result
v2.1.212Cap of 200 subagents per sessionRaise it with CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION; it cannot be disabled

Subagent vs Skill vs Agent Team vs Fork: Which One Do You Actually Need?

Pick a subagent when a side task would flood your main conversation and you only need the summary back. Pick a skill when you want to teach Claude a procedure it runs inside your existing context. Pick an agent team when workers must coordinate with each other. Pick a fork when the side task needs your conversation history.

SubagentSkillAgent teamFork
ContextOwn windowThe main conversation's contextOwn window plus a shared task listInherits the full conversation
CommunicationReports to the main agent only, never to another subagentNot applicable, it loads into your sessionMembers message each other directlyNot applicable, it branches your session
Cost profileFresh context on every spawnCheapest, no new context createdSignificantly more tokensReuses the parent's prompt cache
StatusStableStableExperimental, off by default behind CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1Stable
Pick it whenA side task would flood your main conversationYou want a repeatable procedure inside the current contextSeveral workers must coordinate, not just report backYou need a side task that already knows the conversation

Subagents report to you and never to each other. Agent teams message each other directly. That one difference decides which primitive you need.

Our default is the subagent, and we've never needed a team. Coordination in our pipeline is sequential rather than conversational, so a shared task list would buy nothing and cost tokens. Teams are also still experimental and off by default, which is a hard stop for anything we run unattended. Skills sit at a different layer entirely: they're instructions loaded into whichever context is already running, including a subagent's, which is why researcher declares two of them rather than delegating to them.

Model Selection: Which Agents Belong on Haiku, Sonnet, and Opus

Set model in a subagent's frontmatter to haiku, sonnet, opus, or a specific model ID, and that subagent overrides your session model. Our real distribution across 18 agents is six on Opus, eleven on Sonnet, one on Haiku, assigned by how much judgment the agent's output actually requires.

TierModel (count)AgentsThe rule that put them there
Judgmentopus (6)researcher, brief-creator, content-writer, validator, rescue-diagnoser, abc-link-checkerThe output is a judgment call and a bad one costs a full rewrite
Executionsonnet (11)content-refresher, content-gap-finder, payload-publisher, image-handler, language-translator, rescue-prioritizer, rank-checker, pipeline-manager, seo-auditor, sanity-publisher, translation-coordinatorThe task is well specified and the shape of a correct answer is already known
Mechanicalhaiku (1)sitemap-checkerThe output is deterministic and the input is small

Three rules we'd hand to anyone tiering a fleet. Put an agent on Haiku when its output is deterministic and its input is small: fetching, parsing, counting, reformatting. Put an agent on Sonnet when the task is long and well specified but somebody already decided what "correct" looks like, which covers most execution work including all nine translation workers. Reserve Opus for agents whose output nothing downstream will second-guess.

That last rule is why validator sits on Opus even though it produces a short report. Nothing checks the checker.

One version note that changes the arithmetic: since v2.1.198 the built-in Explore subagent no longer always runs on Haiku, it inherits the session model. A user- or project-level subagent named Explore overrides the built-in and keeps its own model field, so define one with model: haiku if you want exploration held on a cheap model.

File Contracts: How Our Agents Hand Off Work Without Sharing Context

A subagent doesn't see your conversation history, and it doesn't see any other subagent's. In-memory handoffs between agents are therefore structurally impossible. The fix is to make every handoff an artifact on disk, so the next agent reads a file rather than inheriting a context it can never have.

text
techsy.community/posts/claude-code-subagents/
โ”œโ”€โ”€ research.md      # researcher       โ†’ SERP analysis, keyword data, gaps
โ”œโ”€โ”€ brief.md         # brief-creator    โ†’ section-by-section spec
โ”œโ”€โ”€ en.md            # content-writer   โ†’ the post you are reading
โ”œโ”€โ”€ de.md            # language-translator (one subagent per language)
โ”œโ”€โ”€ hero.webp        # image-handler
โ”œโ”€โ”€ validation.md    # validator
โ””โ”€โ”€ meta.json        # pipeline stage, updated by a PostToolUse hook

Five artifacts, each written by a different agent, each read by the next, every one of them readable by a human and tracked in git. The pipeline survives context limits because no agent ever needs another agent's context. It only needs the previous agent's file.

The clearest payoff is translation. translation-coordinator reads en.md, then spawns one language-translator subagent per language, nine or ten of them at once. In our repo the concurrency depends on issuing all the spawn calls in a single message: that's observed behavior on our setup rather than something the docs state, but it has been consistent enough that the coordinator is written to do it deliberately. Each translator writes its own {lang}.md and none of them can see each other's work, which is fine, because the contract is the file and the file is already complete.

This is also where subagents stop and something else starts. Subagents work inside a single session. If you want genuinely independent workspaces with their own histories, you're running multiple Claude Code sessions instead, or reaching for isolation: worktree to give one subagent its own copy of the repository.

How Do Subagents Remember Things Between Sessions?

Only if you set the memory field, which takes three scopes: user writes to ~/.claude/agent-memory/<name>/, project writes to .claude/agent-memory/<name>/, and local writes to .claude/agent-memory-local/<name>/. Without it, every invocation starts blank. Twelve of our eighteen agents declare memory: project.

After roughly forty posts, those directories are substantial. researcher holds 74 memory files, validator 66, brief-creator 65. They are not logs. They're accumulated rulings: which H1 patterns underperformed, which client claims we can't make, which SERP shapes reward a table over prose.

Here's the constraint that shapes all of it. A memory-enabled subagent gets only the first 200 lines or 25KB of MEMORY.md injected into its system prompt, whichever comes first. That single limit is why every one of our agents keeps an index instead of a journal.

markdown
# Researcher Memory

## Reusable post patterns
- [Challenger H1 pattern](feedback_challenger_h1_pattern.md): when a question-shaped H1 earns the click
- [Sponsored post research](feedback_sponsored_post_research.md): H1 must be category-shaped, never a review
- [Claude Skills tutorial](project_claude_skills_tutorial.md): docs own the top two slots, target the long tail

One line per entry, detail pushed into the linked topic file, which the agent reads on demand with its Read tool. MEMORY.md stays an index that fits inside the injection budget while the corpus behind it grows without limit.

We use project rather than user for almost everything, because project memory lives in the repo and travels through version control. When a teammate pulls, they pull the agent's accumulated judgment with the code. local exists for the cases where you want the notes but not the commit.

What Broke: Failure Modes, Duplicate Names, and a Legacy Alias in Our Own Repo

Four failure modes account for nearly everything we've hit. A subagent that refuses to launch, a subagent that silently isn't the one you edited, a subagent Claude can't find at all, and a hard session ceiling on how many you can spawn. All four have short, unambiguous fixes.

SymptomCauseFix
Refuses to launch, error names your tool entriesNothing in tools resolves. Before v2.1.208 it launched with no tools and returned a confusing empty resultFix the entries; the error names them for you
Only one of two same-named agents ever loadsDuplicate name in the same tree, resolved by filesystem read order rather than documented precedenceKeep name unique tree-wide; /doctor reports duplicates since v2.1.205
New agent not found at allThe watcher covers only directories that existed at session startRestart Claude Code
Agent tool fails with Subagent spawn limit reachedThe 200-subagent session cap added in v2.1.212Raise CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION

The duplicate-name one is nastier than it reads. You edit a file, the behavior doesn't change, and there's no error anywhere, because a different file with the same name won the read order.

Hooks helped more than we expected for the failures that aren't errors at all, just steps a human forgets. Ours is deliberately dumb:

json
"SubagentStop": [
  {
    "matcher": "content-writer",
    "hooks": [
      {
        "type": "command",
        "command": "echo 'Content writer finished. Run /validate to check quality and SEO compliance.'"
      }
    ]
  }
]

Now the honest one. While writing this post we grepped our own fleet and found this still sitting in translation-coordinator.md:

yaml
# .claude/agents/translation-coordinator.md
name: translation-coordinator
tools: Read, Write, Glob, Grep, Task
model: sonnet

Task, not Agent. That field has been stale since v2.1.63 and it has never once failed, because Anthropic kept the alias. We haven't cleaned it up yet. If your own agent files still say Task, they're not broken, they're just old, and the alias is doing quiet work for a lot of repos right now.

One correction in the other direction: guides written before v2.1.172 tell readers a subagent cannot spawn subagents. It can, and has since that release. Depth is fixed at five levels below the main conversation and is not configurable, so a subagent at depth five simply doesn't receive the Agent tool.

What Subagents Cost, and When Not to Use One

Every subagent spawn creates a fresh context window, so delegation is never free. Anthropic's engineering team reports that agents use roughly 4x more tokens than chat interactions and multi-agent systems roughly 15x more, and that token usage alone explains 80% of the performance variance they measured.

We have no token measurements of our own to add, so treat any specific multiplier you read on this topic, including the 4x-to-7x figures floating around other blog posts, as that author's number rather than a benchmark. Anthropic's multi-agent research system writeup is the one source here with real data behind it, and the same study found an Opus lead agent with Sonnet subagents beat a single Opus agent by 90.2% on their internal evaluation. That result, not the token count, is the case for tiering.

Skip the subagent when the output belongs in your main conversation anyway, because you'll only paste it back in and pay twice. Skip it for small edits where the delegation round trip costs more than doing the work. And skip it when the task genuinely needs your conversation history: use a fork instead, which inherits the full conversation and reuses the parent's prompt cache, making it cheaper than a fresh subagent for context-heavy side work. Anthropic's own cost guidance and their when-to-use framing both land in the same place.

The 200-per-session cap is worth knowing before you design a fan-out. It's a real ceiling on runaway delegation, and raising it is a deliberate act rather than a default.

About the author

Mert Batur builds at Techsy, where the team ships AI agents, automation systems, and voice/SDR pipelines for B2B clients. He writes about the LLM tooling stack and Claude Skills the Techsy team actually uses in production.

Techsy โ€” University of Birmingham ยท LinkedIn

Frequently Asked Questions

What are Claude Code subagents?

Claude Code subagents are specialized assistants that each run in their own context window with a custom system prompt, restricted tool access, and independent permissions. You define one as a Markdown file with YAML frontmatter in .claude/agents/. The subagent does a side task and returns only its summary to your main conversation.

Does Claude Code use subagents automatically?

Yes. Claude reads the description field of every subagent available to it and delegates when a task matches, without asking you first. As of v2.1.198 subagents run in the background by default, so the delegated work often happens while you keep typing in the main conversation.

Where do subagent files live?

Project subagents live in .claude/agents/ and user subagents in ~/.claude/agents/. Both locations are scanned recursively, so subfolders are fine. Identity comes only from the name frontmatter field, never the path. Managed subagents deployed by an administrator take precedence over project and user definitions sharing a name.

How do I invoke a subagent explicitly?

Ask for it by name in your prompt, for example "use the validator subagent on this draft." Explicit invocation bypasses the description matching that drives automatic delegation, which helps when two of your subagents have overlapping descriptions and Claude keeps reaching for the wrong one.

Can a subagent spawn its own subagents?

Yes, since Claude Code v2.1.172. Guides written before that release state nesting is impossible, and they are out of date. Depth counts levels below the main conversation and is fixed at five: a subagent at depth five doesn't receive the Agent tool. The limit is not configurable.

Do subagents remember anything between sessions?

Only if you set the memory field. It accepts user for ~/.claude/agent-memory/<name>/, project for .claude/agent-memory/<name>/, or local for .claude/agent-memory-local/<name>/. Without it, every invocation starts blank. Twelve of our eighteen agents use memory: project so their notes travel in version control.

Can a subagent use a different model than my session?

Yes. Set model in the frontmatter to haiku, sonnet, opus, or a specific model ID, and it overrides your session model for that subagent. Our fleet splits six on Opus, eleven on Sonnet, and one on Haiku, assigned by how much judgment each agent's output requires.

Why isn't my new subagent showing up?

Three usual causes. The agents directory didn't exist when the session started, so the watcher never picked it up: restart Claude Code. Or two files share the same name and only one loads. Or nothing in your tools list resolves, which since v2.1.208 refuses to launch with a naming error.

Is Task still a valid tool name?

Yes, as an alias. The Task tool was renamed Agent in v2.1.63, and existing Task(...) references still work in settings and agent definitions. Write Agent in new files. Our own translation-coordinator.md still declares Task, which we found while writing this post and haven't cleaned up.

Three Things to Take Away

If you're standing up your first fleet, start here. The description field decides everything, because it's what Claude reads when picking a worker, so write it as a routing rule rather than a job title. Design the handoff as a file before you design the agent, since no subagent will ever see another's context. And put each agent on the cheapest model that can produce a correct answer, then move it up only when you catch it being wrong.

Explore the full library for the specs behind this pipeline.

Related posts