Anthropic: a multi-agent research system
When Claude's Research feature answers a broad question, it doesn't use one agent. A lead agent plans the research, starts several subagents that search in parallel, each in its own context window, and then writes the answer from their findings. In June 2025 Anthropic published how they built it, with numbers: a large gain over a single agent, a large token bill, and a list of ways early versions went wrong. It's the clearest public evidence for when the supervisor architecture pays.
- Sam Is there real evidence that multiple agents beat one?
- Priya For one kind of work, yes. In June twenty twenty-five Anthropic described how Claude's Research feature works: a lead agent plans, starts several subagents that search in parallel, each in its own context window, and writes the answer from their findings.
- Sam What did it achieve?
- Priya It beat a single agent by ninety point two percent on their internal research evaluation. But agents use about four times the tokens of a chat, and the multi-agent system about fifteen times. On one benchmark, token usage alone explained eighty percent of the difference in performance. Parallel searching cut research time by up to ninety percent on complex questions. They say it fits breadth-first questions with many independent directions, and only high-value tasks.
- Sam How does it work step by step?
- Priya The lead thinks through its approach and saves the plan to memory. It gives each subagent an objective, an output format, and guidance on tools and sources. The subagents search in parallel in their own windows and return summaries. The lead decides whether to dig further, writes the report, and a citation step attaches sources.
- Sam And the demo?
- Priya A model with illustrative numbers. For a simple fact, the team is slower and costs two and a half times the tokens. For broad research, one agent answers four of eight sub-questions before its window fills; the team answers all eight, faster, for about one point seven times the tokens.
- Priya Your turn. Early versions spawned fifty subagents for a simple question. What fixed it?
- Priya Telling the lead to scale effort to the question. A simple fact needs one agent and a few tool calls.
- Sam What should I take from it?
- Priya Use a supervisor for breadth: research, multi-angle review, surveys. Not for coupled work, where the next case applies. Budget for the tokens. Brief subagents like a manager would. And treat subagents as a way to keep each search out of the lead's context.
1. The situation
Research questions such as "find all the board members of the companies in this sector" have many independent leads. One agent working through them in sequence runs out of context window and time; it has to keep every search result in one place while it decides where to look next.
2. What they built, and what it achieved
| Finding | Reported |
|---|---|
| Quality | A lead (Claude Opus 4) with subagents (Claude Sonnet 4) beat a single Opus 4 agent by 90.2% on Anthropic's internal research evaluation |
| Cost | Agents use about 4× the tokens of a chat; "multi-agent systems use about 15× more tokens than chats" |
| What drives results | On the BrowseComp evaluation, three factors explained 95% of the variance in performance; token usage alone explained 80% |
| Speed | Running subagents in parallel, each using tools in parallel, cut research time by up to 90% for complex queries |
| Fit | Best for breadth-first questions with many independent directions; the economics work only for high-value tasks |
3. How it works
Orchestrator-worker: the architecture Module 07a calls a supervisor.
4. The trade-off in code
A model of the trade-off, with illustrative numbers. One agent keeps every result in one window, rereading it each step, until the window is full. A lead with subagents gives each sub-question a fresh window, so subagents can dig deeper and all run at once. For a simple fact, the team is slower and costs 2.5× the tokens. For broad research, one agent answers only half the sub-questions before its window fills; the team answers all eight, faster, for 1.7× the tokens. The program was run in all three languages; each prints the output below it.
WINDOW = 30000 # tokens one agent's context can usefully hold
RESULT = 2000 # tokens each search or page read adds
STEP = 4 # seconds per tool call
BRIEF, SUMMARY = 500, 1500 # tokens: a task brief, a subagent's returned summary
CALLS_SINGLE = 3 # tool calls per sub-question for one agent sharing its window
CALLS_SUB = 5 # a subagent with its own window can afford to dig deeper
def single_agent(questions):
"""One agent, one context: every result stays in the window, and each step rereads it."""
context, processed, covered, calls = BRIEF, 0, 0, 0
for _ in range(questions):
if context + CALLS_SINGLE * RESULT > WINDOW:
break # the window is full: the rest goes unanswered
for _ in range(CALLS_SINGLE):
processed += context
context += RESULT
calls += 1
covered += 1
return covered, calls * STEP, processed + context
def lead_and_subagents(questions):
"""The lead writes a brief per sub-question; subagents research in parallel, each in a fresh window."""
processed = BRIEF + questions * BRIEF # the lead plans and writes briefs
for _ in range(questions):
context = BRIEF
for _ in range(CALLS_SUB):
processed += context
context += RESULT
processed += context # the subagent writes its summary
processed += questions * SUMMARY # the lead reads every summary and writes the answer
return questions, CALLS_SUB * STEP, processed
for questions, kind in ((1, "simple fact"), (8, "broad research")):
c1, t1, k1 = single_agent(questions)
c2, t2, k2 = lead_and_subagents(questions)
print(f"{kind}, {questions} sub-question{'s' if questions > 1 else ''}:")
print(f" one agent: answered {c1}/{questions}, {t1:3} s, {k1:7,} tokens")
print(f" lead + subagents: answered {c2}/{questions}, {t2:3} s, {k2:7,} tokens ({k2 / k1:.1f}x the tokens)")
const WINDOW = 30000; // tokens one agent's context can usefully hold
const RESULT = 2000; // tokens each search or page read adds
const STEP = 4; // seconds per tool call
const BRIEF = 500, SUMMARY = 1500; // tokens: a task brief, a subagent's returned summary
const CALLS_SINGLE = 3; // tool calls per sub-question for one agent sharing its window
const CALLS_SUB = 5; // a subagent with its own window can afford to dig deeper
// One agent, one context: every result stays in the window, and each step rereads it.
function singleAgent(questions: number): [number, number, number] {
let context = BRIEF, processed = 0, covered = 0, calls = 0;
for (let q = 0; q < questions; q++) {
if (context + CALLS_SINGLE * RESULT > WINDOW) break; // the window is full: the rest goes unanswered
for (let c = 0; c < CALLS_SINGLE; c++) { processed += context; context += RESULT; calls++; }
covered++;
}
return [covered, calls * STEP, processed + context];
}
// The lead writes a brief per sub-question; subagents research in parallel, each in a fresh window.
function leadAndSubagents(questions: number): [number, number, number] {
let processed = BRIEF + questions * BRIEF; // the lead plans and writes briefs
for (let q = 0; q < questions; q++) {
let context = BRIEF;
for (let c = 0; c < CALLS_SUB; c++) { processed += context; context += RESULT; }
processed += context; // the subagent writes its summary
}
processed += questions * SUMMARY; // the lead reads every summary and writes the answer
return [questions, CALLS_SUB * STEP, processed];
}
const fmt = (n: number, w: number) => n.toLocaleString("en-US").padStart(w);
for (const [questions, kind] of [[1, "simple fact"], [8, "broad research"]] as [number, string][]) {
const [c1, t1, k1] = singleAgent(questions), [c2, t2, k2] = leadAndSubagents(questions);
console.log(`${kind}, ${questions} sub-question${questions > 1 ? "s" : ""}:`);
console.log(` one agent: answered ${c1}/${questions}, ${String(t1).padStart(3)} s, ${fmt(k1, 7)} tokens`);
console.log(` lead + subagents: answered ${c2}/${questions}, ${String(t2).padStart(3)} s, ${fmt(k2, 7)} tokens (${(k2 / k1).toFixed(1)}x the tokens)`);
}import java.util.Locale;
public class Main {
static final int WINDOW = 30000; // tokens one agent's context can usefully hold
static final int RESULT = 2000; // tokens each search or page read adds
static final int STEP = 4; // seconds per tool call
static final int BRIEF = 500, SUMMARY = 1500; // tokens: a task brief, a subagent's returned summary
static final int CALLS_SINGLE = 3; // tool calls per sub-question for one agent sharing its window
static final int CALLS_SUB = 5; // a subagent with its own window can afford to dig deeper
// One agent, one context: every result stays in the window, and each step rereads it.
static int[] singleAgent(int questions) {
int context = BRIEF, processed = 0, covered = 0, calls = 0;
for (int q = 0; q < questions; q++) {
if (context + CALLS_SINGLE * RESULT > WINDOW) break; // the window is full: the rest goes unanswered
for (int c = 0; c < CALLS_SINGLE; c++) { processed += context; context += RESULT; calls++; }
covered++;
}
return new int[] {covered, calls * STEP, processed + context};
}
// The lead writes a brief per sub-question; subagents research in parallel, each in a fresh window.
static int[] leadAndSubagents(int questions) {
int processed = BRIEF + questions * BRIEF; // the lead plans and writes briefs
for (int q = 0; q < questions; q++) {
int context = BRIEF;
for (int c = 0; c < CALLS_SUB; c++) { processed += context; context += RESULT; }
processed += context; // the subagent writes its summary
}
processed += questions * SUMMARY; // the lead reads every summary and writes the answer
return new int[] {questions, CALLS_SUB * STEP, processed};
}
public static void main(String[] args) {
int[][] runs = {{1}, {8}};
String[] kinds = {"simple fact", "broad research"};
for (int i = 0; i < 2; i++) {
int questions = runs[i][0];
int[] a = singleAgent(questions), b = leadAndSubagents(questions);
System.out.println(kinds[i] + ", " + questions + " sub-question" + (questions > 1 ? "s" : "") + ":");
System.out.println(String.format(Locale.US, " one agent: answered %d/%d, %3d s, %,7d tokens", a[0], questions, a[1], a[2]));
System.out.println(String.format(Locale.US, " lead + subagents: answered %d/%d, %3d s, %,7d tokens (%.1fx the tokens)", b[0], questions, b[1], b[2], (double) b[2] / a[2]));
}
}
}simple fact, 1 sub-question:
one agent: answered 1/1, 12 s, 14,000 tokens
lead + subagents: answered 1/1, 20 s, 35,500 tokens (2.5x the tokens)
broad research, 8 sub-questions:
one agent: answered 4/8, 48 s, 162,500 tokens
lead + subagents: answered 8/8, 20 s, 280,500 tokens (1.7x the tokens)
5. Try it: is a team worth it?
6. What went wrong on the way
- Too many agents. Early versions spawned 50 subagents for simple queries. The fix: tell the lead to scale effort to the question; a simple fact needs one agent and 3 to 10 tool calls, complex research may need more than 10 subagents.
- Vague delegation. Short instructions led to duplicated work: one subagent explored the 2021 automotive chip crisis while two others duplicated work on 2025 supply chains. "Each subagent needs an objective, an output format, guidance on the tools and sources to use."
- Bad tool descriptions. They sent agents down wrong paths; having an agent test and rewrite tool descriptions cut task completion time by 40% for later agents.
- Endless searching. Agents looked for sources that didn't exist and sent each other excessive updates.
- Compounding errors. In long-running stateful agents, one failure derails the run, so they added checkpoints, resuming from failures, and rainbow deployments that don't break running agents.
- Evaluation. They started with about 20 test queries, judged outcomes rather than exact paths, used an LLM judge with a 0.0 to 1.0 score, and kept human testers, who caught agents preferring content farms over authoritative sources.
7. Lessons: when the supervisor pattern pays
- Use it for breadth. Many independent directions, valuable answers: research, reviews from several angles, surveys (Module 07a).
- Don't use it for coupled work. When parts depend on each other's decisions, Cognition's single-agent argument applies (C12).
- Budget for tokens. About 15× a chat. Worth it only when the better answer is worth the bill.
- Delegate like a manager. Objective, output format, tools and sources, boundaries (Module 16a).
- Subagents are context isolation. Each explores in its own window and returns a summary (Module 05a).
8. Your turn
- Find the breadth (10 min). Name one task in your work with many independent directions, and one that looks similar but is coupled.
- Write a brief (10 min). For one subagent: objective, output format, tools and sources, boundaries.
- Price it (10 min). Estimate the tokens of a single agent and a team for that task. Is the better answer worth the difference?
- "When would you use multiple agents?" For breadth-first work with independent parts, like research or multi-angle review. Anthropic's research system beat a single agent by 90% that way, but used about 15× a chat's tokens, so I'd reserve it for valuable tasks and keep coupled work in one agent.
9. Check yourself
By how much did Anthropic's multi-agent system beat a single agent on its internal research evaluation?
Roughly how many tokens did the multi-agent system use compared with a chat?
Early versions spawned 50 subagents for simple queries. What fixed it?
Which kind of task fits this architecture best?
10. Sources and further reading
| Resource | Why |
|---|---|
| How we built our multi-agent research system (Anthropic, June 2025) | Every fact and quote on this page. |
| C12: Cognition, don't build multi-agents | The counter-argument, for coupled work. |
| Modules 07a and 16a | Architectures, and running teams of agents. |