Building AI-Powered Customer Support: From 24-Hour Response to Real-Time
Our support team was drowning. 10K tickets/day, 24-hour response time, customers frustrated. I built an AI support system.
Results: 30-second response, 85% automation, $500K saved. Here’s how.
Table of Contents
The Problem
Before AI:
- 10,000 tickets/day
- 24-hour average response time
- 50 support agents
- $1.2M annual cost
- Customer satisfaction: 3.2/5
Pain Points:
- Repetitive questions (70%)
- Slow escalation
- Inconsistent answers
- 24/7 coverage expensive
Solution Architecture
class AICustomerSupport:
def __init__(self):
self.llm = OpenAI(model="gpt-4")
self.knowledge_base = VectorStore()
self.ticket_system = TicketSystem()
self.escalation_rules = EscalationRules()
async def handle_ticket(self, ticket):
"""Main ticket handling flow."""
# 1. Classify ticket
classification = await self._classify(ticket)
# 2. Check if can auto-resolve
if classification['confidence'] > 0.8 and classification['type'] in self.auto_resolve_types:
return await self._auto_resolve(ticket, classification)
# 3. Generate suggested response for agent
elif classification['confidence'] > 0.6:
return await self._assist_agent(ticket, classification)
# 4. Escalate complex issues
else:
return await self._escalate(ticket, classification)
async def _classify(self, ticket):
"""Classify ticket type and urgency."""
prompt = f"""
Classify this customer support ticket:
Subject: {ticket['subject']}
Message: {ticket['message']}
Classify:
1. Type: billing, technical, account, shipping, other
2. Urgency: low, medium, high, critical
3. Sentiment: positive, neutral, negative, angry
4. Can auto-resolve: yes/no
5. Confidence: 0-1
Return JSON.
"""
response = await self.llm.apredict(prompt)
return json.loads(response)
async def _auto_resolve(self, ticket, classification):
"""Automatically resolve ticket."""
# Search knowledge base
relevant_docs = self.knowledge_base.search(ticket['message'], k=3)
# Generate response
response = await self._generate_response(ticket, relevant_docs)
# Send to customer
await self._send_response(ticket['id'], response)
# Close ticket
await self.ticket_system.close(ticket['id'], resolution=response)
return {
'status': 'auto_resolved',
'response': response,
'time': '30s'
}
async def _generate_response(self, ticket, context):
"""Generate customer response."""
prompt = f"""
You are a helpful customer support agent.
Customer question:
{ticket['message']}
Relevant information:
{context}
Provide a helpful, friendly response that:
1. Addresses the customer's question
2. Is clear and concise
3. Includes specific steps if applicable
4. Offers additional help
Tone: Professional but friendly
"""
return await self.llm.apredict(prompt)
Knowledge Base
from langchain.vectorstores import Pinecone
from langchain.embeddings import OpenAIEmbeddings
class KnowledgeBase:
def __init__(self):
self.embeddings = OpenAIEmbeddings()
self.vectorstore = Pinecone.from_existing_index(
index_name="support-kb",
embedding=self.embeddings
)
def add_document(self, doc):
"""Add document to knowledge base."""
self.vectorstore.add_texts(
texts=[doc['content']],
metadatas=[{
'title': doc['title'],
'category': doc['category'],
'last_updated': doc['updated']
}]
)
def search(self, query, k=3):
"""Search for relevant documents."""
results = self.vectorstore.similarity_search_with_score(query, k=k)
return [{
'content': doc.page_content,
'metadata': doc.metadata,
'relevance': score
} for doc, score in results]
def update_from_resolved_tickets(self):
"""Learn from resolved tickets."""
# Get recently resolved tickets
resolved = self.ticket_system.get_resolved(days=7)
# Extract common patterns
for ticket in resolved:
if ticket['rating'] >= 4: # High satisfaction
# Add to knowledge base
self.add_document({
'title': ticket['subject'],
'content': f"Q: {ticket['question']}\nA: {ticket['resolution']}",
'category': ticket['category'],
'updated': datetime.now()
})
Ticket Classification
class TicketClassifier:
def __init__(self):
self.llm = OpenAI(model="gpt-4")
self.categories = [
'billing', 'technical', 'account',
'shipping', 'product', 'refund'
]
async def classify(self, ticket):
"""Classify ticket with high accuracy."""
# Use few-shot learning
examples = self._get_classification_examples()
prompt = f"""
Classify customer support tickets.
Examples:
{examples}
New ticket:
Subject: {ticket['subject']}
Message: {ticket['message']}
Classification:
"""
response = await self.llm.apredict(prompt)
classification = json.loads(response)
# Validate
if classification['confidence'] < 0.6:
# Use ensemble approach
classification = await self._ensemble_classify(ticket)
return classification
def _get_classification_examples(self):
"""Get few-shot examples."""
return """
1. "My payment failed" → billing, high urgency, 0.95 confidence
2. "How do I reset password?" → account, low urgency, 0.98 confidence
3. "Product not working" → technical, medium urgency, 0.90 confidence
"""
async def _ensemble_classify(self, ticket):
"""Use multiple models for better accuracy."""
# Get classifications from multiple models
gpt4_result = await self._classify_with_model("gpt-4", ticket)
claude_result = await self._classify_with_model("claude-3", ticket)
# Combine results
if gpt4_result['category'] == claude_result['category']:
return gpt4_result # Agreement
else:
# Use highest confidence
return max([gpt4_result, claude_result], key=lambda x: x['confidence'])
Auto-Resolution
class AutoResolver:
def __init__(self, knowledge_base):
self.kb = knowledge_base
self.llm = OpenAI(model="gpt-4")
self.auto_resolve_types = ['password_reset', 'order_status', 'faq']
async def can_auto_resolve(self, ticket, classification):
"""Determine if ticket can be auto-resolved."""
return (
classification['type'] in self.auto_resolve_types and
classification['confidence'] > 0.85 and
classification['urgency'] != 'critical'
)
async def resolve(self, ticket):
"""Auto-resolve ticket."""
# Get relevant information
context = self.kb.search(ticket['message'], k=5)
# Generate resolution
resolution = await self._generate_resolution(ticket, context)
# Verify quality
if await self._verify_quality(resolution):
return resolution
else:
# Escalate if quality is poor
return None
async def _generate_resolution(self, ticket, context):
"""Generate resolution with context."""
prompt = f"""
Resolve this customer support ticket:
Ticket: {ticket['message']}
Relevant information:
{self._format_context(context)}
Provide:
1. Direct answer to the question
2. Step-by-step instructions if applicable
3. Links to relevant resources
4. Offer for additional help
Be helpful, clear, and concise.
"""
return await self.llm.apredict(prompt)
async def _verify_quality(self, resolution):
"""Verify resolution quality."""
prompt = f"""
Rate this customer support response quality (0-10):
Response: {resolution}
Criteria:
- Addresses the question
- Clear and actionable
- Professional tone
- Complete information
Score:
"""
score = await self.llm.apredict(prompt)
return int(score) >= 8
Agent Assistance
class AgentAssistant:
def __init__(self, knowledge_base):
self.kb = knowledge_base
self.llm = OpenAI(model="gpt-4")
async def assist(self, ticket):
"""Provide suggested response for human agent."""
# Search knowledge base
context = self.kb.search(ticket['message'], k=5)
# Generate suggested response
suggestion = await self._generate_suggestion(ticket, context)
# Find similar past tickets
similar = await self._find_similar_tickets(ticket)
return {
'suggested_response': suggestion,
'similar_tickets': similar,
'relevant_docs': context,
'confidence': 0.75
}
async def _generate_suggestion(self, ticket, context):
"""Generate suggested response."""
prompt = f"""
Generate a suggested response for this customer support ticket:
Ticket: {ticket['message']}
Context: {context}
The response will be reviewed by a human agent before sending.
Provide a helpful, professional response.
"""
return await self.llm.apredict(prompt)
async def _find_similar_tickets(self, ticket):
"""Find similar resolved tickets."""
# Use embeddings to find similar tickets
similar = self.kb.vectorstore.similarity_search(
ticket['message'],
k=3,
filter={'status': 'resolved', 'rating': {'$gte': 4}}
)
return similar
Escalation System
class EscalationSystem:
def __init__(self):
self.rules = self._load_escalation_rules()
self.agents = self._load_agent_availability()
async def escalate(self, ticket, classification):
"""Escalate ticket to appropriate agent."""
# Determine escalation level
level = self._get_escalation_level(classification)
# Find available agent
agent = await self._find_agent(level, classification['type'])
# Assign ticket
await self._assign_ticket(ticket, agent)
# Notify agent
await self._notify_agent(agent, ticket, classification)
return {
'status': 'escalated',
'agent': agent['name'],
'level': level
}
def _get_escalation_level(self, classification):
"""Determine escalation level."""
if classification['urgency'] == 'critical':
return 'senior'
elif classification['sentiment'] == 'angry':
return 'experienced'
else:
return 'standard'
async def _find_agent(self, level, category):
"""Find best available agent."""
available_agents = [
a for a in self.agents
if a['level'] == level and
category in a['specialties'] and
a['available']
]
# Sort by current workload
available_agents.sort(key=lambda x: x['current_tickets'])
return available_agents[0] if available_agents else None
Results
After 6 Months:
| Metric | Before | After | Improvement |
|---|---|---|---|
| Response Time | 24h | 30s | 99.9% |
| Resolution Time | 48h | 2h | 95.8% |
| Automation Rate | 0% | 85% | +85% |
| Customer Satisfaction | 3.2/5 | 4.7/5 | +47% |
| Support Agents | 50 | 15 | -70% |
| Annual Cost | $1.2M | $700K | -42% |
Breakdown:
- Auto-resolved: 85% (8,500/day)
- Agent-assisted: 12% (1,200/day)
- Escalated: 3% (300/day)
Cost Savings:
- Agent reduction: $500K/year
- Faster resolution: $200K/year (customer retention)
- AI costs: -$200K/year
- Net savings: $500K/year
Lessons Learned
- Knowledge base is critical: Quality in = quality out
- Don’t aim for 100% automation: 85% is optimal
- Human oversight essential: For complex/sensitive issues
- Continuous learning: Update KB from resolved tickets
- Monitor quality: Not just speed
Conclusion
AI customer support works. 85% automation, 30-second response, $500K saved.
Key takeaways:
- 99.9% faster response (24h → 30s)
- 85% automation rate
- Customer satisfaction +47%
- $500K annual savings
- Human agents for complex issues
Automate support. Keep customers happy.