Module 14 · Multi-agent systems · Lesson 3 of 5
Handoffs and shared state
What crosses an agent boundary: a typed handoff with goal, inputs, constraints and done-when, the user and permissions attached, results back as structured outputs, bulk in a shared store with one writer, and a versioned schema.
Why it matters
A boundary between two agents is a place where the task can be lost. The second agent did not see the user, did not read the forty documents, and does not know what the first agent already tried. Whatever crosses the boundary is all it has. Teams either send the whole transcript, so the second agent drowns and the bill doubles, or a one-line instruction, so it guesses. Interviewers probe the handoff because it is where multi-agent systems quietly go wrong.
The idea
What crosses the boundary
Treat the handoff as a function call, not a conversation. The caller sends a typed object: the goal (what to achieve, in one sentence), the inputs (the ids, documents or facts the callee needs, not the whole context), the constraints (budget, deadline, what not to do), and what done looks like (the shape of the result). The callee starts a fresh context containing its own system prompt and that object, nothing else. The object has a schema and is validated on the way in, so a missing field is a bug caught at the boundary rather than a wrong answer three hops later.
{
"handoff_version": 2,
"trace_id": "7f3a-21c",
"goal": "Find the three most-cited objections to the Q3 pricing change",
"inputs": { "doc_ids": ["d-118", "d-204"], "period": "2026-07 to 2026-09" },
"constraints": { "max_tokens": 40000, "deadline_ms": 60000, "external_search": false },
"done_when": { "result_schema": "ObjectionList", "max_items": 3 },
"principal": { "user_id": "u-9812", "scopes": ["docs:read"] },
"notes": "The author of d-204 already replied; do not count that reply as an objection."
}
Results come back structured
The callee returns an object of the agreed shape, not prose: the items, a confidence, the sources used, and a status that can say "could not complete" with a reason. The caller's code checks it before the caller's model reads it; prose cannot be validated and carries the callee's reasoning, which the caller pays to read.
Shared state versus message passing
With message passing, every fact an agent needs arrives in a handoff and agents share nothing else. Simple, explicit, and the handoffs grow with the task. With shared state, a blackboard or store that all agents read and write, agents post findings and read others' findings, and handoffs carry only pointers. It scales better and couples worse: an agent that reads a field another agent writes now depends on that agent's schema and timing. Combine them: the handoff carries the goal and pointers, the store carries the bulk (documents, drafts, tool outputs), and every key has one writer, which the Failure modes lesson insists on.
Keep the principal attached
The user's identity, intent and permissions travel with every hop. A sub-agent that runs with the system's own credentials rather than the user's is a privilege escalation waiting for a prompt injection; the Excessive agency lesson calls this the confused deputy. Put the user id and the scopes in the handoff, have each agent's tools check them, and never widen scopes at a boundary. The original request rides along verbatim, so the fourth agent checks its work against what the user asked, not three summaries of it.
Version the schema
Handoff schemas change as agents evolve, and the two sides deploy separately. Put a version in the object, accept the previous version for one release, and reject unknown versions loudly. Two agents that disagree about the handoff format fail in the most confusing way available: both run, both report success, and the result is wrong.
The lost-context failure
The first agent learned that the customer's account is frozen, concluded that the refund path was blocked, and handed off "process the refund" anyway, without the fact. The second agent, which cannot see what the first learned, tries the refund. Typed handoffs prevent this structurally: the schema has fields for findings and constraints, and the output is validated against it. A free-text handoff relies on the model remembering to mention the frozen account, and under context pressure it will not.
The cost of each hop
A handoff costs tokens twice: the caller composes it and the callee reads it, on top of the callee's own system prompt. A 1,500-token handoff plus a 2,000-token system prompt is 3,500 tokens of overhead per hop before any work happens. Over a ten-hop run that is 35,000 tokens, which is the argument for few hops, lean handoffs and the bulk in the store.
| Full transcript | Typed handoff | Shared blackboard | |
|---|---|---|---|
| Context cost | Highest; every hop re-reads the whole history | Low; a few hundred to a few thousand tokens | Lowest per hop; agents read only what they need |
| Clarity | The callee must infer what is wanted | Explicit goal, inputs, constraints, done-when | Depends on the store schema and discipline |
| Coupling | Loose on paper; the callee depends on everything | Coupled to one schema, versioned | Coupled through shared keys and timing |
| Debuggability | Poor; nobody knows what the callee attended to | Good; the object is logged and validated | Mixed; reads are hard to attribute without a single writer |