Systems Library / Customer Service / How to Create an AI Bot with Human Handoff
Customer Service chatbots

How to Create an AI Bot with Human Handoff

Build seamless handoff from AI bot to human agents when needed.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

The hardest part of any ai chatbot human handoff escalation system is knowing when to stop and pass to a human. Get it wrong in either direction and you lose. Too early and you waste agent time. Too late and you frustrate the customer. I build these with three detection layers: content-based, sentiment-based, and conversation-length triggers.

The goal is a smooth transition where the human agent gets full context and the customer never has to repeat themselves.

What You Need Before Starting

Step 1: Define Handoff Triggers

Build a detection system that catches multiple escalation signals:

HANDOFF_KEYWORDS = [
    "speak to a human", "talk to someone", "real person",
    "manager", "supervisor", "complaint", "lawyer", "cancel"
]

def check_keyword_trigger(message):
    message_lower = message.lower()
    return any(keyword in message_lower for keyword in HANDOFF_KEYWORDS)

def check_frustration_trigger(messages):
    """Trigger if user sends 3+ messages with negative sentiment."""
    recent = messages[-3:]
    frustrated_count = sum(1 for m in recent if is_frustrated(m["content"]))
    return frustrated_count >= 2

def check_loop_trigger(messages):
    """Trigger if bot has responded 5+ times without resolution."""
    bot_messages = [m for m in messages if m["role"] == "assistant"]
    return len(bot_messages) >= 5

Step 2: Add Sentiment Detection

Use the AI model itself to detect frustration:

def is_frustrated(text):
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=10,
        messages=[{
            "role": "user",
            "content": f"Is this message frustrated or angry? Reply only YES or NO.\n\nMessage: {text}"
        }]
    )
    return "yes" in response.content[0].text.lower()

Step 3: Execute the Handoff

When any trigger fires, transition the conversation:

def execute_handoff(session_id, conversation, trigger_reason):
    # Generate a conversation summary for the agent
    summary = generate_summary(conversation)

    # Create a ticket in your support system
    ticket = create_ticket(
        session_id=session_id,
        summary=summary,
        full_conversation=conversation,
        trigger=trigger_reason
    )

    # Notify the agent
    notify_agent(ticket)

    # Send the customer a handoff message
    handoff_message = "I am connecting you with a team member who can help further. They will have our full conversation so you will not need to repeat anything."
    return handoff_message

Step 4: Generate Agent Context

Give the agent everything they need to pick up seamlessly:

def generate_summary(conversation):
    messages_text = "\n".join([f"{m['role']}: {m['content']}" for m in conversation])

    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=300,
        messages=[{
            "role": "user",
            "content": f"""Summarize this support conversation in 3 bullet points:
1. What the customer wants
2. What has been tried
3. Why it needs a human

Conversation:
{messages_text}"""
        }]
    )
    return response.content[0].text

Step 5: Handle the Agent Takeover

When the agent starts responding, the bot stops:

def handle_incoming_message(session_id, text, sender_type):
    session = get_session(session_id)

    if session["status"] == "handed_off":
        if sender_type == "agent":
            relay_to_customer(session_id, text)
        else:
            relay_to_agent(session_id, text)
        return

    # Normal bot flow
    response = process_with_ai(session_id, text)

    if should_handoff(session_id, text):
        execute_handoff(session_id, get_history(session_id), "trigger_detected")
        update_session_status(session_id, "handed_off")
    else:
        send_to_customer(session_id, response)

What to Build Next

Track handoff rates and reasons. If a specific topic causes most handoffs, add that knowledge to the bot. The goal is to reduce handoff rate month over month while keeping customer satisfaction high.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems