Memory-backed handoff
Transfer work between agents as a durable, structured memory entry — with a verdict loop — instead of a raw transcript dump.
A memory-backed handoff moves a task from one agent to another by writing a handoff entry into shared memory: who it's from, who it's for, what's being asked, and the decisions made so far. The receiver answers with a feedback entry carrying a verdict. Use this when one agent's output needs another agent's review, approval, or continuation — and when "paste the whole conversation into the next agent's prompt" would either blow the context budget or silently drop the one constraint that mattered.
How it works
handoff() writes a handoff entry into the run, addressed to a specific agent. The receiver responds with feedback(), which writes a feedback entry referencing the handoff. Both are ordinary memory: they survive the turn, appear in assembled context (the handoffs and feedback sections), and feed reflection later.
Ari shared run Rex
│ handoff(to=rex, ┌──────────────┐ │
│ requested_action=approve) →│ handoff entry│→ recall(...) ──┤
│ │ trace, trace │→ (full history) │
│ ← await/poll verdict │feedback entry│← feedback(block)│Two enums shape the exchange (both from the control-plane contract):
| Field | Values | Meaning |
|---|---|---|
requested_action | review, continue, approve, execute | What the sender is asking the receiver to do |
verdict | approve, request_changes, block, acknowledge | The receiver's answer, written by feedback() |
The design point that makes this better than a transcript dump: put decisions, constraints, and open questions in the handoff content — the distilled state the receiver needs, not the raw history. But because the handoff lives in the shared run, the receiver isn't limited to your summary. When a summary might have dropped an implicit decision, the receiver can query the run's full trace history directly and check the evidence itself. You get compaction without loss.
Walkthrough
At Nimbus, Ari (the support agent) wants to refund Acme Corp $1,200 for the CSV-export incident — above the $500 rule that requires reviewer approval. Ari hands the action to Rex (the reviewer agent) with requested_action="approve"; Rex reads the traces, finds the refund double-counts a credit already applied, and blocks.
Rex's block is now a durable feedback entry: it surfaces in Ari's assembled context, and reflection can later distill it into a lesson ("check for existing credits before computing refund amounts"). The review didn't just gate one action — it became memory.
Two conveniences on top of this loop, available in all three SDKs from v0.12.0: receive_handoffs(agent_id=...) / receiveHandoffs is a packaged receiver inbox (the same entry_types=["handoff"] query, filtered to handoffs addressed to that agent), and handoff(..., await_verdict=True) makes the sender block and poll until a verdict lands (returns the verdict string, or None on timeout, default 30s). On earlier SDK versions, use the explicit query shown in the walkthrough — it's the same wire calls.
Ari and Rex here share one run. If the reviewer works in its own run instead, link the sender's run and pass include_linked_runs=True on the trace query — see Runs, sessions, and scopes.
When not to use it
| Situation | Prefer instead |
|---|---|
| One agent calling a subroutine and consuming the result immediately, no review semantics | A plain function/tool call — memory adds nothing |
| Two agents interleaving tightly on the same task, every step | One shared run with lanes — handoffs per step is ceremony |
| Fanning a task out to isolated workers | Subagent isolation — separate runs, linked back |
Related
- Multi-agent shared state — the full recipe: registration, scopes, handoff, feedback, shared context
- The memory model — where
handoffandfeedbackentries sit in the taxonomy and context priority - Runs, sessions, and scopes — run linking, for cross-run review
- Shared team memory — fleet-wide knowledge sharing beyond one handoff
- Control HTTP reference — the wire contract for
/v2/control/handoffand/v2/control/feedback