跳转至

Handoff: Change the Owner When the Current Agent Is Wrong

The Failure It Fixes

A travel assistant is helping with an itinerary. The user suddenly asks, “My father has a heart condition. Is this high-altitude plan safe?” If the same itinerary agent keeps answering, it may produce something that sounds like medical advice. The problem is not that the model needs a longer prompt. The problem is that the wrong agent owns the task.

Handoff handles that moment. The current agent lacks the domain, tool access, permission, or risk profile to continue. Instead of guessing, it transfers ownership to a better specialist with a compact summary.

One-Sentence Version

Handoff turns “I should not answer this” into a structured action: handle means answer directly, while handoff names the next agent and carries the summary needed to continue.

The Naive Version

answer = travel_agent.complete(user_message)

This code assumes the current agent is always the owner. Once the conversation crosses into medicine, visas, insurance, or legal constraints, the model may bluff. You need an auditable ownership change.

What Handoff Adds

Add a router before the specialist call:

  • handle: answer now.
  • handoff: transfer to a named agent with a short summary.

At runtime, Python validates that the target exists, then sends the original task plus the handoff summary to that specialist.

Flow

flowchart TD
  U["User question"] --> R["Router / triage"]
  R -->|handle| A["Current agent answers"]
  R -->|handoff + summary| S["Specialist takes over"]
  S --> O["Final answer"]
  A --> O

Trace Walkthrough

The example uses What is 9+1?. The router hands it to the math agent:

  1. router returns {"type":"handoff","to":"math","summary":"This is a simple arithmetic question: compute 9+1."}.
  2. Python checks that math is in the agent list.
  3. Python builds a new message containing the original task and the handoff summary.
  4. math returns 10.
  5. the trace records handoff.decision and handoff.completed.

For a travel assistant: normal itinerary questions stay with the travel agent; medical, insurance, visa, or safety questions move to the right specialist or to a human.

Code

from __future__ import annotations

from pathlib import Path

from agent_patterns_lab.patterns.handoff import HandoffAgent, run_handoff
from agent_patterns_lab.runtime import MockLLM, Tracer


def main() -> None:
    tracer = Tracer()

    router = MockLLM(['{"type":"handoff","to":"math","summary":"This is a simple arithmetic question: compute 9+1."}'])

    agents = [
        HandoffAgent(
            name="math",
            description="Arithmetic specialist.",
            model=MockLLM(["10"]),
        ),
        HandoffAgent(
            name="writer",
            description="Writing specialist.",
            model=MockLLM(["(unused)"]),
        ),
    ]

    out = run_handoff(router, agents, task="What is 9+1?", tracer=tracer)
    print(out)

    trace_path = tracer.export_jsonl(Path(".traces") / "64_handoff.jsonl")
    print(f"[trace] {trace_path}")


if __name__ == "__main__":
    main()

Run it:

UV_CACHE_DIR=.uv_cache PYTHONPATH=src uv run --no-sync python examples/64_handoff.py

What Goes Into the Summary

Do not forward the whole transcript by default. A useful handoff summary is short, but it must let the next agent start work:

  • what the user is trying to do
  • known constraints: budget, dates, party size, risk tolerance
  • what has already been tried and where it failed
  • what the specialist should decide next
  • pointers to files, links, or tool results if they matter

Boundaries to Decide

  • Who can hand off: only the router, or any active agent.
  • Allowed targets: the destination agent must be on an allowlist.
  • Depth: cap the number of handoffs to avoid ping-pong.
  • Permissions: handoff must not bypass tool access rules.
  • Answer ownership: the receiving specialist or a higher-level manager.

Use It When

  • The question crosses into a domain where the current agent should not improvise.
  • Agents have different tool permissions, such as normal support vs. account admin.
  • You need an audit trail showing who took over and why.

Avoid It When

  • The right route is obvious from the first user message. That is Routing.
  • The main agent should stay in charge and only call a specialist for a subtask. Use Agents-as-Tools.
  • You cannot limit handoff depth. Handoff loops are common and annoying.

Common Failure Modes

  • Empty summaries: “please handle this” is not a handoff; include constraints and open questions.
  • Context loss: important files, tool outputs, and user preferences must travel with the handoff.
  • Permission bypass: changing agents must not grant hidden access.
  • Unclear responsibility: once handoff succeeds, answer ownership must be explicit.

Nearby Patterns

  • Routing: routes at the entrance; Handoff changes owner mid-conversation.
  • Agents-as-Tools: the main agent calls experts but remains owner; Handoff transfers ownership.
  • Manager-Worker: a manager assigns tasks; Handoff feels more like escalation or referral.
  • Policy / Guardrails: Handoff often pairs with permissions, audit logs, and human escalation.

References

  • Azure Architecture Center — Handoff orchestration: https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/ai-agent-design-patterns
  • Microsoft Agent Framework — Handoff orchestration: https://learn.microsoft.com/en-us/agent-framework/user-guide/workflows/orchestrations/handoff