Index Ai Academy
Phase 10 · Agent harnesses · Scaling & shipping

Subagents

Hand a focused task to a fresh context with fewer tools.

About 35 minutes · A free account opens the whole lesson

Create a free account Try part of it here

Already have an account? Sign in to open this lesson

Why it matters

Ask an agent to find every place a function is used across a big codebase, and it reads dozens of files. All of that lands in its context, though the answer is a short list. A subagent does the search in its own fresh context and hands back only the list. The main agent stays focused, and its context stays clean. Used well, subagents let harnesses tackle bigger tasks. Used badly, they multiply cost and confusion.

What you'll be able to do

  • Explain what subagents buy: a clean context, focus, least privilege and parallel work
  • Weigh their costs: more tokens, lost context and edit conflicts
  • Define agent types with their own prompt, tools and limits, and expose them as a tool
  • Write briefs that give a subagent everything it needs

What it covers

  1. What a subagent is
  2. What they buy
  3. What stays out of your context
  4. What they cost
  5. Writing a good brief
  6. Is this brief enough?
  7. Parallel subagents
  8. Agent types as data
  9. Three things people get wrong

What a subagent is

Picture sending an assistant to the archive with one question. They spend all afternoon among the boxes and come back with a single page. Your desk stays clear, and you have the answer.

A subagent is the same kind of loop you've built, started by the main agent with:

  • a fresh context: no shared history, only the brief it's given;
  • its own system prompt for its role (explorer, reviewer, test runner);
  • a smaller tool set, often read-only;
  • its own limits: turns, tokens, maybe a cheaper model.

When it finishes, only its final answer goes back to the parent, as a tool result. Claude Code exposes this as a tool the model can call with a description and a prompt. The Claude Agent SDK lets you define your own agent types.

Try it now

A subagent costs tokens to save context. A vague brief gets a vague result.

What they buy

Here's what a subagent gets you, compared with doing the same work in the main conversation:

benefitexample
clean context40 files read by the explorer; the parent gets a 10-line summary
focusa reviewer prompt and only read tools: it can't wander off and edit
least privilegea web-research subagent has no file access, so injected pages can't touch the repo
parallel workthree subagents search three services at the same time

In plain words: the mess stays in the subagent's context, and you only get the answer.

Worked example

What stays out of your context

A subagent reads what it needs in its own context and sends back a summary. Compare what the main conversation holds afterward.

files_read = 40
tokens_per_file = 1200
summary = 300
turns_left = 30

direct = files_read * tokens_per_file
delegated = summary

print("reading them yourself adds:", direct, "tokens")
print("delegating adds:", delegated, "tokens")
# Everything in context is sent again on every later turn.
print("tokens resent over the next", turns_left, "turns:", direct * turns_left, "against", delegated * turns_left)
It runs right here in your browser, with nothing to install.

Context is paid for again on every turn, which is why the difference grows so large. The subagent still spent its tokens, but they don't stay around to crowd out your actual task.

What they cost

An assistant's afternoon isn't free, and they only know what you told them.

  • Tokens. Each subagent re-reads its own context. Multi-agent systems often use several times the tokens of one agent. Worth it for broad, valuable work; wasteful for small tasks.
  • Lost context. The subagent knows only the brief. A vague brief gets a vague result.
  • Conflicts. Two subagents editing the same files at once will clash. Keep parallel subagents read-only, or give each its own files or worktree.
  • Runaway trees. A subagent that starts subagents that start subagents is hard to bound. Most harnesses allow one level only.
Quick check
Which task suits a subagent best?
  1. Answering "what's 2 + 2?"
  2. Searching a large codebase for every caller of a function and reporting a list
  3. Renaming one variable in the file the main agent is editing
  4. Making five tightly linked edits across one function
Show the answer

Searching a large codebase for every caller of a function and reporting a list

Broad, read-heavy work with a short answer gains the most from a separate context.

Writing a good brief

Imagine leaving a note for a temp who starts while you're away. They can't ask you anything, so the note has to carry it all. The brief is the subagent's whole world. Include:

  1. The goal, and why it matters.
  2. What's known: what the parent already found or ruled out.
  3. Where to look: files, folders, services.
  4. The output wanted: format and length ("a list of path:line, under 20 items").
  5. Limits: read-only, time budget, what not to touch.

"Find bugs" is a weak brief. "Review src/auth/ for ways an expired session token could still be accepted. We already checked verify_token. Report each issue as path:line and one sentence, most serious first" is a strong one.

Worked example

Is this brief enough?

A subagent knows only what you tell it. This check looks for the parts a brief usually needs, to show how much a short request leaves out.

def missing(brief):
    text = brief.lower()
    checks = {
        "the goal": ["find", "why", "fix", "check", "list"],
        "where to look": ["src/", "file", "folder", "repo"],
        "what to return": ["return", "report", "answer with", "list of"],
        "what's been ruled out": ["already", "not the", "ruled out"],
    }
    return [part for part, words in checks.items() if not any(w in text for w in words)]

print(missing("Look into the login bug."))
print(missing("Find why login fails after a password reset. Look in src/auth. "
              "It's not the session store, I already checked. Return the file and line."))
In the lesson you can change this and run it.

A real check would be far smarter than word matching. The point is the shape: goal, scope, what you already know, and the form of the answer. A vague brief gets a vague result, and you pay for it.

Parallel subagents

Three people can search three floors at once. Independent subagents can run at the same time too. On a normal machine:

from concurrent.futures import ThreadPoolExecutor

briefs = {"billing": "...", "search": "...", "accounts": "..."}
with ThreadPoolExecutor(max_workers=3) as pool:
    futures = {name: pool.submit(run_subagent, "explorer", brief) for name, brief in briefs.items()}
    results = {name: f.result() for name, f in futures.items()}

The parent then combines the three short reports. (Browsers have no threads, so the exercise runs subagents one at a time.)

Quick check
Which brief will get the best result from an explorer subagent?
  1. "Find stuff about dates."
  2. "Find every caller of parse_date in src/. We know the billing module uses it. Report each as path:line, read-only."
  3. "Do what you think is best."
  4. "Look around the code."
Show the answer

"Find every caller of parse_date in src/. We know the billing module uses it. Report each as path:line, read-only."

The brief is the subagent's whole world: goal, what's known, where to look, the output wanted and the limits.

Worked example

Agent types as data

Each type is a small config. Tools are filtered against what the harness has.

HARNESS_TOOLS = {"read", "grep", "glob", "edit", "bash", "web_fetch"}

AGENT_TYPES = {
    "explorer": {"system": "Find code and report locations. Never edit.",
                 "tools": ["read", "grep", "glob"], "max_turns": 15},
    "reviewer": {"system": "Review changes for bugs. Report, don't fix.",
                 "tools": ["read", "grep", "git_diff"], "max_turns": 10},
}

for name, spec in AGENT_TYPES.items():
    offered = sorted(t for t in spec["tools"] if t in HARNESS_TOOLS)
    print(name, offered)
In the lesson you can change this and run it.

The reviewer asks for git_diff, which this harness doesn't have, so it isn't offered. Neither type gets edit or bash.

Quick check
Subagents can't start more subagents. What does this print?
def can_delegate(depth, max_depth=1):
    return depth < max_depth

print(can_delegate(0), can_delegate(1))
  1. False True
  2. True False
  3. True True
  4. False False
Show the answer

True False

0 < 1 is True and 1 < 1 is False, so it prints True False. The main agent, at depth 0, can delegate. A subagent, at depth 1, can't, which keeps cost and behavior bounded.

Three things people get wrong

A subagent can't see your conversation. It starts with nothing but its brief. Everything you worked out over the last hour, including the file you already ruled out, is invisible to it unless you write it down. This is the most common reason subagents disappoint: the brief felt complete to the person writing it, since they had all the context.

Don't delegate small things. You wouldn't send someone to the archive for a book on your own shelf. Spawning a subagent costs thousands of tokens before it does any work. If you know the file and the line, read it yourself. Subagents pay off when the search is broad, and you only need the conclusion.

Parallel subagents must not touch the same files. Two agents editing one file will overwrite each other, or make changes based on versions that no longer exist. Keep parallel ones read-only, or give each its own folder or worktree.

Fewer tools, not more

Handing a subagent every tool the main agent has feels generous. It's also risky. A subagent searching the docs doesn't need to send email, and if a page it reads contains a prompt injection, then any tool it holds can be misused. Give it only what the job needs.

There's a benefit beyond safety too. With fewer tools, each call carries fewer definitions, and the model has fewer ways to wander off. A research subagent with only read and search tools stays focused on reading and searching.

When not to use them at all

Work that needs many small decisions in sequence is usually better in one agent, because each step depends on what the last one found. Subagents suit tasks that split cleanly and don't need to talk to each other. If you find yourself passing long notes between them, one agent would probably have done it better.

Practice what you just read

  • 4 code examples you can edit and run
  • a practice exercise that checks your code
  • a 5-question quiz
  • 4 review cards for spaced repetition

Create a free account

Try a quiz question

What does the parent agent get back from a subagent?

  1. Only the subagent's final answer, as a tool result
  2. The subagent's full transcript
  3. Nothing; the subagent edits files directly
  4. The subagent's system prompt

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson