AGENTS FROM FIRST PRINCIPLES · PART 14 OF 17

2026-07-10

The Supervisor and the Handoff

One agent with one context cannot parallelize breadth-first work and is overkill for a specialist. Orchestrator-worker fan-out, handoff-as-a-tool, honest economics.

What you’ll learn

Since Part 1 there has been exactly one agent with one context window, working the problem alone, and that single shape carried the entire series, including the twenty parts of RAG before it. It is a real limit, and it shows up in two distinct ways. The first is breadth: a task with genuinely independent parts, “summarize the refund policy and the warranty and the shipping options,” cannot be done in parallel inside one context. A single agent has to do it depth-first, one item after the next, and its one transcript fills with the debris of each subtask as it goes. The second is specialization: a task that should really be handled by a dedicated specialist is awkward to cram into a generalist’s loop, when the cleaner move is to hand the whole thing off to the right agent. So this part introduces the two main multi-agent shapes. The first is the orchestrator-worker pattern (a supervisor): a lead agent decomposes a task into subtasks, spawns N workers, each with its own isolated context and a typed brief, and then synthesizes their results. The worker is just the Part 1 agent reused as a black box; we do not rebuild the loop. The second is the handoff as a tool call: transferring control, and the live trace, to a specialist, with its two classic failure modes. And running through both, just as importantly, is the honest economics of when NOT to reach for multi-agent, because these systems are more expensive, harder to debug, and frequently overkill. We put single, supervisor, and a proposer-critic debate side by side with the numbers, and we are careful never to claim a speedup we did not measure.

Prerequisites

You need basic Python: a function, a list, a dictionary, a string check. That is all. Three earlier parts help but are not required. Part 1 is the worker: the multi-agent shapes here reuse that agent as a black box rather than re-deriving the ReAct loop. Part 8 is the circuit breaker: a runaway supervisor (workers spawning workers) is stopped by it, reused unchanged, not rebuilt. Part 12 is the tool layer: a worker’s tools are the MCP-discovered actions from that part. But the essay is self-contained: where it leans on an earlier idea it restates it in a sentence and references it rather than re-deriving it. The companion code, supervisor_and_handoffs.py, runs offline with no API key, no network, and no dependencies, so you can read every line and reproduce every line of output in this essay yourself. The default lead, workers, and critic are deterministic (offline); a real hosted LLM in each of those roles is one generate() flag away.

What is new since the single agent

I want to be precise about what is new, because this is genuinely new ground and not a refinement of the single-agent world. Every part so far, all the way back through RAG, used one controller, one context window: RAG was single-agent end to end, retrieving and reasoning in a single growing transcript, and the agents core track never questioned that either. What this part adds is coordination between agents, and almost all of it is net-new. Orchestration: a lead that decomposes a goal and dispatches subtasks. Parallel workers with separate contexts: each worker sees only its own small brief, not one shared, ever-growing transcript. Typed briefs: the structured contract a supervisor hands a worker. The blackboard: a shared, append-only place workers post results to. Agent-control handoff: transferring the loop itself, plus the live trace, to a different agent. And the single-vs-multi economics: the honest accounting of when more agents help and when they just multiply the ways things go wrong. Two pieces are deliberately reused, not rebuilt. The worker is the Part 1 agent as a black box, so the ReAct loop is never re-derived. The safety stop on a runaway supervisor is Part 8’s circuit breaker, referenced not duplicated. And one distinction matters: the handoff here is categorically different from a router. RAG’s Part 15 complexity router and Part 18 text-vs-SQL router picked a path inside one agent; a handoff transfers control to another agent and carries the trace with it. Reference, do not conflate.

The orchestrator and its workers

Start with the supervisor. The lead is handed a breadth-first goal, Prepare a customer briefing on refunds, the earbuds warranty, and shipping., and its job is not to answer it but to decompose it. It breaks the goal into three subtasks and writes a typed brief for each: an objective (“summarize the refund policy”), an output format (“one sentence”), tool guidance (which tool to reach for), and boundaries (what is in and out of scope, “policy only”). Each brief goes to a separate worker, and the crucial property is context isolation: a worker’s context is just its brief. It never sees the goal, the other briefs, or the other workers’ output; it sees its one small objective, runs its one tool, and posts its one result to a shared append-only blackboard. Here are the three workers running in their own isolated contexts, quoted from the artifact’s real output:

  supervisor decomposes: 'Prepare a customer briefing on refunds, the earbuds warranty, and shipping.'
    [w1] brief: summarize the refund policy (own context, 14 tokens) -> Refunds within 30 days; a 10% restocking fee applies after the window.
    [w2] brief: state the earbuds warranty (own context, 14 tokens) -> The Globex earbuds carry a 2-year limited warranty.
    [w3] brief: list the shipping options (own context, 14 tokens) -> Standard shipping is 3 to 5 business days; express is next business day.

Read each worker. w1 got the brief “summarize the refund policy,” ran in a context of just 14 tokens, and returned Refunds within 30 days; a 10% restocking fee applies after the window. w2 got “state the earbuds warranty,” ran in its own 14-token context, and returned The Globex earbuds carry a 2-year limited warranty. w3 got “list the shipping options” and returned Standard shipping is 3 to 5 business days; express is next business day. The number to notice is 14 tokens, three times, not one context that grew to 42 and beyond. Each worker carries only its own brief, so none of them pays for the others’ context. Once all three have posted, the supervisor does the one job a worker cannot: it reads the blackboard and synthesizes the parts into the whole the goal asked for:

  supervisor synthesizes the blackboard into the briefing:
    Refunds within 30 days; a 10% restocking fee applies after the window. The Globex earbuds carry a 2-year limited warranty. Standard shipping is 3 to 5 business days; express is next business day.
    (3 workers, each its own context; with real concurrency they run in ONE round.)

The synthesized briefing is the three blackboard entries joined into one coherent answer, exactly the briefing the goal called for, assembled from three isolated pieces of work rather than computed inside one swelling transcript. The last line is the honest claim about parallelism, and we hold to it precisely: there are three workers, each its own context, and with real concurrency they run in one round. Offline they ran sequentially; what isolation buys is small per-worker contexts now, and a single round of latency when you do run them concurrently.

A diagram of the supervisor pattern. At the top, a lead agent box receives the goal prepare a customer briefing on refunds, the earbuds warranty, and shipping, with a decompose arrow fanning out into three typed-brief cards. Each card lists four fields, objective, output format one sentence, tool guidance, and boundaries. The first card, w1, objective summarize the refund policy, boundary policy only. The second card, w2, objective state the earbuds warranty, boundary products only. The third card, w3, objective list the shipping options, boundary shipping only. Below each card sits a separate worker box labelled own context 14 tokens, each marked as a Part 1 agent reused as a black box, isolated from the others. Worker w1 returns refunds within 30 days, a 10 percent restocking fee applies after the window; worker w2 returns the Globex earbuds carry a 2-year limited warranty; worker w3 returns standard shipping is 3 to 5 business days, express is next business day. Three arrows carry these results down into a shared append-only blackboard strip holding the three posted entries. From the blackboard, a synthesize arrow runs up into the supervisor, which emits one joined briefing combining all three. A caption strip reads: typed briefs plus isolated 14-token contexts plus a blackboard plus synthesis; with real concurrency the three workers run in one round.
Fig 1 The orchestrator-worker (supervisor) pattern on the customer-briefing goal. A lead agent receives the breadth-first goal prepare a customer briefing on refunds, the earbuds warranty, and shipping, and decomposes it into three typed briefs, each carrying an objective, an output format of one sentence, tool guidance, and boundaries. Each brief is dispatched to a separate worker that runs in its own isolated context of just 14 tokens: w1 summarizes the refund policy and returns refunds within 30 days then a 10 percent restocking fee after the window, w2 states the earbuds warranty and returns the Globex earbuds carry a 2-year limited warranty, w3 lists the shipping options and returns standard shipping is 3 to 5 business days then express is next business day. Each worker posts its single result to a shared append-only blackboard, and the supervisor then synthesizes the three blackboard entries into one coherent briefing. The figure shows that the worker is the Part 1 agent reused as a black box, that each worker context is isolated and small rather than one growing transcript, and that with real concurrency the three independent workers run in a single round.

Handoff as a tool call

Fan-out is the right move for breadth. For specialization, the right move is the second shape: not to spawn workers but to transfer control to a specialist, carrying the live trace along. handoff(to=...) is a tool like any other, except what it transfers is the loop itself plus the conversation so far. A clean handoff needs two things to be right: the full trace must travel (so the specialist has the facts the first agent gathered), and the role must be clear (so the specialist knows it now owns the task). When both hold, the handoff just works, quoted from the artifact’s real output:

  clean handoff (full trace, clear role):
    handoff(to='billing-specialist'): carrying 3/3 trace entries, role=clear
    -> [done] billing-specialist refunded order ORD-3300 using the carried trace.

The lead had already done the legwork: it identified order ORD-3300 for refund, looked up the policy, and confirmed the user wanted it, three trace entries. The handoff carries 3/3 trace entries, role=clear, so the billing-specialist inherits every fact, knows it owns the refund, and completes it: [done] billing-specialist refunded order ORD-3300 using the carried trace. Now the two classic failure modes, which are exactly the two preconditions broken. The first is truncation: the trace is cut, and the key fact is gone with it.

  failure mode TRUNCATION (trace cut to the last entry; the order id was earlier):
    handoff(to='billing-specialist'): carrying 1/3 trace entries, role=clear
    -> [failed] billing-specialist cannot act: the order id was truncated out of the carried trace.

Here only the last entry survived the handoff, 1/3 trace entries, and the order id was established earlier, in an entry that got cut. The role was clear, the specialist was ready, but it cannot act: the order id was truncated out of the carried trace. The specialist is not wrong; it is simply missing the one fact it needed, because the trace that should have carried it was clipped. The second failure mode is role confusion: the trace is complete, but nobody said who owns the task.

  failure mode ROLE CONFUSION (brief never said who owns it):
    handoff(to='billing-specialist'): carrying 3/3 trace entries, role=UNCLEAR
    -> [stalled] billing-specialist and the lead both wait: the brief never said who owns the task.

This time the full 3/3 trace entries arrived, so the facts are all there, but role=UNCLEAR. The result is a deadlock of politeness: [stalled] billing-specialist and the lead both wait: the brief never said who owns the task. Each agent assumes the other has it, so neither acts. Note how these are different from a router’s failures: a router picks a wrong branch but one agent keeps going; a botched handoff leaves the work stranded between two agents, because control itself, and the trace it rides on, did not cleanly transfer.

A diagram split into two coordination styles. On the left, headed blackboard, three worker boxes post their results down into a shared append-only board strip and a lead box reads up from it to synthesize, labelled coordination through shared data, no control transfer. On the right, headed handoff as a tool call, a lead agent hands control and a trace to a billing-specialist across a transfer arrow labelled handoff. Three stacked rows show the outcomes. The top row, clean handoff, shows carrying 3 of 3 trace entries, role clear, and a green result, done, billing-specialist refunded order ORD-3300 using the carried trace. The middle row, truncation, shows the trace clipped to 1 of 3 entries with the earlier order id entry crossed out and falling away, role clear, and a red result, failed, billing-specialist cannot act, the order id was truncated out of the carried trace. The bottom row, role confusion, shows the full 3 of 3 trace carried but a role tag reading UNCLEAR, with both the specialist and the lead drawn waiting on each other, and an amber result, stalled, both wait, the brief never said who owns the task. A caption strip reads: a clean handoff needs the full trace plus a clear owner; lose either and the work strands between two agents.
Fig 2 Handoff as a tool call, contrasted with the blackboard, and its two failure modes. On one side, the blackboard pattern from the supervisor: workers post results to a shared append-only board and a lead synthesizes, coordination through shared data with no transfer of control. On the other side, the handoff pattern: control and the live trace are transferred to a specialist. The clean handoff carries 3 of 3 trace entries with a clear role, and the billing-specialist completes the work, done, refunded order ORD-3300 using the carried trace. Then the two failure modes. Truncation, the trace is cut to 1 of 3 entries and the order id was in an earlier entry that got dropped, so the role is clear but the specialist failed, it cannot act because the order id was truncated out of the carried trace. Role confusion, the full 3 of 3 trace arrived but the role is unclear, so the work stalled, the billing-specialist and the lead both wait because the brief never said who owns the task. The figure shows that a clean handoff needs both the full trace and a clear owner, and that losing either one strands the work between two agents rather than merely picking a wrong branch.

The economics: single vs supervisor vs debate

Now the part that decides whether you should reach for any of this. We run the same goal three ways, single agent, supervisor, and a proposer-critic debate, and report the only honest currencies offline: LLM-call count, total context tokens, and quality out of three. Here is the table, quoted from the artifact’s real output:

  strategy        LLM calls   tokens  quality
  -----------------------------------------
  single                  4      300      3/3
  supervisor              5      220      3/3
  debate                  7      320      2/3

Read it row by row. The single agent uses the fewest calls, four, but the most tokens for that work, 300, because it has one growing context: every step re-sends everything before it, so the transcript climbs the whole way through. The supervisor uses more calls, five (decompose, three workers, synthesize), and yet fewer tokens, 220, because each worker context is isolated and small and does not grow; you pay for an extra call or two and you save on the context every one of them carries. Both reach 3/3 quality. The debate is the cautionary tale: seven calls, the most tokens at 320, and it actually scores worse, 2/3. More machinery, more cost, less quality. And the reason is in the round-by-round breakdown, which is the uncomfortable finding of the whole part, quoted from the artifact’s real output:

  Debate quality by round (more rounds is NOT more quality):
    proposer   quality 2/3
    round 1    quality 3/3
    round 2    quality 3/3
    round 3    quality 2/3  <- regressed

The proposer opens at 2/3. Round 1 of critique-and-revise lifts it to 3/3, and round 2 holds at 3/3. Then round 3 regresses to 2/3: the extra round did not refine the answer, it damaged it. Quality is not monotonic in rounds; more debate is not more quality, and a system that keeps debating “to be safe” can talk itself out of a correct answer. The flagship figure below puts all three strategies side by side and lets you step through the debate rounds to watch the regression happen.

Open figure ↗

Fig 3 The economics of single versus supervisor versus debate on one customer-briefing goal, reported as LLM-call count, total context tokens, and quality out of three, with the debate broken out by round. The single agent uses the fewest calls, four, but 300 tokens because it carries one growing context that re-sends everything every step, and reaches 3 of 3 quality. The supervisor uses more calls, five, decompose plus three workers plus synthesize, but only 220 tokens because each worker context is isolated and small and does not grow, and also reaches 3 of 3, the cheaper option on tokens despite the extra calls. The debate uses the most of everything, seven calls and 320 tokens, and scores worse at 2 of 3. The debate-by-round panel shows why quality is not monotonic: the proposer starts at 2 of 3, round 1 lifts it to 3 of 3, round 2 holds at 3 of 3, and round 3 regresses back to 2 of 3. The figure is explicit that the offline default runs workers sequentially, so it reports call count and token isolation rather than a wall-clock speedup, and that cost-per-success follows tokens, so breadth is worth paying for only when the task is genuinely broad.

When NOT to

The whole table points one way: multi-agent is a tool, not a default. For a small, sequential task, a single agent is the right and cheaper tool, fewest calls and a context that, while it grows, never has to be paid for three or four times over. Reach for the supervisor only when the work is genuinely broad, several independent subtasks that can each run in their own clean context and be synthesized at the end, because that is the one case where isolation pays for the extra calls and where real concurrency collapses the latency into a single round. Reach for debate almost never on the strength of these numbers: it was the most expensive strategy and it regressed. The governing rule is simple and it follows the rightmost-but-one column: cost-per-success follows tokens. Pay for breadth only when the task is broad; otherwise you are spending more to get the same answer, or, in the debate’s case, a worse one.

What we are and are not claiming

This is the honesty section, and it is the feasibility crux of the whole part. The offline default runs the workers sequentially. We never print a fabricated wall-clock speedup, and you will not find one anywhere in the run; it would be a lie about the deterministic path. What multi-agent actually buys, and all that we claim, is reported in two honest currencies. The first is LLM-call count, the table’s calls column. The second is token isolation: each worker sees only its own small brief, 14 tokens, not one ever-growing shared transcript, which is why the supervisor’s 220 tokens beat the single agent’s 300 even with an extra call. The run states this up front, quoted from the artifact’s real output:

Parallelism is SEQUENTIAL in this offline default: we report LLM-call count and
TOKEN ISOLATION (each worker sees only its brief), never a fabricated wall-clock.

The latency story is a consequence, not a measurement: because the three workers are independent and each has its own context, with real concurrency they run in one round, depth 1, which is exactly the parallel-fan-out idea from Part 3. That is a claim about the shape of the work (independent, so parallelizable), not a stopwatch reading we took offline. Two reuses close the loop and are referenced rather than rebuilt. A runaway supervisor, workers spawning workers spawning workers, is stopped by Part 8’s circuit breaker, unchanged. And these distributed runs, a lead with its fan-out of workers, render as the span tree of Part 11, a forward-looking continuation of the same observability we already built.

💡 From experience. The most expensive lesson I learned about multi-agent systems is that I built one before I needed one. We had a perfectly good single agent answering support questions, and I was sure that splitting it into a supervisor with a fleet of specialist workers would make it faster and better. It made it neither. For the tasks we actually had, mostly one lookup and a short answer, the supervisor added a decompose call and a synthesize call on top of work that fit in one context anyway, so every request got slower and pricier for no quality gain, exactly the single-versus-supervisor row in this part but lived through in a billing dashboard. The supervisor only started earning its keep months later, when a new feature genuinely needed to gather five independent things at once; then the isolated contexts and the one-round fan-out paid off precisely as advertised. The other scar is from a handoff. We transferred a refund from the triage agent to a billing agent and trimmed the carried trace to “save context,” and the trim dropped the entry that held the order id. The billing agent did everything right and still failed, because the one fact it needed had been truncated out from under it, the [failed] ... the order id was truncated out of the carried trace. line in this part, almost word for word. Now I treat the trace a handoff carries as a contract: the full trace travels, and the brief says in one sentence who owns the task, or I do not ship the handoff.

Key takeaways

  • Since Part 1 there has been one agent with one context window, and that breaks in two ways: it cannot parallelize breadth-first work (independent subtasks must go depth-first in one swelling context) and it is overkill when the right move is to hand off to a specialist. The fix is more than one agent, and the fix is also a trap.
  • The orchestrator-worker (supervisor) pattern: a lead decomposes the goal into typed briefs (objective, output format, tool guidance, boundaries), spawns N workers each in its own isolated context (here 14 tokens apiece), the workers post to a shared append-only blackboard, and the supervisor synthesizes. The worker is the Part 1 agent reused as a black box; the loop is not rebuilt.
  • The handoff as a tool call transfers control and the live trace to a specialist. The clean case completed: [done] billing-specialist refunded order ORD-3300 using the carried trace. Its two failure modes are truncation (1/3 trace, [failed] ... the order id was truncated out of the carried trace.) and role confusion (3/3 trace but role=UNCLEAR, [stalled] ... the brief never said who owns the task.).
  • A handoff is categorically different from a router: a router picks a path inside one agent (RAG’s Part 15 / Part 18 routers), while a handoff transfers control to another agent and carries the trace. A botched handoff strands the work between two agents rather than merely choosing a wrong branch.
  • The economics: single 4 calls / 300 tokens / 3/3, supervisor 5 / 220 / 3/3, debate 7 / 320 / 2/3. Single has the fewest calls but one growing context; the supervisor has more calls but isolated small contexts (cheaper on tokens and parallelizable); debate is the dearest and non-monotonic, regressing from 3/3 at round 2 to 2/3 at round 3. Cost-per-success follows tokens: pay for breadth only when the task is broad.
  • The honesty: the offline default runs workers sequentially, so we report call count and token isolation, never a wall-clock speedup. With real concurrency the independent workers run in one round (Part 3 depth). A runaway supervisor is stopped by Part 8’s circuit breaker (reused), and these runs render as the Part 11 span tree.

Glossary

  • Orchestrator-worker / supervisor: a multi-agent shape where a lead agent decomposes a task into subtasks, dispatches each to a worker, and synthesizes the results. The lead does the breaking-up and the putting-together; the workers do the parts. The worker is the Part 1 agent reused as a black box.
  • Typed brief: the structured contract a supervisor hands a worker, with an objective, an output format, tool guidance, and boundaries (what is in and out of scope). It is what lets a worker run usefully on its own with no knowledge of the wider goal.
  • Worker context isolation: the property that a worker’s context is just its brief (here 14 tokens), never the goal, the other briefs, or the other workers’ output. Isolation is why the supervisor’s total tokens (220) can beat the single agent’s (300) even with more LLM calls.
  • Blackboard: a shared, append-only place where workers post their results and from which the supervisor reads to synthesize. Coordination through shared data, with no transfer of control, the opposite end of the spectrum from a handoff.
  • Handoff (as a tool call): a tool that transfers control of the loop, plus the live trace, to a specialist agent. A clean handoff needs both the full trace and a clear owner; it is distinct from a router, which picks a path inside one agent rather than passing control to another.
  • Truncation (failure mode): the trace is cut on the way through the handoff, so the specialist is missing a key fact. Here 1/3 entries survived and the order id was in a dropped earlier entry, so the specialist [failed] even though its role was clear.
  • Role confusion (failure mode): the full trace arrives but the brief never says who owns the task, so both agents wait on each other. Here 3/3 trace but role=UNCLEAR produced a [stalled] deadlock of politeness, each assuming the other has it.
  • Proposer-critic debate: a multi-agent shape where a proposer drafts an answer and a critic revises it over several rounds. In this part it was the most expensive strategy (7 calls, 320 tokens) and non-monotonic: quality rose to 3/3 by round 2 then regressed to 2/3 at round 3. More rounds is not more quality.
  • Single-vs-multi economics: the accounting that decides whether to use more than one agent, measured in LLM calls, total context tokens, and quality. Cost-per-success follows tokens, so a single agent is right for a small sequential task and the supervisor is right only when the work is genuinely broad.
  • Reporting parallelism honestly: because the offline default runs workers sequentially, the value of multi-agent is reported as LLM-call count and token isolation, never a fabricated wall-clock speedup. The one-round latency is a consequence of the work being independent (Part 3 depth), claimed about the shape, not measured offline.

The rule from this part: treat multi-agent as a tool, not a default. When the work is genuinely broad, use the orchestrator-worker shape, a lead that decomposes the goal into typed briefs, spawns workers in isolated contexts, coordinates them through a blackboard, and synthesizes the result, reusing the Part 1 agent as the worker and Part 8’s breaker as the stop on a runaway. When the right move is a specialist, hand off as a tool call, but carry the full trace and name a clear owner, or you get truncation and role-confusion stalls. And keep the economics in front of you: a single agent is the cheaper, right tool for a small sequential task; the supervisor pays for itself only on breadth; debate is dear and not monotonic. But notice the boundary every shape in this part shares: handoffs and workers all live inside one process. The supervisor can spawn a worker because the worker is its own code; it can hand off to a billing-specialist because that specialist is reachable in the same runtime. The moment the billing agent is owned by another team, behind another service, that boundary breaks. Part 15, Agent to Agent, takes delegation across that line, an A2A protocol for one agent to discover, call, and hand off to an agent it does not own and cannot import, the same step from a private dictionary to a public protocol that MCP made for tools, now made for agents themselves.

AgentsMulti-AgentOrchestrationHandoffCostAI