Skip to content
Examples Gallery/Agent-to-Agent Handoff

Agent-to-Agent Handoff

Explore the Implementation

Clone RepositoryView on GitHub
Bash
git clone https://github.com/vobiz-ai/Vobiz-Livekit-Agent-to-Agent-Handoff-Example.git
cd Vobiz-Livekit-Agent-to-Agent-Handoff-Example

This example reveals LiveKit's native tool-handoff abstraction pattern. Instead of overloading a solitary massive system prompt, you deploy numerous distinct specialist sub-agents, orchestrating their activation when the LLM deems it appropriate to surrender the thread control. The codebase specifically models a TriageAgent fielding inbound calls before distributing the live session to dedicated SalesAgent, BillingAgent, or SupportAgent entities using isolated prompt boundaries.


How It Works

In advanced enterprise flows, compiling a multi-megabyte prompt governing every scenario leads to rampant hallucinations and sluggish latency. A tiered specialist array resolves this elegantly via state-maintained context propagation.

  • The Triage Router: The system initiates with a lightweight TriageAgent that simply answers the line. It collects the caller's identity array (stored actively in a CallerInfo dataclass bound to session.userdata), extracts user intent, and maps that intent to a function tool like transfer_to_billing().
  • Returning Instantiated Agents: Crucially, these function tools do not return string primitives in JSON. In LiveKit, the tool literally constructs and yields a brand-new Python Agent instance equipped with strict billing context configurations natively out of the tool executor.
  • Preserving Conversational Flow: The framework automatically detaches the Triage agent and mounts the specialized Billing agent inside the exact same RTC Room instance natively. Context memory arrays are duplicated precisely across the handoff boundary via chat_ctx.copy(exclude_instructions=True) so the new agent explicitly inherits the historical transcript without merging the previous agent's system prompt instructions.
  • Bi-Directional Flexibility: The handoff_count attribute guarantees the system recognizes cyclic state regressions, ensuring specialist agents can successfully route callers back into the upstream TriageAgent if the user requests an entirely disparate operational department.

Implementation Code

In LiveKit's Python architecture, Agent Hot-Swapping works natively by returning entirely new Agent instances directly out of the active function tool array explicitly passing the previous Context pointer:

Python
from livekit.agents import llm, Agent
from backend.specialists import BillingAgent

class RoutingTools(llm.ToolContext):
    def __init__(self, caller_identity: str):
        super().__init__()
        self.caller_identity = caller_identity

    @llm.function_tool(description="Pass control securely to the Billing department specialist")
    async def route_to_billing(self):
        """Immediately returns an Agent instantiation. LiveKit gracefully hot-swaps active contexts."""
        return BillingAgent(
            chat_ctx=self.chat_ctx.copy(exclude_instructions=True),
            fnc_ctx=BillingTools(caller=self.caller_identity)
        )