Introduction to AutoGen for Customer Support
Customer support is one of the most impactful areas for AI automation. AutoGen, Microsoft's open-source multi-agent conversation framework, allows developers to build sophisticated support bots that can triage inquiries, answer questions from knowledge bases, escalate complex issues, and seamlessly hand off to human agents when needed. This guide walks you through building a complete, production-ready customer support bot using AutoGen.
What is AutoGen?
AutoGen is a framework for building multi-agent LLM applications where multiple AI agents can converse with each other to solve tasks. Each agent can have a distinct role, personality, and set of tools. Agents can autonomously collaborate, reason, and even request human input when necessary. The framework supports group chats, nested conversations, tool use, and code execution — all of which make it ideal for customer support scenarios.
Why AutoGen for Customer Support?
Traditional chatbot approaches suffer from rigid decision trees and limited contextual understanding. AutoGen offers several advantages for support bots:
- Multi-agent reasoning: Different agents handle different concerns — billing, technical troubleshooting, account management — each with specialized knowledge and prompts
- Natural escalation: Agents can autonomously decide when to involve a human agent, preserving context across the handoff
- Tool integration: Agents can query databases, search documentation, check order status, and execute code to resolve issues
- Conversational memory: The framework maintains full conversation history, enabling context-aware follow-ups
- Customizable guardrails: You can embed company policies, tone guidelines, and compliance rules directly into agent prompts
Setting Up Your Development Environment
Before building the bot, install AutoGen and its dependencies. You'll need Python 3.8+ and an API key for your chosen LLM provider (OpenAI, Azure OpenAI, or any compatible endpoint).
# Create a virtual environment (recommended)
python -m venv autogen_env
source autogen_env/bin/activate # On Windows: autogen_env\Scripts\activate
# Install AutoGen with OpenAI support
pip install pyautogen
# Optional: install additional providers
pip install autogen[openai]
pip install autogen[azure]
Set your API key as an environment variable:
# On Linux/macOS
export OPENAI_API_KEY="your-openai-api-key-here"
# On Windows PowerShell
$env:OPENAI_API_KEY = "your-openai-api-key-here"
Create a configuration file for your LLM endpoints. AutoGen uses this to manage model selection and fallbacks:
# config_list.json — place this in your project root
[
{
"model": "gpt-4o",
"api_key": "your-openai-api-key-here",
"api_type": "openai"
},
{
"model": "gpt-4o-mini",
"api_key": "your-openai-api-key-here",
"api_type": "openai"
}
]
Designing Your Customer Support Bot Architecture
A well-designed support bot uses multiple specialized agents that collaborate. Here's the architecture we'll build:
Agent Roles and Responsibilities
- Triage Agent: The first point of contact. Classifies the customer's issue, asks clarifying questions, and routes to the appropriate specialist agent
- FAQ Agent: Handles common questions about shipping, returns, account setup, and billing basics. Uses a knowledge base for accurate answers
- Technical Support Agent: Diagnoses product issues, walks customers through troubleshooting steps, and checks order/device information via tools
- Escalation Agent: Handles complex cases that require human intervention — refund disputes, legal concerns, or emotionally charged situations
- User Proxy Agent: Represents the customer in the conversation. It relays messages between the human user and the AI agents
Building the Bot — Step-by-Step Implementation
Step 1: Define Configuration and LLM Settings
Start by loading your configuration and defining the base LLM settings that all agents will inherit:
import autogen
import json
import os
from typing import Dict, List, Optional
# Load configuration from JSON file
with open("config_list.json", "r") as f:
config_list = json.load(f)
# Alternatively, load from environment variables
# config_list = autogen.config_list_from_json(
# env_or_file="config_list.json"
# )
# Base LLM configuration for all agents
llm_config = {
"config_list": config_list,
"temperature": 0.3, # Lower temperature for consistent support responses
"timeout": 120,
"cache_seed": 42 # Seed for reproducible conversations during testing
}
# For agents that need more creative responses (like de-escalation)
creative_llm_config = {
"config_list": config_list,
"temperature": 0.7,
"timeout": 120,
"cache_seed": None # No caching for varied empathetic responses
}
print("Configuration loaded successfully.")
print(f"Available models: {[c['model'] for c in config_list]}")
Step 2: Create the Knowledge Base and Tools
Give your agents access to real data. Here we create a simulated knowledge base and tool functions that agents can call:
# ---- Knowledge Base ----
KNOWLEDGE_BASE = {
"shipping": {
"standard_delivery": "5-7 business days, free on orders over $50",
"express_delivery": "2-3 business days, $14.99 flat rate",
"international": "10-14 business days, rates vary by destination",
"tracking": "Visit tracking.example.com and enter your order number"
},
"returns": {
"policy": "30-day return window for unused items in original packaging",
"refund_timing": "Refunds processed within 5-7 business days after receipt",
"exceptions": "Personalized items, digital goods, and clearance items are final sale",
"process": "Initiate return at returns.example.com or call 1-800-SUPPORT"
},
"account": {
"password_reset": "Use the 'Forgot Password' link on the login page. Reset email arrives within 2 minutes.",
"email_change": "Go to Account Settings > Profile > Change Email. Requires re-verification.",
"delete_account": "Contact support via email with subject 'Account Deletion Request' from your registered email."
},
"billing": {
"payment_methods": "We accept Visa, Mastercard, Amex, PayPal, and Apple Pay",
"billing_cycle": "Subscriptions renew on the same date each month",
"failed_payment": "We retry failed payments 3 times over 5 days before suspending service"
}
}
# ---- Tool Functions (simulated backend calls) ----
def lookup_order(order_id: str) -> Dict:
"""Simulate looking up an order in the database."""
# In production, this would query your actual order database
sample_orders = {
"ORD-12345": {
"status": "Shipped",
"tracking": "TRK-987654321",
"eta": "2024-12-20",
"items": ["Premium Widget", "Widget Charger"],
"total": "$89.99"
},
"ORD-67890": {
"status": "Processing",
"tracking": None,
"eta": "2024-12-22",
"items": ["Basic Widget"],
"total": "$29.99"
}
}
return sample_orders.get(order_id, {"status": "Not Found", "message": "Order ID not in system"})
def check_inventory(product_name: str) -> Dict:
"""Check current inventory for a product."""
inventory = {
"premium widget": {"in_stock": True, "quantity": 342, "warehouse": "Chicago"},
"basic widget": {"in_stock": True, "quantity": 1200, "warehouse": "Dallas"},
"widget charger": {"in_stock": False, "quantity": 0, "next_restock": "2024-12-28"},
"deluxe widget": {"in_stock": True, "quantity": 15, "warehouse": "New York"}
}
return inventory.get(product_name.lower(), {"in_stock": False, "message": "Product not found"})
# Register tools for AutoGen agents
tool_functions = [
{
"function": lookup_order,
"name": "lookup_order",
"description": "Look up order details by order ID. Returns status, tracking, ETA, and items."
},
{
"function": check_inventory,
"name": "check_inventory",
"description": "Check product inventory by name. Returns stock status and warehouse location."
}
]
print("Knowledge base and tools initialized.")
print(f"Knowledge categories: {list(KNOWLEDGE_BASE.keys())}")
print(f"Registered tools: {[t['name'] for t in tool_functions]}")
Step 3: Define the Support Agents
Each agent gets a carefully crafted system prompt that defines its role, boundaries, and escalation rules:
# ---- Triage Agent ----
triage_agent = autogen.AssistantAgent(
name="TriageAgent",
system_message="""You are the initial customer support triage specialist for WidgetCo.
YOUR ROLE:
- Greet the customer warmly and professionally
- Understand their issue by asking 1-2 clarifying questions if needed
- Categorize the issue into one of: FAQ (shipping/returns/account/billing), Technical Support, or Escalation
- Route the customer to the appropriate specialist agent
ROUTING RULES:
- Shipping, returns, account, or billing questions → FAQ Agent
- Product troubleshooting, order issues, technical problems → Technical Support Agent
- Refund disputes, legal threats, angry customers requesting supervisor, or anything requiring human judgment → Escalation Agent
IMPORTANT:
- NEVER try to solve the issue yourself — your job is diagnosis and routing
- If the customer is angry or threatening, route IMMEDIATELY to Escalation Agent without asking extra questions
- After routing, stop responding and let the specialist take over
- If you cannot confidently categorize after 2 questions, default to Technical Support Agent
When ready to route, say exactly: 'I'm transferring you to our [Agent Name]. They'll be able to help you right away.'
""",
llm_config=llm_config,
human_input_mode="NEVER"
)
# ---- FAQ Agent ----
faq_agent = autogen.AssistantAgent(
name="FAQAgent",
system_message=f"""You are the FAQ and general inquiries specialist for WidgetCo.
YOUR ROLE:
- Answer questions about shipping, returns, account management, and billing
- Use the knowledge base provided below for accurate, consistent answers
- Be friendly, concise, and helpful
KNOWLEDGE BASE:
{json.dumps(KNOWLEDGE_BASE, indent=2)}
RULES:
- Always cite the specific policy when answering (e.g., "Per our shipping policy...")
- If a question falls outside your knowledge areas, transfer back to Triage Agent for re-routing
- For complex billing disputes or refunds outside policy, suggest escalation
- Never make up policies — if the answer is not in the knowledge base, say: "That's a great question. Let me connect you with a specialist who can give you the most accurate information."
TONE:
- Professional but warm
- Use the customer's name when known
- End each response with a clear next step or offer of further assistance
""",
llm_config=llm_config,
human_input_mode="NEVER"
)
# ---- Technical Support Agent ----
tech_support_agent = autogen.AssistantAgent(
name="TechSupportAgent",
system_message="""You are the technical support specialist for WidgetCo products.
YOUR ROLE:
- Diagnose and resolve product-related issues
- Look up order statuses and inventory using available tools
- Guide customers through troubleshooting steps
- Escalate hardware failures or safety concerns to the Escalation Agent
AVAILABLE TOOLS:
- lookup_order(order_id): Check order status, tracking, and ETA
- check_inventory(product_name): Check stock availability
TROUBLESHOOTING PROCESS:
1. Acknowledge the issue and show empathy
2. Ask targeted diagnostic questions
3. Use tools to gather relevant data
4. Provide step-by-step resolution
5. If unresolved after 3 attempts, escalate to Escalation Agent
ESCALATION CRITERIA:
- Physical safety concerns (smoke, burning smell, electrical issues)
- Repeated failures after thorough troubleshooting
- Customer explicitly requests a supervisor
- Issues involving legal liability
TONE:
- Patient and methodical
- Use plain language, avoid jargon
- Validate the customer's frustration before problem-solving
""",
llm_config=llm_config,
human_input_mode="NEVER",
function_map={
"lookup_order": lookup_order,
"check_inventory": check_inventory
}
)
# ---- Escalation Agent ----
escalation_agent = autogen.AssistantAgent(
name="EscalationAgent",
system_message="""You are the senior escalation specialist at WidgetCo. You handle the most sensitive customer situations.
YOUR ROLE:
- Handle cases that require human-level judgment and empathy
- De-escalate angry or frustrated customers
- Process refund exceptions, legal concerns, and supervisor requests
- Coordinate with human agents for final resolution when needed
GUIDELINES:
- Start by acknowledging the customer's frustration sincerely
- Summarize what you understand about their situation to show you've been paying attention
- Offer concrete next steps — not generic platitudes
- For refunds outside policy: explain the standard policy, then offer what you CAN do (partial credit, future discount, etc.)
- For legal concerns: document the claim, assure the customer it will be reviewed, and provide a reference number
WHEN TO REQUEST HUMAN HANDOFF:
- Legal threats or formal complaints requiring legal team review
- Medical or safety incidents
- Requests for compensation above your authorized limit ($500)
- Customer insists on speaking with a real person after your best de-escalation attempt
When initiating human handoff, say: 'I'm documenting everything we've discussed. A member of our leadership team will personally reach out within 24 hours. Your reference number is [generate a realistic reference like ESC-2024-XXXX].'
TONE:
- Empathetic and sincere
- Take ownership — use 'I' statements
- Never sound robotic or scripted
""",
llm_config=creative_llm_config,
human_input_mode="NEVER"
)
# ---- User Proxy Agent (represents the customer) ----
user_proxy = autogen.UserProxyAgent(
name="CustomerProxy",
system_message="You are the customer's proxy in this support conversation. Relay the customer's messages accurately.",
code_execution_config=False,
human_input_mode="ALWAYS", # Real human provides input each time
max_consecutive_auto_reply=0 # Wait for human input after each agent response
)
print("All agents initialized.")
print(f"Agents: {[triage_agent.name, faq_agent.name, tech_support_agent.name, escalation_agent.name, user_proxy.name]}")
Step 4: Set Up the Group Chat with a Custom Speaker Selection
AutoGen's GroupChat manages multi-agent conversations. We'll use a custom speaker selection function to enforce the routing logic:
# ---- Custom Speaker Selection Function ----
def custom_speaker_selection(
speaker: autogen.Agent,
group_chat: autogen.GroupChat,
agents: List[autogen.Agent]
) -> Optional[autogen.Agent]:
"""
Custom logic for selecting the next speaker in the support workflow.
This enforces our routing architecture.
"""
last_message = group_chat.messages[-1]["content"] if group_chat.messages else ""
last_speaker_name = speaker.name if speaker else "None"
# If the Triage Agent just finished routing, select the appropriate specialist
if last_speaker_name == "TriageAgent":
if "FAQ Agent" in last_message or "faq" in last_message.lower():
return next(a for a in agents if a.name == "FAQAgent")
elif "Technical Support" in last_message or "tech" in last_message.lower():
return next(a for a in agents if a.name == "TechSupportAgent")
elif "Escalation" in last_message or "escalation" in last_message.lower():
return next(a for a in agents if a.name == "EscalationAgent")
# Default fallback
return next(a for a in agents if a.name == "TechSupportAgent")
# If a specialist agent mentions escalation, route to Escalation Agent
if last_speaker_name in ["FAQAgent", "TechSupportAgent"]:
if "escalation" in last_message.lower() or "supervisor" in last_message.lower() or "manager" in last_message.lower():
return next(a for a in agents if a.name == "EscalationAgent")
# If Escalation Agent requests human handoff, route to UserProxy for final message
if last_speaker_name == "EscalationAgent":
if "reference number" in last_message.lower() or "leadership team" in last_message.lower():
return next(a for a in agents if a.name == "CustomerProxy")
# If a specialist needs re-triage, route back to Triage Agent
if last_speaker_name in ["FAQAgent", "TechSupportAgent", "EscalationAgent"]:
if "triage" in last_message.lower() or "re-route" in last_message.lower() or "re-routing" in last_message.lower():
return next(a for a in agents if a.name == "TriageAgent")
# Default: let AutoGen's built-in selection handle it
# This uses LLM-based selection which works well for dynamic conversations
return None # None means use default AutoGen speaker selection
# ---- Group Chat Configuration ----
group_chat = autogen.GroupChat(
agents=[user_proxy, triage_agent, faq_agent, tech_support_agent, escalation_agent],
messages=[],
max_round=15,
speaker_selection_method="auto", # Will use custom function when needed
allow_repeat_speaker=False, # Prevent agents from hogging the conversation
speaker_selection_method_for_speaker=custom_speaker_selection
)
# ---- Group Chat Manager ----
manager = autogen.GroupChatManager(
name="SupportManager",
group_chat=group_chat,
llm_config=llm_config,
system_message="""You are the Support Manager orchestrating the customer support workflow.
Ensure smooth handoffs between agents and that the customer's issue is resolved efficiently.
Track conversation progress and step in only if the workflow stalls.""",
human_input_mode="NEVER"
)
print("Group chat and manager configured.")
print(f"Max rounds: {group_chat.max_round}")
print("Speaker selection: Custom routing + AutoGen auto-select fallback")
Step 5: Run the Conversation
Initiate the support session. The user proxy will prompt for human input at each turn:
# ---- Initiate the Support Conversation ----
def start_support_session(initial_message: str = None):
"""
Start a customer support session.
The UserProxy will ask for human input when it's the customer's turn to respond.
"""
if initial_message is None:
initial_message = """Hello! I need some help.
I ordered a Premium Widget (order ORD-12345) and it's been a week,
but I haven't received any shipping updates. Can you help me figure out what's going on?"""
print("\n" + "="*60)
print(" CUSTOMER SUPPORT SESSION STARTED ")
print("="*60)
print(f"Initial customer message: {initial_message[:100]}...")
print("-"*60 + "\n")
user_proxy.initiate_chat(
recipient=manager,
message=initial_message,
clear_history=True # Start fresh conversation
)
# Uncomment to run interactively:
# start_support_session()
Complete Runnable Script
Below is the entire bot consolidated into a single runnable script. Save it as support_bot.py and run it to start an interactive support session:
#!/usr/bin/env python3
"""
Customer Support Bot powered by AutoGen
A multi-agent support system with triage, FAQ, technical support, and escalation capabilities.
"""
import autogen
import json
import os
from typing import Dict, List, Optional
# ============================================================================
# CONFIGURATION
# ============================================================================
# Load your API configuration
with open("config_list.json", "r") as f:
config_list = json.load(f)
llm_config = {
"config_list": config_list,
"temperature": 0.3,
"timeout": 120,
"cache_seed": 42
}
creative_llm_config = {
"config_list": config_list,
"temperature": 0.7,
"timeout": 120,
"cache_seed": None
}
# ============================================================================
# KNOWLEDGE BASE & TOOLS
# ============================================================================
KNOWLEDGE_BASE = {
"shipping": {
"standard_delivery": "5-7 business days, free on orders over $50",
"express_delivery": "2-3 business days, $14.99 flat rate",
"international": "10-14 business days, rates vary by destination",
"tracking": "Visit tracking.example.com and enter your order number"
},
"returns": {
"policy": "30-day return window for unused items in original packaging",
"refund_timing": "Refunds processed within 5-7 business days after receipt",
"exceptions": "Personalized items, digital goods, and clearance items are final sale",
"process": "Initiate return at returns.example.com or call 1-800-SUPPORT"
},
"account": {
"password_reset": "Use the 'Forgot Password' link on the login page. Reset email arrives within 2 minutes.",
"email_change": "Go to Account Settings > Profile > Change Email. Requires re-verification.",
"delete_account": "Contact support via email with subject 'Account Deletion Request' from your registered email."
},
"billing": {
"payment_methods": "We accept Visa, Mastercard, Amex, PayPal, and Apple Pay",
"billing_cycle": "Subscriptions renew on the same date each month",
"failed_payment": "We retry failed payments 3 times over 5 days before suspending service"
}
}
def lookup_order(order_id: str) -> Dict:
sample_orders = {
"ORD-12345": {
"status": "Shipped",
"tracking": "TRK-987654321",
"eta": "2024-12-20",
"items": ["Premium Widget", "Widget Charger"],
"total": "$89.99"
},
"ORD-67890": {
"status": "Processing",
"tracking": None,
"eta": "2024-12-22",
"items": ["Basic Widget"],
"total": "$29.99"
}
}
return sample_orders.get(order_id, {"status": "Not Found", "message": "Order ID not in system"})
def check_inventory(product_name: str) -> Dict:
inventory = {
"premium widget": {"in_stock": True, "quantity": 342, "warehouse": "Chicago"},
"basic widget": {"in_stock": True, "quantity": 1200, "warehouse": "Dallas"},
"widget charger": {"in_stock": False, "quantity": 0, "next_restock": "2024-12-28"},
"deluxe widget": {"in_stock": True, "quantity": 15, "warehouse": "New York"}
}
return inventory.get(product_name.lower(), {"in_stock": False, "message": "Product not found"})
# ============================================================================
# AGENT DEFINITIONS
# ============================================================================
triage_agent = autogen.AssistantAgent(
name="TriageAgent",
system_message="""You are the initial customer support triage specialist for WidgetCo.
YOUR ROLE:
- Greet the customer warmly and professionally
- Understand their issue by asking 1-2 clarifying questions if needed
- Categorize the issue into one of: FAQ (shipping/returns/account/billing), Technical Support, or Escalation
- Route the customer to the appropriate specialist agent
ROUTING RULES:
- Shipping, returns, account, or billing questions → FAQ Agent
- Product troubleshooting, order issues, technical problems → Technical Support Agent
- Refund disputes, legal threats, angry customers requesting supervisor, or anything requiring human judgment → Escalation Agent
IMPORTANT:
- NEVER try to solve the issue yourself — your job is diagnosis and routing
- If the customer is angry or threatening, route IMMEDIATELY to Escalation Agent without asking extra questions
- After routing, stop responding and let the specialist take over
- If you cannot confidently categorize after 2 questions, default to Technical Support Agent
When ready to route, say exactly: 'I'm transferring you to our [Agent Name]. They'll be able to help you right away.'
""",
llm_config=llm_config,
human_input_mode="NEVER"
)
faq_agent = autogen.AssistantAgent(
name="FAQAgent",
system_message=f"""You are the FAQ and general inquiries specialist for WidgetCo.
YOUR ROLE:
- Answer questions about shipping, returns, account management, and billing
- Use the knowledge base provided below for accurate, consistent answers
- Be friendly, concise, and helpful
KNOWLEDGE BASE:
{json.dumps(KNOWLEDGE_BASE, indent=2)}
RULES:
- Always cite the specific policy when answering (e.g., "Per our shipping policy...")
- If a question falls outside your knowledge areas, transfer back to Triage Agent for re-routing
- For complex billing disputes or refunds outside policy, suggest escalation
- Never make up policies — if the answer is not in the knowledge base, say: "That's a great question. Let me connect you with a specialist who can give you the most accurate information."
TONE:
- Professional but warm
- Use the customer's name when known
- End each response with a clear next step or offer of further assistance
""",
llm_config=llm_config,
human_input_mode="NEVER"
)
tech_support_agent = autogen.AssistantAgent(
name="TechSupportAgent",
system_message="""You are the technical support specialist for WidgetCo products.
YOUR ROLE:
- Diagnose and resolve product-related issues
- Look up order statuses and inventory using available tools
- Guide customers through troubleshooting steps
- Escalate hardware failures or safety concerns to the Escalation Agent
AVAILABLE TOOLS:
- lookup_order(order_id): Check order status, tracking, and ETA
- check_inventory(product_name): Check stock availability
TROUBLESHOOTING PROCESS:
1. Acknowledge the issue and show empathy
2. Ask targeted diagnostic questions
3. Use tools to gather relevant data
4. Provide step-by-step resolution
5. If unresolved after 3 attempts, escalate to Escalation Agent
ESCALATION CRITERIA:
- Physical safety concerns (smoke, burning smell, electrical issues)
- Repeated failures after thorough troubleshooting
- Customer explicitly requests a supervisor
- Issues involving legal liability
TONE:
- Patient and methodical
- Use plain language, avoid jargon
- Validate the customer's frustration before problem-solving
""",
llm_config=llm_config,
human_input_mode="NEVER",
function_map={
"lookup_order": lookup_order,
"check_inventory": check_inventory
}
)
escalation_agent = autogen.AssistantAgent(
name="EscalationAgent",
system_message="""You are the senior escalation specialist at WidgetCo. You handle the most sensitive customer situations.
YOUR ROLE:
- Handle cases that require human-level judgment and empathy
- De-escalate angry or frustrated customers
- Process refund exceptions, legal concerns, and supervisor requests
- Coordinate with human agents for final resolution when needed
GUIDELINES:
- Start by acknowledging the customer's frustration sincerely
- Summarize what you understand about their situation to show you've been paying attention
- Offer concrete next steps — not generic platitudes
- For refunds outside policy: explain the standard policy, then offer what you CAN do (partial credit, future discount, etc.)
- For legal concerns: document the claim, assure the customer it will be reviewed, and provide a reference number
WHEN TO REQUEST HUMAN HANDOFF:
- Legal threats or formal complaints requiring legal team review
- Medical or safety incidents
- Requests for compensation above your authorized limit ($500)
- Customer insists on speaking with a real person after your best de-escalation attempt
When initiating human handoff, say: 'I'm documenting everything we've discussed. A member of our leadership team will personally reach out within 24 hours. Your reference number is [generate a realistic reference like ESC-2024-XXXX].'
TONE:
- Empathetic and sincere
- Take ownership — use 'I' statements
- Never sound robotic or scripted
""",
llm_config=creative_llm_config,
human_input_mode="NEVER"
)
user_proxy = autogen.UserProxyAgent(
name="CustomerProxy",
system_message="You are the customer's proxy in this support conversation. Relay the customer's messages accurately.",
code_execution_config=False,
human_input_mode="ALWAYS",
max_consecutive_auto_reply=0
)
# ============================================================================
# GROUP CHAT & CUSTOM SPEAKER SELECTION
# ============================================================================
def custom_speaker_selection(
speaker: autogen.Agent,
group_chat: autogen.GroupChat,
agents: List[autogen.Agent]
) -> Optional[autogen.Agent]:
"""
Custom routing logic for the support workflow.
"""
last_message = group_chat.messages[-1]["content"] if group_chat.messages else ""
last_speaker_name = speaker.name if speaker else "None"
# Triage Agent routes to specialist
if last_speaker_name == "TriageAgent":
if "FAQ Agent" in last_message or "faq" in last_message.lower():
return next(a for a in agents if a.name == "FAQAgent")
elif "Technical Support" in last_message or "tech" in last_message.lower():
return next(a for a in agents if a.name == "TechSupportAgent")
elif "Escalation" in last_message or "escalation" in last_message.lower():
return next(a for a in agents if a.name == "EscalationAgent")
return next(a