Choose the Right Dispatch: Spawn, Fork, or Direct
Three ways to hand work to a sub-agent - fresh-context spawn, cache-sharing fork, or just doing it yourself - and the decision matrix for picking per task.
The route
4 steps to Done
- 01
Implement spawn: fresh context specialists
A spawn is a new employee: they know only what the dispatch tells them.
Preview prompt + verify gate ▾ Hide ▴
Build the spawn path. Maintain a registry of agent definitions (explorer, planner, verifier, general) each with: its own system prompt, tool list, default model (cheap+fast for read-only scouts, inherit for reasoning-heavy roles), and permission mode. On dispatch: look up the definition, build a FRESH context containing only the definition's system prompt plus the dispatch message - no parent history. Assemble the child's tool pool independently under its own permission mode, not a copy of the parent's. Because the child starts from zero, enforce dispatch-prompt discipline: task, relevant background, constraints, expected output format - a checklist the orchestrator prompt requires. Return the child's final report as a tool result the parent folds into its context.
- ✓ Registry with prompt/tools/model/permission per definition
- ✓ Child context contains zero parent history
- ✓ Dispatch prompts carry complete background
- 02
Implement fork: inherited context, shared cache
A fork is a clone at the current moment - cheap because the prefix is already paid for.
Preview prompt + verify gate ▾ Hide ▴
Build the fork path. The child's message list starts with the parent's conversation reproduced exactly, then: placeholder tool-results for any pending tool calls in the parent's last assistant message (identical placeholder text for every fork, so all siblings share the same byte prefix), followed by the child's directive as the only differing content. Use the parent's already-rendered system prompt bytes and the parent's exact tool array - do not re-filter or re-order, since any byte difference breaks prompt-cache sharing. Give fork children a strict behavior contract injected with the directive: you are a worker, not the main agent; do not spawn or fork further; do not converse or propose next steps; use tools directly; commit changes before reporting; report starts with a scope line and stays under a size cap.
- ✓ Placeholder results identical across sibling forks
- ✓ System prompt and tool array reused byte-for-byte
- ✓ Worker contract injected with every directive
- 03
Add guards and async lifecycle
Parallel dispatch needs recursion limits and a results path.
Preview prompt + verify gate ▾ Hide ▴
Add the safety rails. Recursion guard: mark forked children (a tag in their context and a flag in their execution options) and refuse fork/spawn requests from inside one - two independent checks, because a single guard eventually gets bypassed by a refactor. Run forks async by default: dispatch returns immediately with a task id; children execute in the background with independent abort handling (cancelling the parent's current step must not kill the workers); completed children deliver reports through a notification path that inserts results into the parent's next turn. Support parallel dispatch of multiple children in one turn - the cache sharing from step 2 is what makes N parallel forks affordable. Track running children so the parent can list, await, or cancel them.
- ✓ Recursion refused via two independent checks
- ✓ Children survive parent-step cancellation
- ✓ Parallel siblings share cache (verify via provider metrics)
- 04
Encode the decision matrix
The strategies only pay off if the orchestrator picks correctly.
Preview prompt + verify gate ▾ Hide ▴
Write the decision policy and put it in the orchestrator's prompt. SPAWN when the task needs a specialist definition (exploration with a cheap model, planning, verification), when context isolation is the point (an investigation whose noise should not pollute the parent), or when a different permission/tool profile is required. FORK when the task is splittable research or implementation where the parent's context is the necessary background and parallel siblings benefit from cache sharing. DIRECT when the task is a few tool calls the parent can do inline - dispatch overhead (context assembly, report round-trip) exceeds the work itself. Include the cost intuition: spawn pays full fresh-prompt cost, fork pays near-zero prefix cost, direct pays context-pollution cost. Audit a week of transcripts against the matrix and tune the prompt where the orchestrator chose badly.
- ✓ Spawn/fork/direct each have stated conditions and costs
- ✓ Prompt contains the policy, not just your docs
- ✓ Transcript audit confirms correct choices predominate
Research-backed
Sources behind this flow
Tier 1 · claude-code-internals
Deep Dive: Multi-Agent Dispatch - Spawn, Fork, Direct
Source-level analysis of the three ways Claude Code dispatches work: Spawn (a named sub-agent with a fresh context, its own tool pool, permission mode, and model), Fork (a synthetic agent that inherits the parent conversation byte-for-byte so parallel workers share the prompt cache), and Direct (the main agent just does the task itself). Covers sync-to-background promotion via a promise race, recursion guards on forking, git-worktree isolation, and a decision matrix for picking a strategy per task.
Tier 1 · claude-code-internals
Deep Dive: Agent Orchestration Patterns
Follows a dispatched agent through its full lifecycle - foreground vs background execution, auto-backgrounding of long tasks, sidechain transcripts for resume, layered tool filtering, and result handoff - then catalogs six reusable orchestration patterns: worker pool, pipeline, supervisor-worker, adversarial verification, fork-join, and resume chain. The adversarial verification agent, which must run real commands and issue a PASS/FAIL verdict while being forbidden from editing the project, gets special attention as a defense against LLM self-verification failure modes.