DataAIHub
DataAIHubNews · Research · Tools · Learning
AI Agents

Multi-Agent Handoffs Guide

How specialist AI agents delegate work through structured handoffs - routing, context transfer, ownership rules, and production patterns in OpenAI Agents SDK, CrewAI, and LangGraph.

50 min readIntermediateUpdated Jul 16, 2026

Quick Summary

A handoff transfers task ownership from one agent to another with enough structured context for the specialist to continue without restarting from scratch.

One Analogy

Like a hospital triage nurse routing a patient to cardiology with a chart - the specialist inherits the case, not a vague hallway rumor.

Engineering Rule

Handoffs must pass typed context and clear ownership; never rely on free-form multi-agent chat dumps as the only interface between specialists.

TL;DR

  • A handoff is a controlled transfer of ownership from one agent to a specialist - not just "mentioning" another agent in chat.

  • Routing decides who should act next; the handoff package decides what they need to succeed (goal, constraints, artifacts, tool results).

  • Structured context beats transcript dumping - pass summaries, IDs, and typed fields; truncate or abstract raw histories.

  • Ownership must be exclusive at a time - ambiguous dual control causes duplicate tool calls and conflicting user messages.

  • Handoffs compose with HITL and durability - approve before privileged specialists act; checkpoint across transfers so crashes do not lose the case.

Why This Matters

Single agents degrade when tool counts and responsibilities grow. The practical fix is specialization: a triage agent, a billing agent, a technical support agent. Specialization only works if transfer between them is reliable.

Poor handoffs look like this: Agent A dumps a 40-message thread into Agent B; B re-asks questions the user already answered; both call issue_refund; the user sees contradictory replies. Good handoffs look like ticket systems: clear owner, structured case file, explicit reason for transfer, and a path back when the specialist is done.

Frameworks now expose handoffs as first-class primitives (OpenAI Agents SDK handoff, CrewAI task delegation, LangGraph supervisor edges). Understanding the pattern matters more than any one API - the failure modes are the same everywhere.

The Problem Multi-Agent Handoffs Solve

Multi-agent systems need a way to move work across boundaries when:

  1. Tools and prompts should stay focused - billing tools do not belong on the coding agent.

  2. Different models or temperatures fit different roles - creative drafting vs. strict policy checks.

  3. Context windows fill up - specialists start with a compressed case, not the entire org history.

  4. Permissions differ - only the refunds agent can call payment APIs; triage cannot.

  5. Parallelism or staged pipelines - research hands off to writer hands off to reviewer.

Without an explicit handoff protocol, teams fake it with shared chat rooms. That scales poorly: loops, role confusion, and unreadable traces. Handoffs make delegation an engineered interface.

How We Got Here

Multi-agent handoffs evolved from helpdesk routing and supervisor patterns into first-class SDK primitives:

Diagram: From one agent to explicit handoffs

flowchart LR
    A[Single mega-agent] --> B[Role prompts in one chat]
    B --> C[Supervisor + workers]
    C --> D[Typed handoff tools]
    D --> E[Owned specialists + shared case]

Major components and how control or data moves between them.

Era Pattern Gap
One agent, many tools Prompt + huge registry Tool selection and prompt conflict
Shared group chat Agents talk freely Ping-pong, unclear ownership
Supervisor graphs Manager assigns workers Still needs a transfer contract
Handoff primitives OpenAI Agents SDK handoffs, LangGraph multi-agent Typed package + exclusive owner
Production + HITL + durable case state Permissions enforced outside the model

Anthropic — Building effective agents favors simple, composable patterns over swarms; handoffs earn their complexity only when specialization boundaries are real.

What Is a Multi-Agent Handoff?

A handoff is an orchestration event that:

  1. Selects a target agent (by router policy or model decision).
  2. Packages a handoff payload (goal, constraints, artifacts, user-visible summary).
  3. Transfers active ownership so only the target agent may act toward the user or call tools (unless designed as a consult).
  4. Optionally defines return semantics - report back to supervisor, close the case, or chain to the next specialist.
Handoff style Behavior Typical use
Transfer Source stops; target owns the user thread Support escalation
Delegate & return Target does subtask; result returns to supervisor Manager-worker
Consult Target advises; source keeps ownership Optional specialist opinion
Broadcast / swarm Multiple agents act (needs strong merge rules) Rare in production UX

Engineering Insight

💡 Key Idea - The hard part is not spawning agents. The hard part is the contract: what must be true when ownership moves, and what the new owner is allowed to do.

How Multi-Agent Handoffs Work

Routing

Routing answers "who next?" Options:

  • Rules - intent classifier / keywords → agent (fast, testable)
  • LLM router - small model picks from an agent catalog
  • Supervisor agent - capable model plans and assigns
  • User-driven - explicit "talk to billing"

Context transfer

What to pass:

  • Case identity - thread_id, customer_id, ticket_id
  • Goal & success criteria - what "done" means
  • Constraints - policy, budget, language, tone
  • Artifacts - order records, prior tool results, draft text
  • Handoff reason - why triage escalated (helps the specialist and audit)

What not to pass blindly:

  • Full raw tool dumps with secrets
  • Entire unrelated conversation history
  • Conflicting instructions from multiple system prompts

Diagram: Handoff sequence between specialists

flowchart LR
    U[User] --> T[Triage]
    T -->|to billing| B[Billing]
    T -->|to tech| S[Tech support]
    B -->|return| T
    S -->|return| T
    B -->|approve| H[Human review]
    H --> B
    T --> U

Major components and how control or data moves between them.

The diagram shows triage as a router/owner for the user-facing thread, specialists receiving structured handoffs, optional return to triage, and a HITL gate on privileged billing actions.

Handoff lifecycle

Diagram: State lifecycle

stateDiagram-v2
    [*] --> Triage
    Triage --> Routing: classify
    Routing --> Specialist: handoff
    Specialist --> Specialist: act
    Specialist --> Triage: return
    Specialist --> NextSpecialist: chain
    Specialist --> HumanGate: write gate
    HumanGate --> Specialist: decided
    Triage --> Done: reply
    Specialist --> Done: close
    Done --> [*]

Valid states and transitions for this control-plane pattern.

Lifecycle notes: only one agent holds user-facing ownership at a time. Every hop increments a budget; A→B→A without new evidence is a defect. Privileged specialists should interrupt for HITL before writes.

Framework mapping

Framework Handoff mechanism
OpenAI Agents SDK handoff(agent) tools the model can invoke
CrewAI Task delegation / agent assignment in crews
LangGraph Conditional edges, supervisor nodes, Send API for fan-out
AutoGen Speaker selection / handoff in group chats
Mastra Network/routing primitives for agent graphs

Architecture

Diagram: Handoff state and ownership model

flowchart TB
    User[User channel] --> Owner[Active owner lock]
    Owner --> Router[Router / supervisor]
    Router --> Catalog[Agent catalog]
    Router -->|handoff| Spec[Specialist agent]
    Spec --> Tools[Per-agent tool allowlist]
    Spec --> Case[(Shared case store)]
    Case --> Durability[Durable run_id]
    Spec -->|privileged| HITL[HITL gate]
    Spec --> Trace[Hop trace / spans]

Major components and how control or data moves between them.

Component Responsibility
Agent catalog Name, description, tools, model, permissions per specialist
Router / supervisor Chooses next agent; enforces max hops
Handoff schema Typed payload validated before transfer
Shared state store Case file durable across agents (durable execution)
Ownership lock Ensures one active writer to the user channel
Guardrails Per-agent tool allowlists (guardrails)
Trace graph Parent run + child spans for each handoff

Keep the catalog small. Routing accuracy collapses when you expose twenty vaguely named specialists. Compare frameworks that expose handoffs cleanly in Best AI Agent Frameworks and OpenAI Agents SDK vs LangGraph.

Step-by-Step Flow

Customer message: "My invoice looks wrong and the API returns 401 after we rotated keys."

  1. Triage receives message - Classifies as mixed billing + technical; policy says pick primary intent or split.

  2. Router decision - Primary: technical (service broken). Billing follow-up after auth restored. Handoff to Tech agent with {customer_id, symptom: 401 after key rotation}.

  3. Ownership transfer - Triage stops calling tools; Tech agent becomes active.

  4. Tech investigates - Calls check_api_logs, finds invalid key; walks customer through rotation. Marks tech issue resolved in shared state.

  5. Return or chain - Tech returns summary to supervisor: {tech_status: resolved, notes: "..."}.

  6. Second handoff - Supervisor hands off to Billing with invoice dispute fields + tech resolution note so Billing does not re-debug auth.

  7. Billing proposes adjustment - Hits HITL before credit note.

  8. Close - Supervisor synthesizes user-facing reply; ownership returns to triage or session ends.

  9. Trace - Auditors see hop list: triage → tech → triage → billing → human → billing → done.

Real Production Example

OpenAI Agents SDK–style handoffs with a typed context package (conceptual, production-shaped):

from __future__ import annotations

from dataclasses import dataclass, asdict
from typing import Callable, Literal

@dataclass
class HandoffPackage:
    case_id: str
    goal: str
    reason: str
    customer_id: str
    artifacts: dict
    constraints: dict
    return_to: str | None = "triage"

AgentName = Literal["triage", "billing", "tech"]

@dataclass
class Agent:
    name: AgentName
    description: str
    tools: dict[str, Callable[..., str]]
    instruct: str
    llm: Callable[[str, list[dict], list[str]], dict]

def build_handoff_tool(target: Agent, package_builder: Callable[..., HandoffPackage]):
    def handoff_to_target(**fields) -> str:
        pkg = package_builder(target=target.name, **fields)
        # Runtime swaps active agent + injects pkg into specialist context.
        return f"HANDOFF:{target.name}:{pkg.case_id}"

    handoff_to_target.__name__ = f"handoff_to_{target.name}"
    handoff_to_target.__doc__ = (
        f"Transfer ownership to {target.name} ({target.description}). "
        "Use when the user's need matches that specialist."
    )
    return handoff_to_target

class HandoffRuntime:
    def __init__(self, agents: dict[str, Agent], max_hops: int = 6):
        self.agents = agents
        self.max_hops = max_hops
        self.active = "triage"
        self.hops = 0
        self.case: dict = {}

    def run(self, user_message: str, case_id: str) -> str:
        self.case = {
            "case_id": case_id,
            "messages": [{"role": "user", "content": user_message}],
            "artifacts": {},
            "handoff_log": [],
        }
        while self.hops <= self.max_hops:
            agent = self.agents[self.active]
            tool_names = list(agent.tools) + [
                n for n in self.agents if n != self.active  # handoff tools registered separately in practice
            ]
            action = agent.llm(agent.instruct, self.case["messages"], tool_names)

            if action["type"] == "reply":
                return action["content"]

            if action["type"] == "tool":
                result = agent.tools[action["name"]](**action["args"])
                self.case["messages"].append({"role": "tool", "content": result})
                continue

            if action["type"] == "handoff":
                self._transfer(action["target"], action["package"])
                continue

            raise RuntimeError(f"unknown action {action}")

        raise RuntimeError("max handoff hops exceeded")

    def _transfer(self, target: str, package: HandoffPackage):
        if target not in self.agents:
            raise ValueError(target)
        self.hops += 1
        self.case["handoff_log"].append(asdict(package))
        # Replace noisy history with structured specialist brief.
        brief = (
            f"You are {target}. Case {package.case_id}. Goal: {package.goal}. "
            f"Reason: {package.reason}. Constraints: {package.constraints}. "
            f"Artifacts: {package.artifacts}."
        )
        self.case["messages"] = [
            {"role": "system", "content": brief},
            {"role": "user", "content": self.case["messages"][0]["content"]},
        ]
        self.active = target

# Specialists with narrow tools
billing = Agent(
    name="billing",
    description="Invoices, credits, refunds",
    tools={"get_invoice": lambda invoice_id, **_: f"invoice {invoice_id} ..."},
    instruct="Resolve billing issues only. Handoff back if the issue is technical.",
    llm=lambda *a, **k: {"type": "reply", "content": "..."},
)
tech = Agent(
    name="tech",
    description="API auth, outages, SDK errors",
    tools={"check_api_logs": lambda customer_id, **_: "401 invalid_api_key"},
    instruct="Resolve technical issues only.",
    llm=lambda *a, **k: {"type": "reply", "content": "..."},
)

Production additions: schema validation on HandoffPackage, durable case store, hop budgets, and per-agent tool allowlists enforced outside the model.

Design Decisions

Decision Option A Option B When to choose
Who routes Rules / classifier LLM supervisor Rules when intents are stable; LLM when long-tail
Ownership Hard transfer Delegate & return Transfer for user-facing specialists; return for subtasks
Context Full transcript Structured package + summary Structured for production; transcript only when short
Hop limit 3–4 8+ Prefer low; investigate loops if you need more
User visibility Silent transfer "Connecting you to billing" Disclose when humans expect a department switch
Specialist count 2–4 10+ Start small; split only with clear tool/permission boundaries

Comparisons

Handoffs vs Tool Calling

Dimension Handoff (transfer) Tool calling another agent
Ownership Moves to the specialist Caller keeps ownership
User thread Specialist drives next turns Caller synthesizes the reply
Context Structured package + brief Tool args / return value
Best for Department-style escalation Consult / subtask / lookup
Risk Ping-pong hops Nested agent loops without hop caps

If the specialist should own the conversation, use a handoff. If you only need a result back, call it as a tool - see tool calling. OpenAI Agents SDK handoffs make this distinction explicit.

Handoffs vs Supervisor pattern

Dimension Direct handoffs Supervisor pattern
Who routes Source agent or rules Central supervisor plans/assigns
Return path Optional / chain Usually delegate & return
Complexity Lower for 2–3 specialists Better for 3+ roles and multi-step plans
Failure mode Peer ping-pong Supervisor bottleneck / vague assignments

Supervisors and handoffs compose: the supervisor chooses the target; the handoff package is still the contract. LangGraph supervisor graphs and OpenAI handoff tools are two implementations of the same idea - see LangGraph multi-agent.

Handoffs vs Shared Memory

Dimension Handoffs Shared memory
Primary job Transfer ownership + brief Persist facts across agents/sessions
Payload Goal, reason, IDs, artifacts Profiles, embeddings, long-term notes
Without the other Specialist lacks case facts No clear owner; duplicate tool calls
Compose Package points at memory IDs Memory does not imply who may act

Agent memory stores knowledge; handoffs decide who acts next. Production systems use a durable shared case file plus a typed transfer - not a vector store alone.

⚠ Common Mistakes

  1. Transcript dumping - Flooding the specialist with noise and secrets. Summarize and pass IDs.

  2. No hop limit - Agents ping-pong forever (billingtech) until tokens die.

  3. Overlapping tools - Both agents can refund; handoffs do not prevent double charges.

  4. Vague agent descriptions - Router cannot choose; model invents random escalations.

  5. Losing case IDs - Specialist cannot fetch systems of record; re-asks the user for data already known.

  6. No return path - Work finishes in a black hole; supervisor never closes the loop with the user.

  7. Handoff as free-form chat between agents - Unstructured debates are hard to test and audit. Prefer typed payloads.

Where It Breaks Down

  • Tasks that are truly atomic - One agent with 4 tools is simpler; do not multi-agent for fashion.

  • Poor intent boundaries - If every ticket is "mixed," handoffs thrash. Improve triage taxonomy first.

  • Real-time voice / ultra-low latency - Extra model calls for routing add seconds; use rules.

  • Missing shared state - Handoffs without a durable case file fail after process restarts.

  • Organizational politics in prompts - Specialists with conflicting policies (sales vs. compliance) need a supervisor or human gate, not endless negotiation.

Decision tree: handoff or stay put?

Decision tree: When to hand off to another agent

flowchart TD
    A[Current agent missing tools or policy?] -->|No| B[Continue in-place]
    A -->|Yes| C{Clear specialist owner?}
    C -->|No| D[Escalate to human / supervisor]
    C -->|Yes| E[Typed handoff payload]
    E --> F{Irreversible write at destination?}
    F -->|Yes| G[HITL before write]
    F -->|No| H[Resume specialist with shared case id]
    G --> H

Hand off for specialization and policy boundaries - not to paper over a bloated tool registry.

When NOT to Use Multi-Agent Handoffs

Prefer a single agent (or a thin router) when:

  1. One agent with a small tool set already meets quality and latency targets - handoffs add hops without specialization wins.
  2. Intent boundaries are mushy - every ticket is "mixed"; fix triage taxonomy before adding specialists.
  3. You need sub-second replies - each hop is another LLM turn; use rules or one agent.
  4. Tools and permissions are identical across "roles" - renaming prompts is not a handoff architecture.
  5. You lack a durable shared case store - transfers lose IDs across restarts; add durable execution first.
  6. Eval coverage cannot assert hop sequences and forbidden tools - multi-agent bugs hide without traces.

Anthropic's guidance is pragmatic: start simple; earn multi-agent complexity with measurable boundaries.

Running in Production

Best Practice

Best Practices - Typed handoff schemas, exclusive ownership, max hops, per-agent tool allowlists, durable case IDs, and traces that show the hop graph.

Dimension Consideration
Scaling Stateless specialists + shared case store. Route by case_id affinity if caching helps.
Latency Each hop adds an LLM turn. Cache triage classifications; skip hops when confidence is high for a single specialist.
Cost More agents ≠ more cost if context is smaller per hop. Ping-pong is what burns money.
Monitoring Hop count, loop rate (A→B→A), handoff reason distribution, time-in-specialist, re-asks after handoff.
Evaluation Golden tickets with expected hop sequences and forbidden tools per agent.
Security Enforce tool allowlists in runtime, not prompts. Redact secrets in handoff packages.

Important

Enforce permissions in the tool layer. A handoff description that says "billing only" does nothing if the tech agent still has issue_refund in its bound tool list.

Common Mistake

Measuring only final answer quality. Many handoff bugs show up as duplicate actions or user re-prompts. Trace hops and tool ownership in evals.

  • OpenAI Agents SDK - Explicit handoff primitives between agents.
  • CrewAI - Role-based crews with delegated tasks.
  • LangGraph - Supervisor patterns, conditional edges, and Send for multi-agent graphs.
  • AutoGen - Group chat and speaker selection for multi-agent dialogues.
  • Mastra - TypeScript-first agent networks and routing.

Explore and compare:

If you understood this topic, read next:

Diagram: Learning path for handoffs

flowchart LR
    A[Durable] --> B[HITL]
    B --> C[Handoffs]
    C --> D[Memory]
    D --> E[Multi-agent]

Prerequisites: AI Agents · Multi-Agent Systems

Next topics: Human-in-the-Loop · Durable Execution · Agent Memory

Estimated time: 50 min · Difficulty: Intermediate

Key Takeaways

  • A handoff is a typed ownership transfer, not a free-form multi-agent chat dump.
  • Separate routing (who) from package design (what); keep exclusive user-facing ownership.
  • Cap hops, partition tools per agent in the runtime, and persist a shared case via durable execution.
  • Prefer consult-via-tool calling when the caller should keep ownership; hand off when the specialist should drive.
  • Gate privileged specialists with HITL; do not rely on prompt-only permission stories.
  • Start with two or three crisp roles; expand only when single-agent tool/prompt limits show up in metrics.
  • Compare stacks via Best AI Agent Frameworks, LangGraph vs CrewAI, and OpenAI Agents SDK vs LangGraph.

FAQs

What is the difference between a handoff and calling another agent as a tool?

A tool-call consult usually returns data while the caller keeps ownership. A transfer handoff moves ownership so the specialist drives the next user turns and tool calls.

How many specialists should I start with?

Two or three with crisp boundaries (e.g., triage + billing + tech). Split further only when tool overload or prompt conflict is measurable.

Should the user see handoffs?

For customer support, yes - set expectations ("routing you to billing"). For internal pipelines (research → writer), silent handoffs are fine.

How do I stop agent ping-pong?

Max hops, require new evidence before bouncing back, and give supervisors merge authority. Log A→B→A patterns as defects.

What belongs in the handoff package?

Goal, reason, case IDs, constraints, and key artifacts. Not full secret-bearing tool transcripts.

Can handoffs run in parallel?

Fan-out is possible (research agents), but user-facing ownership should remain single-writer. Merge results in a supervisor before replying.

Which framework is best for handoffs?

Depends on stack. OpenAI Agents SDK makes handoff tools explicit; LangGraph excels at graph-shaped supervisors; CrewAI fits role/task crews. Compare via Best AI Agent Frameworks.

How do handoffs interact with memory?

Write durable case facts to shared memory/store; keep specialist working memory small. See Agent Memory.

Do I need a supervisor agent?

Helpful when there are 3+ specialists or multi-step plans. For two agents, a rules router may be enough.

How should permissions work across handoffs?

Each agent gets a tool allowlist enforced by the runtime. Handoff never grants new privileges implicitly.

What metrics matter?

Hops per case, loop rate, specialist success rate, post-handoff clarification rate, and forbidden-tool attempts.

Can handoffs include human agents?

Yes - escalate to a human queue as a terminal or intermediate owner. Same package idea: structured case file, clear ownership.

How do I test handoffs?

Fixture dialogues with expected hop sequences, assert package schema, assert only the active agent can call tools, and assert max-hop failures are graceful.

When should I avoid multi-agent handoffs?

When one agent with a small tool set already meets quality/latency targets. Handoffs add moving parts; earn them with clear specialization wins.

References

Further Reading

Next Topics

Learning Path

Continue Learning

Related Guides

Related Tools

ToolCategoryPurposeWebsiteBest For
OpenAI Agents SDK
Open SourceAPI
frameworksOfficial OpenAI framework for tool-using agents with handoffs, guardrails, and tracing.openai.github.ioMulti-step agent workflows
CrewAI
NewOpen SourceAPI
frameworksMulti-agent framework with Crews, tasks, and event-driven Flows.crewai.comContent pipelines
LangGraph
FeaturedOpen SourceAPI
frameworksGraph-based orchestration runtime for long-running, stateful agents.langgraph.devMulti-agent orchestration
AutoGen
Open SourceAPI
frameworksMicrosoft framework with AgentChat, Core, Extensions, and Studio for multi-agent systems.microsoft.github.ioConversational multi-agent apps
Mastra
Open SourceAPI
frameworksTypeScript framework for agents, tools, and workflows with Studio.mastra.aiTypeScript agent apps

Related Rankings

Related Comparisons