Multi-Agent

Handoffs transfer responsibility inside one run — not a second chatbot.

Multi-Agent

Multi-agent work in Shiro is built on handoffs: control moves to another registered agent while the same runner continues the run. You are not starting a disconnected second chat — you are changing who is responsible mid-execution.

Why handoffs exist#

Different domains need different tools and policies. A support agent that can also delete accounts or issue refunds is a footgun. A billing agent with refund tools and approval gates is clearer — and the handoff shows up in traces and Studio’s graph.

Support Triage
    │  handoff (invoice domain)

Billing Agent  ──► lookupInvoice / issueRefund (+ approval)

How it fits the runtime#

  1. Define specialist agents
  2. engine.registerAgent(...) so they can be resolved
  3. Attach a handoff strategy on the source agent (see HandoffStrategy in core)
  4. Execute once — the runner records handoff events
engine.registerAgent(billing);
engine.registerAgent(research);

const support = new Agent({
  name: "support",
  instructions: "Triage issues. Hand off billing questions.",
  provider: "openai",
  tools: [classifyIssue],
  handoff: myHandoffStrategy, // HandoffStrategy
});

Implement HandoffStrategy.evaluate to return HandoffDecisionStatus.Handoff with a targetAgent name, or Continue to stay on the current agent.

When to hand off#

Use a handoffDo not
Tools / approval policy changePrompt is slightly long
Domain ownership changesYou want a second opinion in parallel (model that explicitly)
Specialist needs narrower permissionsCosmetic “agent personas” with the same tools

Depth limits#

Unbounded handoff loops are a real failure mode. The engine owns a handoff depth limiter so a misconfigured strategy cannot recurse forever. Design acyclic happy paths; if you need cycles, document why.

Observability#

Handoffs emit events and appear as:

  • Terminal lines (→ Handoff → billing)
  • Graph edges between agents
  • Trace events you can export

See Studio and Tracing.

Best practices#

  • Register every handoff target on the engine
  • Give specialists fewer tools, not more
  • Put approval on the specialist’s mutating tools
  • Keep reasons in the handoff decision for operators

Common mistakes#

  • Calling engine.execute(specialist) manually and calling it a handoff
  • Sharing one mega-tool-list across all agents
  • Circular handoffs without a depth policy
  • Hiding the transfer outside the runner (Studio will not see it)