Skip to main content

Agent Handoff System

The handoff system enables seamless task delegation between specialized agents, allowing complex workflows where each agent contributes their expertise.

Overview

When an agent encounters a task outside its expertise, it can dynamically hand off the conversation to a more suitable agent, ensuring optimal task completion.

Quick Start

1
Install praisonaiagents
pip install praisonaiagents
2
Import required components
from praisonaiagents import Agent, handoff
3
Create specialist agents
# Technical support specialist
tech_support = Agent(
    name="TechnicalSupport",
    instructions="You are a technical support specialist. Resolve technical issues."
)

# Billing specialist
billing = Agent(
    name="Billing",
    instructions="You are a billing specialist. Handle payment and subscription issues."
)
4
Create main agent with handoff capabilities
# Customer service agent that can handoff to specialists
customer_service = Agent(
    name="CustomerService",
    instructions="You are a customer service agent. For technical issues, handoff to TechnicalSupport.",
    handoffs=[tech_support, billing]  # Pass agent instances
)
5
Use handoffs naturally in conversation
# Customer service agent automatically hands off when needed
response = customer_service.chat("I'm having trouble installing the software")
# This will trigger a handoff to TechnicalSupport

How Handoffs Work

1. Handoff Detection

Agents identify when they need to delegate based on:
  • Task complexity beyond their expertise
  • Specific keywords or patterns in user requests
  • Explicit handoff instructions in their role

2. Target Selection

The system selects the best agent using:
  • Predefined handoff targets in agent configuration
  • Dynamic selection based on agent capabilities
  • Custom selection logic via callbacks

3. Context Transfer

When handing off, the system:
  • Packages the entire conversation history
  • Includes any relevant metadata
  • Maintains user context and preferences

4. Seamless Continuation

The receiving agent:
  • Gets full context of the conversation
  • Continues naturally without user intervention
  • Can hand back or to another agent if needed

Basic Usage

from praisonaiagents import Agent

# Specialist agents
billing_agent = Agent(
    name="Billing Specialist",
    instructions="You handle billing inquiries and payment issues."
)

tech_agent = Agent(
    name="Technical Support",
    instructions="You solve technical problems and provide guidance."
)

# Main agent with handoffs (pass agent instances)
triage_agent = Agent(
    name="Customer Service",
    instructions="You help customers and route to specialists.",
    handoffs=[billing_agent, tech_agent]
)

Handoff Configuration

Parameters

ParameterTypeDescriptionDefault
agentAgentTarget agent for handoffRequired
tool_name_overridestrCustom name for handoff tooltransfer_to_<agent_name>
tool_description_overridestrCustom descriptionAuto-generated
on_handoffCallableCallback functionNone
input_filterCallableFilter for conversation dataNone

Handoff Filters

Control what conversation data is passed during handoff:
from praisonaiagents.agent.handoff import handoff, handoff_filters

handoff(
    agent,
    input_filter=handoff_filters.remove_all_tools
)

Agent-Level Filters

from praisonaiagents.agent.handoff import handoff_filters

# Default filters available: ["all", "none", "self", "other", "team:"]

agent = Agent(
    name="TeamLead",
    handoff_filter="team:support",  # Only handoff to support team
    handoffs=["Agent1", "Agent2", "Agent3"]
)

# Filter examples:
# "all" - Can receive from any agent (default)
# "none" - Cannot receive handoffs
# "self" - Can only receive from itself
# "other" - Can receive from any agent except itself
# "team:xyz" - Can only receive from agents in team 'xyz'

Advanced Usage

Custom Handoff Names

from praisonaiagents import Agent, handoff

# Create handoff with custom name
transfer_to_human = handoff(
    name="transfer_to_human",
    description="Transfer the conversation to a human agent when the user requests it"
)

chatbot = Agent(
    name="Chatbot",
    instructions="You are an AI assistant. Transfer to human when requested.",
    tools=[transfer_to_human]
)

Handoff Callbacks

def on_transfer():
    print("Transfer initiated")

handoff(agent, on_handoff=on_transfer)

Structured Input with Pydantic

from pydantic import BaseModel
from praisonaiagents import Agent
from praisonaiagents.agent.handoff import handoff

class EscalationData(BaseModel):
    reason: str
    priority: str
    customer_id: str

escalation = handoff(
    escalation_agent,
    input_type=EscalationData,
    tool_description_override="Escalate to senior management with structured data"
)

agent = Agent(
    name="Intake",
    tools=[escalation]
)

Complete Example

from praisonaiagents import Agent
from praisonaiagents.agent.handoff import handoff, handoff_filters
from pydantic import BaseModel

# Specialist agents
order_agent = Agent(
    name="Order Management",
    instructions="You help with order status and tracking.",
    tools=[check_order_status, track_shipment]
)

refund_agent = Agent(
    name="Refund Specialist",
    instructions="You process refunds and handle return requests.",
    tools=[process_refund, check_refund_policy]
)

technical_agent = Agent(
    name="Technical Support",
    instructions="You solve technical issues and provide guidance.",
    tools=[diagnose_issue, create_ticket]
)

# Escalation with structured input
class EscalationRequest(BaseModel):
    issue_type: str
    severity: str
    description: str

escalation_agent = Agent(
    name="Senior Manager",
    instructions="You handle escalated issues requiring management attention."
)

# Main triage agent
triage_agent = Agent(
    name="Customer Service",
    instructions="""You are the first point of contact. Route customers to the right specialist:
    - Order issues → Order Management
    - Refunds → Refund Specialist
    - Technical problems → Technical Support
    - Complex issues → Escalate to management
    """,
    handoffs=[
        order_agent,
        refund_agent,
        technical_agent,
        handoff(
            escalation_agent,
            tool_name_override="escalate_to_management",
            input_type=EscalationRequest,
            on_handoff=lambda src, data: log_escalation(src.name, data)
        )
    ]
)

# Start the service
response = triage_agent.chat("I need a refund for order #12345")

Common Use Cases

Customer Support System

# Tiered support system with automatic escalation
l1_support = Agent(
    name="L1Support",
    role="Level 1 Support",
    instructions="Handle basic queries. Escalate complex issues to L2.",
    handoffs=["L2Support"]
)

l2_support = Agent(
    name="L2Support", 
    role="Level 2 Support",
    instructions="Handle complex technical issues. Escalate critical issues to L3.",
    handoffs=["L3Support", "L1Support"]
)

l3_support = Agent(
    name="L3Support",
    role="Level 3 Support", 
    instructions="Handle critical and escalated issues.",
    handoffs=["Engineering", "L2Support"]
)

Multi-Department Routing

# Multi-department organization
reception = Agent(
    name="Reception",
    role="Virtual Receptionist",
    handoffs=["Sales", "Support", "HR", "Finance", "Legal"]
)

# Each department can hand back to reception or to other departments
sales = Agent(
    name="Sales",
    role="Sales Department",
    handoffs=["Reception", "Finance", "Support"]
)

Language-Based Routing

# Multilingual support system
language_detector = Agent(
    name="LanguageRouter",
    role="Language Detection and Routing",
    instructions="Detect user language and route to appropriate agent.",
    handoffs=["EnglishSupport", "SpanishSupport", "FrenchSupport"]
)

Best Practices

Clear Handoff Criteria

Define explicit criteria for when agents should handoff:
  • Specific keywords or phrases
  • Task complexity thresholds
  • User requests for specialists
  • Error or uncertainty conditions

Context Preservation

Ensure important context is maintained:
  • Include conversation summary in handoffs
  • Pass relevant user preferences
  • Maintain task state and progress
  • Include any gathered information

Prevent Loops

Avoid infinite handoff loops:
  • Implement handoff history tracking
  • Set maximum handoff limits
  • Use handoff filters appropriately
  • Design clear agent responsibilities

User Experience

Make handoffs seamless for users:
  • Inform users about handoffs when appropriate
  • Maintain conversation continuity
  • Preserve user context and preferences
  • Minimize repetition of information

Troubleshooting

API Reference

See the Handoff API documentation for detailed information about:
  • The Handoff class
  • The handoff() function
  • HandoffInputData structure
  • Built-in handoff filters
  • Callback signatures

Next Steps