Overview
A second agent helps when it parallelizes independent work, separates cheap context from expensive context, or isolates a tool budget; otherwise it adds a hop and a failure point. Start with one agent and split only when the single-agent design is the measured bottleneck. Cost is the first constraint: Anthropic reports agents using about 4 times the tokens of a chat and multi-agent systems about 15 times. vault-orchestration works a concrete case: agents split by pipeline stage over a shared vault.
Use multiple agents when the work is genuinely parallel
- Independent subtasks: review 12 PRs, fetch 100 URLs, generate 8 variants. Fan out, then gather.
- Information beyond one context window, or many complex tools: a worker explores a slice and returns a summary.
- Isolated tool budgets: a search agent gets search, a writer gets file write, and neither can call the other’s tools.
Anthropic found the pattern poorly suited to work where all agents need the same context or have many dependencies on each other, which describes most coding tasks. If none of the signals above apply, one agent with a better prompt is cheaper and easier to debug.
Use orchestrator-worker for fan-out
One agent decomposes the task, dispatches workers, and merges. Workers do not talk to each other and are stateless across items; the orchestrator alone holds the global view.
Orchestrator: "Review these 12 PRs. Return one verdict object each."
-> Worker[n]: review PR #4nn -> {verdict, reasons}
Orchestrator: merge into one report.Tell the orchestrator how much effort to spend. In Anthropic’s research system the prompt scaled it: simple fact-finding used one agent with a few tool calls, direct comparisons a few subagents, complex research many. Anthropic found that agents struggle to judge appropriate effort, so put a rule like this in the orchestrator prompt. For Claude Code mechanics see claude-code-subagents.
Use planner-executor when context is expensive
The planner reads the world once and writes numbered steps, each with inputs, expected output, and a verification command. The executor takes step N with the plan as its only context, verifies, and advances. Persist the plan in a file the executor re-reads each step. See agent-architecture-patterns.
Use a bounded reviewer loop for quality
A writer drafts, a reviewer returns a structured critique against a rubric, the writer revises.
rounds = 0
while rounds < MAX_ROUNDS and verdict != "approve":
draft = writer.run(brief, feedback)
feedback, verdict = reviewer.run(draft, rubric)
rounds += 1The reviewer must return structured-output; free-form critique loops do not terminate cleanly. A reviewer asked to find gaps will usually find some, so tell it to report only gaps that affect correctness or the stated requirements.
Hand off through typed messages
Agents exchange JSON with fields the receiver expects, not chat. Free-form messages drift, and schemas make logs greppable.
{ "task_id": "review-401", "input": { "pr_url": "..." },
"output": { "verdict": "approve", "reasons": ["..."] },
"cost": { "input_tokens": 4210, "output_tokens": 380 } }For large outputs, have the worker write an artifact (a file or MCP resource) and return a reference; this avoids copying big payloads through the conversation and losing information in multi-stage processing. Treat every handoff as untrusted input to the next agent; see prompt-injection-defense.
Cap iterations, spend, and time
Every loop needs a termination condition and every run a cost ceiling: a maximum number of rounds or steps (for example 3 for review loops and 30 for executors), a token budget that returns partial results when exceeded, and a wall-clock timeout. An uncapped loop fails silently and expensively.
Log every step so runs can be replayed
Persist each prompt, response, and tool call with agent_id, turn, input, output, tool_calls, and cost, enough to reconstruct the next turn from the previous one. Replayed runs become a golden set for evals; see evaluation.