Agents and orchestration patterns
The catalog of orchestration patterns for Claude-based agents — supervisor-worker, swarm, ReAct, Plan-and-Solve, handoff protocols — plus Anthropic’s own published guidance on building production agents. The headline insight from Anthropic’s engineering posts: most production agents should be simple LLM-plus-tools loops, not multi-agent systems. Multi-agent is an optimization for specific bottlenecks (context window, parallelism, expertise routing), not a default architecture. This note covers the building blocks (single-agent loop, subagents, agent teams, background agents), the named patterns (supervisor-worker, ReAct, Plan-and-Solve, handoff, swarm), the context-engineering rules (memory tool, just-in-time retrieval, compaction), and the production lessons.
See also
- claude-code-subagents-and-skills — in-process subagent primitive
- claude-agent-sdk — programmatic agent loop
- computer-use-and-code-execution — the memory tool that enables long-running agents
- tool-use-and-function-calling — the basic loop
- prompt-engineering-agent-systems — vendor-neutral background on agent design
1. Anthropic’s published canon
Three engineering posts define Anthropic’s thinking on agents (cite them when you need the source):
-
Building effective agents (Dec 2024) — the foundational piece. Distinguishes “workflows” (predefined steps with LLM in loops) from “agents” (LLM-directed). Argues most use cases want workflows.
-
Effective context engineering for AI agents (2025) — the memory + just-in-time retrieval playbook. Introduces the pattern behind the memory tool.
-
Effective harnesses for long-running agents (2025) — for multi-day software-engineering agents. Initializer + recovery pattern.
These are opinionated — Anthropic explicitly rejects some patterns popular in other camps (heavy multi-agent, blackboard architectures, MOA).
2. The single-agent loop (the baseline)
The unit of all agent architectures. Pseudo-code:
messages = [{"role": "user", "content": initial_prompt}]
while True:
response = client.messages.create(model=..., tools=tools, messages=messages)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason == "end_turn":
break
if response.stop_reason == "tool_use":
tool_uses = [b for b in response.content if b.type == "tool_use"]
tool_results = [dispatch(tu) for tu in tool_uses]
messages.append({"role": "user", "content": tool_results})
if response.stop_reason == "max_tokens":
# Continue or abort
breakBound the loop:
- Max turns (
max_turnsin SDK,--max-turnsin CLI) - Max dollars (
--max-budget-usd) - Repeated-tool detection (same tool + same input N times → break)
- Token budget across turns
This loop is the foundation of Claude Code, the Agent SDK, and every Anthropic example agent.
3. Building blocks Claude provides
| Primitive | Where | What for |
|---|---|---|
| Subagents | Same process, separate context window | Save context window; specialize roles; restrict tools |
| Background agents | Separate subprocess (Claude Code daemon) | Long-running tasks, parallel sessions |
| Agent teams | Multiple subagents communicating | Coordinated multi-role work |
Task / Agent tool | Built-in tool | Spawn subagents |
AskUserQuestion tool | Built-in tool | Multiple-choice user input mid-task |
| Memory tool | Tool primitive | Persistent state across context resets |
| Hooks | Settings file or SDK callbacks | Deterministic policy enforcement |
| Compaction | Built-in | Server-side context summarization |
| Skills | Markdown + frontmatter | Reusable task playbooks |
4. Named orchestration patterns
4.1 Workflow vs agent (Anthropic’s framing)
| Type | Definition | Example |
|---|---|---|
| Workflow | LLM and tools orchestrated through predefined code paths | Chain: classify → extract → format → send |
| Agent | LLM dynamically directs its own processes and tool usage | ”Find and fix the bug in auth.py” |
Workflows are more predictable, easier to evaluate, cheaper. Agents are more flexible but harder to test and bound.
Per Anthropic: prefer workflows. Use agents only when:
- The task can’t be decomposed in advance (unknown # of steps)
- The agent needs to reason about results to decide next step
- The work is open-ended (research, exploration)
4.2 Prompt chaining (workflow pattern)
Sequential LLM calls where each output feeds the next input. Optional gates check intermediate output before continuing.
Input → LLM 1 (extract) → gate (validate) → LLM 2 (transform) → LLM 3 (format) → Output
Use when: task naturally breaks into subtasks; subtasks are simpler than the whole.
4.3 Routing (workflow pattern)
Classify input → dispatch to specialized prompt.
Input → LLM 1 (classify intent) → ┬─ LLM A (handle refunds)
├─ LLM B (handle technical)
└─ LLM C (handle billing)
Use when: distinct categories with different best handlers; one-size-fits-all is too generic.
4.4 Parallelization (workflow pattern)
- Sectioning: split task into independent subtasks, run in parallel, aggregate. (“Read each file, summarize, then merge summaries.“)
- Voting: same task N times, take majority. (Adversarial filtering, content moderation.)
Use when: parallelizable work and aggregation is cheap.
4.5 Orchestrator-workers (workflow pattern)
Central LLM dynamically breaks down task, delegates subtasks to worker LLMs, synthesizes results. Different from routing — the breakdown is dynamic, not predefined.
This is what Claude Code does with the Agent tool. Main thread = orchestrator; subagents = workers.
4.6 Evaluator-optimizer (workflow pattern)
One LLM generates, another evaluates and provides feedback, loop until acceptance. Useful for high-stakes generation (legal text, code, designs) when you have clear evaluation criteria.
4.7 ReAct (Reason + Act) — agent pattern
The classic pattern: model emits Thought → Action → Observation in a loop.
Implemented in Claude via:
- Extended / adaptive thinking (
thinkingblocks) — handles “Thought” - Tool use — handles “Action”
- Tool results — handles “Observation”
Out of the box. Don’t reimplement the ReAct paper — Claude does it natively.
4.8 Plan-and-Solve — agent pattern
Force explicit planning before execution:
Step 1: Generate a numbered plan (don't execute yet)
Step 2: Execute the plan step by step
Step 3: Verify final result
Claude Code’s plan mode (/plan or --permission-mode plan) bakes this in — Claude can only read until you approve the plan, then it executes.
Most useful when:
- Stakes are high
- The task has multiple correct paths and you want to choose
- You want a chance to abort before mutation
4.9 Supervisor-Worker — multi-agent pattern
A supervisor agent (often Opus) coordinates worker agents (often Sonnet or Haiku) that execute subtasks.
In Claude Code: main thread is supervisor, subagents are workers. In SDK:
options = ClaudeAgentOptions(
model="claude-opus-4-7", # supervisor
agents={
"researcher": AgentDefinition(model="haiku", tools=["Read", "Grep"], ...),
"implementer": AgentDefinition(model="sonnet", tools=["Edit", "Write", "Bash"], ...),
"reviewer": AgentDefinition(model="opus", tools=["Read", "Grep"], ...),
},
allowed_tools=["Agent", "Read"],
)Use when: clear functional decomposition + workers benefit from constrained context.
4.10 Swarm / handoff — multi-agent pattern (OpenAI’s framing)
Agents pass control to each other based on conditions. Each agent has its own tools and system prompt; explicit handoff tools route to peers.
Less common in Claude land — Anthropic generally prefers supervisor-worker because handoff is harder to reason about. Implementable in Agent SDK via shared session and --agent switching.
4.11 Background agents (parallelism via separate sessions)
Per agent view docs: Claude Code can run up to 12 background agents in parallel via a daemon (claude daemon). Each has its own session, independent of yours. Coordinate via:
- Shared files
- Memory tool (with shared paths)
- A coordinator script that dispatches via
claude --bg "task" --agent worker
Use when: truly parallel work; want to keep main session interactive.
4.12 Agent teams (in-session communication)
Per agent teams docs: multiple subagents that can message each other during a session via the SendMessage tool. Different from Task tool (one-shot dispatch with summary return).
Use when: agents need to negotiate or share intermediate results.
5. Context engineering for long-running agents
Per Effective context engineering for AI agents:
5.1 Just-in-time retrieval, not upfront dumping
Instead of stuffing the context window with everything you might need:
- Store reference material in the memory tool (
/memoriesdirectory) - Agent reads only what’s needed for the current step
- Keeps active context focused
5.2 Memory tool patterns
Per the memory tool docs (see computer-use-and-code-execution §8):
Multi-session software-development pattern:
- Initializer session sets up:
- Progress log (
/memories/progress.md) - Feature checklist (
/memories/features.md) - Reference to startup/init script
- Progress log (
- Each subsequent session opens by reading these artifacts → recovers state in seconds.
- End-of-session update writes completion / what’s-next.
- Mark feature complete only after end-to-end verification.
Auto-injected system prompt when memory tool is enabled:
IMPORTANT: ALWAYS VIEW YOUR MEMORY DIRECTORY BEFORE DOING ANYTHING ELSE.
MEMORY PROTOCOL:
1. Use the `view` command of your `memory` tool to check for earlier progress.
2. ... (work on the task) ...
- As you make progress, record status / progress / thoughts etc in your memory.
ASSUME INTERRUPTION: Your context window might be reset at any moment.
5.3 Compaction
Server-side conversation summarization when approaching context limit. Triggered automatically. Memory + compaction together = long-running agents survive across context resets.
Per code.claude.com/docs/en/how-claude-code-works#when-context-fills-up:
- Skill content re-attached after compaction (first 5,000 tokens; 25,000 token combined budget for re-attached skills)
- Recent tool results preserved
- Older content summarized
5.4 Context editing
Client-side: explicitly clear specific tool results from context (e.g. large file contents that Claude no longer needs). See Context editing docs.
Memory + compaction + context editing form the long-running-agent stack.
6. Effective harnesses for long-running agents
Per Effective harnesses for long-running agents:
- Define done explicitly. The agent doesn’t get to decide what “complete” means; the harness does (test passes, build succeeds, user approves).
- Verify end-to-end. Code-passes-typecheck ≠ feature-works. Run the app.
- Recover from any state. Sessions can crash at any token. State must be reconstructable from disk (memory tool + git + your checklists).
- Bound iterations. Max turns per subtask, max retries per tool.
- Distinguish forward progress from churning. If
feature Nhas been “in progress” for 3 sessions, escalate to a human. - One feature at a time. Don’t let scope creep across sessions.
7. Production lessons
Distilled from Anthropic’s posts + Claude Code’s own codebase:
7.1 Simple > clever
Most agentic systems should be a single agent with good tools, not a swarm. Multi-agent complexity exists to solve specific problems (parallelism, context window, expertise routing); apply it only when those problems exist.
7.2 Evaluate constantly
You can’t have a serious agent without evals. Per Anthropic’s evals guidance:
- Define success criteria up-front
- Build a test set
- Run on every prompt change
- Track regressions per metric
7.3 Cost-aware routing
Run cheap models for cheap tasks. Common pattern: Haiku does extraction, Sonnet does reasoning, Opus does generation or critique. See claude-models-and-capabilities pricing table.
7.4 Determinism where possible
Hooks for hard rules (block rm -rf, auto-format on every edit). Skills for repeatable procedures. Subagents for constrained roles. Reserve LLM freedom for actually-judgement-required steps.
7.5 Human-in-the-loop for high-stakes actions
Per the computer-use safety floor: always require human confirmation for delete, payment, sign-out, ToS-accept, destructive shell commands. Use permissions.ask[] for the lighter version, prompt-injection classifiers for the heavier.
7.6 Observability
Use OpenTelemetry from Claude Code (per OTEL_* env vars in claude-code-cli) or instrument your Agent SDK code with traces/metrics/logs. Long-running agents fail in opaque ways without observability.
7.7 Sandbox aggressively
Per Claude Code sandbox: bash sandboxing via bubblewrap (Linux), filesystem allow/deny lists, network allow/deny lists. For agents that touch arbitrary user-provided URLs or content, sandbox is not optional.
8. Anti-patterns
- Multi-agent for solo work — coordination overhead exceeds benefit.
- Blackboard architectures — multiple agents read/write shared state. Race conditions; hard to reason about. Use one agent + memory tool.
- Stuffing everything in context — works until it doesn’t. Use just-in-time retrieval + memory tool.
- No bounding — unbounded loops on bad tools burn tokens fast. Always cap.
- No verification — generation without verification is hopeful, not effective.
- One giant prompt — break it into stages with explicit handoffs.
- Reimplementing ReAct from scratch — Claude does this natively; don’t add a parsing layer.
- MOA (Mixture of Agents) for everything — useful for specific tasks (debiased generation), not a default.
- Subagents as namespacing — if you’re just organizing prompts, use skills, not subagents.
9. Worked example: multi-day refactor agent
Combining all the above into a multi-day refactor of a large codebase:
# .claude/agents/refactor-coordinator.md
---
name: refactor-coordinator
description: Coordinates a multi-day refactor; maintains progress in memory
tools: Read, Glob, Grep, Bash, Agent, mcp__memory__view, mcp__memory__create, mcp__memory__str_replace
model: opus
memory: project
---
You coordinate a multi-day refactor. On every session:
1. View `/memories/refactor-plan.md` to see the plan.
2. View `/memories/progress.md` to see what's done.
3. Pick the next feature.
4. Dispatch the `refactor-implementer` subagent for the feature.
5. After it returns, dispatch the `refactor-reviewer` subagent.
6. If review passes, run the test suite via Bash.
7. If tests pass, update `/memories/progress.md`.
8. If anything fails, log to `/memories/blockers.md` and stop.# .claude/agents/refactor-implementer.md
---
name: refactor-implementer
description: Implements one feature of the refactor
tools: Read, Edit, Write, Bash, Glob, Grep
model: sonnet
permissionMode: acceptEdits
maxTurns: 30
---
You implement one feature of the refactor. ...# .claude/agents/refactor-reviewer.md
---
name: refactor-reviewer
description: Reviews the implementer's work
tools: Read, Grep, Bash(git diff *)
model: opus
disallowedTools: Write, Edit
maxTurns: 10
---
You review the implementer's changes. Focus on correctness, regressions, style. ...Run on a schedule:
# .claude/settings.json schedule via routine, or cron:
0 9 * * * claude --bg --agent refactor-coordinator "continue the refactor"The supervisor-worker pattern + memory tool + bounded subagent turns + cheap-model-for-implementer + expensive-model-for-reviewer = a robust multi-day agent.
10. Further reading
- Building effective agents — Anthropic’s foundational essay
- Effective context engineering for AI agents
- Effective harnesses for long-running agents
- How Claude Code works — the engine that drives Claude Code
- Agent teams
- Agent view (background agents)
- Subagents
- Context editing
- Compaction
- Develop tests / evals
- Anthropic safety best practices