Aller au contenu principal

Chapter 2: Sub-agents and delegation

A sub-agent is an agent started by another agent to do one bounded piece of work, with its own context window, its own tools and permissions, and a contract for what it must hand back. The agent that started it - the orchestrator - does not see the sub-agent's working; it sees the result. That one property, isolation, is what solves the three scaling problems from Chapter 1.

Why delegate​

Problem (Chapter 1)How a sub-agent solves it
Context pollutionThe sub-agent reads twelve files and runs six test cycles in its context. The orchestrator receives a two-paragraph summary. The orchestrator's context stays small and stays about the task.
Serial executionThree sub-agents for three independent endpoints run at the same time. Wall clock drops from the sum to the maximum.
One permission setThe sub-agent that reads the untrusted issue has no shell. The sub-agent that runs tests has a shell but never sees the issue text. Prompt injection has nowhere to go.

There is a fourth reason: specialisation. A sub-agent can be given a system prompt, a rules file and a tool set tuned for one job - reviewing for security, writing tests, migrating a database - and it will do that job better than a general agent that is also doing everything else.

The orchestrator / worker pattern​

The orchestrator owns the plan. It breaks the task into pieces, writes a contract for each, starts workers, collects results, resolves conflicts, and reports to the human. It does not write code. The moment the orchestrator starts implementing, its context fills up and it becomes the single agent from Chapter 1 again.

Workers each take one contract, do the work in isolation, and return a result in the shape the contract asked for. They do not talk to each other. If two workers need to agree on something - an interface, a type - the orchestrator decides it first and puts it in both contracts.

Reviewers are workers whose job is to read, not write. A reviewer gets the diff and the spec, and returns findings. It never fixes what it finds; that goes back through the orchestrator to the worker or to the human.

The task contract​

A sub-agent with a vague task is a single agent with a vague task, only now you cannot see it drifting. The contract is the spec from Module 2, scoped to one worker:

## Task: implement GET /api/orders/{id}/invoice

### Context you have
- `docs/specs/invoice-endpoint.md` (the spec)
- `app/api/orders.py` (the router to add to)
- `billing/render.py` (reuse `InvoiceRenderer`; do not write a PDF generator)
- `tests/api/test_invoice.py` (three failing tests; do not modify)

### Done when
- The three tests pass.
- `git diff --stat` touches only `app/api/orders.py` and new files under `app/api/`.
- No new dependencies.

### Return
- The diff (as a patch or branch name).
- One paragraph: what you did, anything in the spec that was ambiguous.
- Test output.

### You may
- Read any file under `app/`, `billing/`, `tests/`.
- Run `uv run pytest tests/api/test_invoice.py`.

### You may not
- Modify tests, migrations, or anything outside `app/api/`.
- Install packages. Commit. Push.

Six sections: context, done-when, return shape, allowed actions, forbidden actions. The "return" section is the one teams forget, and it is what lets the orchestrator work without reading the transcript.

How the tools do it​

Claude Code​

Sub-agents are first-class. A sub-agent is defined by a Markdown file with frontmatter in .claude/agents/ (project) or ~/.claude/agents/ (personal): a name, a description of when to use it, the tools it is allowed, optionally a model, and a system prompt in the body. The main agent delegates when a task matches the description, or when you ask it to. Each sub-agent has its own context window; the result comes back as a message. Several can run in parallel.

---
name: security-reviewer
description: Reviews a diff for secrets, injection, auth bypass and unsafe dependencies. Read-only.
tools: Read, Grep, Glob
---
You are a security reviewer. You receive a diff and the spec. Report findings as a list with
file, line, severity and a one-line fix. Do not edit files. If you find nothing, say so.

Three lines of frontmatter and the tools line is the permission boundary: this agent cannot run a command or edit a file, whatever it reads.

Cursor​

Two mechanisms. Subagents inside a session: the agent can spawn specialised helpers (exploration, planning, review) that return results into the main conversation; rules in .cursor/rules/ scope by file pattern, so a worker touching frontend/** gets the frontend rules. Background agents run in isolated cloud environments on their own branch, in parallel, and come back as pull requests - the orchestrator here is you, assigning tasks and reviewing PRs.

GitHub Copilot​

The coding agent is a cloud worker: assign a GitHub issue to Copilot and it works in an Actions-backed environment, on a branch, and opens a PR. Several issues can be assigned at once. Path-scoped instructions in .github/instructions/ specialise its behaviour by area of the repository. Copilot code review acts as the reviewer on the resulting PR. Orchestration is the issue tracker plus you.

The common shape​

Claude CodeCursorGitHub Copilot
Worker definition.claude/agents/*.mdRules + background agent taskIssue + .github/instructions/
IsolationSeparate context per sub-agentSeparate context; separate environment for background agentsSeparate environment per issue
ParallelismYes, in-sessionYes, background agentsYes, multiple issues
Permission boundarytools: frontmatterAgent settings / environmentRepository and Actions permissions
Result shapeMessage to parent agentMessage, or PRPR
OrchestratorThe main agent, or youYouYou (plus the issue tracker)

The products differ in how much orchestration they automate. The engineering is the same: contract in, result out, isolation in between.

Handoff and merge​

Two moments matter in the pattern, and both are the orchestrator's job.

Handoff. The contract goes to the worker with exactly the context it needs - not more. Pasting the whole conversation so far into the worker defeats the isolation. If the worker needs a decision (which interface, which name), the orchestrator makes it before the handoff.

Merge. Results come back; some will conflict. Two workers both added a helper with the same name. One worker's change broke another's test. The orchestrator's merge step is: apply results in dependency order, run the full suite, and for each conflict either resolve it mechanically (rename) or send a new, narrow contract to one worker ("rename your helper to X; nothing else"). Never ask a worker to "fix the merge" - that is a vague task, and vague tasks drift.

When not to delegate​

Delegation has a cost: writing contracts, waiting for handoffs, merging. For a task one agent can finish in ten turns with a clean context, delegation is slower. Rules of thumb:

  • One file, one pattern, under ten turns: single agent.
  • Independent pieces that can run at once: delegate for parallelism.
  • Reading untrusted input, or needing different permissions for different steps: delegate for isolation, even if it is slower.
  • A review step: always a separate agent. A worker reviewing its own diff finds nothing.

Summary​

  • A sub-agent is an agent with its own context, tools and permissions, started by an orchestrator with a contract, returning a result in a defined shape.
  • Isolation is the point: it solves context pollution, enables parallelism and separates permissions.
  • The orchestrator plans, contracts, collects and merges - it does not write code.
  • Claude Code defines workers in .claude/agents/; Cursor uses in-session subagents and background agents; Copilot uses issues and the coding agent. Same shape, different automation.
  • Reviewers are always separate agents.