Customer Support Agent
Build an intelligent support agent that can handle tickets, escalate issues, and learn from interactions.
The Problem#
Your support team is overwhelmed with repetitive questions. You need an agent that can:
01Answer common questions using your knowledge base
02Escalate complex issues to human agents
03Update ticket status and gather required information
04Learn from successful resolutions to improve future responses
Architecture Overview#
Knowledge Base
Vector search over FAQ documents, previous tickets, and product docs
Ticket Management
Create, update, and route support tickets with proper categorization
Escalation Logic
Automatic routing to specialists based on issue complexity and sentiment
1
SET_UP_KNOWLEDGE_BASE
tools/knowledge-base.ts
import { Tool } from '@akios/core'
import { z } from 'zod'
const searchKnowledgeBase = new Tool({
name: 'search_knowledge_base',
description: 'Search the company knowledge base for relevant information about products, policies, and common issues.',
schema: z.object({
query: z.string().describe('The search query'),
category: z.enum(['product', 'policy', 'technical', 'billing']).optional(),
limit: z.number().min(1).max(10).default(5)
}),
handler: async ({ query, category, limit }) => {
// In practice, this would search a vector database
const mockResults = [
{
title: "Password Reset Process",
content: "To reset your password, go to login page and click 'Forgot Password'...",
category: "technical",
relevance_score: 0.95
},
{
title: "Billing FAQ",
content: "Charges appear 24-48 hours after subscription...",
category: "billing",
relevance_score: 0.87
}
]
return JSON.stringify({
results: mockResults.slice(0, limit),
total_found: mockResults.length
})
}
})2
CREATE_TICKET_TOOLS
tools/ticket-management.ts
import { Tool } from '@akios/core'
import { z } from 'zod'
const createTicket = new Tool({
name: 'create_support_ticket',
description: 'Create a new support ticket when the user needs human assistance.',
schema: z.object({
customer_id: z.string(),
subject: z.string(),
description: z.string(),
priority: z.enum(['low', 'medium', 'high', 'urgent']),
category: z.enum(['technical', 'billing', 'product', 'account'])
}),
handler: async (ticketData) => {
// In practice, save to your ticketing system (Zendesk, Jira, etc.)
const ticketId = `TICK-${Date.now()}`
console.log(`Created ticket ${ticketId}:`, ticketData)
return JSON.stringify({
ticket_id: ticketId,
status: 'open',
estimated_response: '2 hours',
message: 'Your ticket has been created and routed to our support team.'
})
}
})
const updateTicket = new Tool({
name: 'update_ticket_status',
description: 'Update an existing ticket with new information or status changes.',
schema: z.object({
ticket_id: z.string(),
status: z.enum(['open', 'pending', 'resolved', 'closed']).optional(),
notes: z.string().optional(),
internal_notes: z.string().optional()
}),
handler: async ({ ticket_id, status, notes, internal_notes }) => {
// Update ticket in your system
console.log(`Updating ticket ${ticket_id}:`, { status, notes, internal_notes })
return JSON.stringify({
ticket_id,
status: status || 'updated',
last_updated: new Date().toISOString(),
message: 'Ticket updated successfully'
})
}
})3
BUILD_SUPPORT_AGENT
support-agent.ts
import { Agent } from '@akios/core'
import { searchKnowledgeBase, createTicket, updateTicket } from './tools'
const supportAgent = new Agent({
name: 'CustomerSupportAgent',
model: 'gpt-4',
systemPrompt: `You are a helpful customer support agent. Follow these guidelines:
1. Always be polite and empathetic
2. First try to solve issues using the knowledge base
3. If you can't solve it, create a ticket and escalate
4. Ask for clarification when needed
5. Keep responses concise but informative
6. End conversations positively
When creating tickets, determine priority based on:
- Urgent: System down, security issues, data loss
- High: Major feature broken, billing disputes
- Medium: Minor bugs, feature requests
- Low: General questions, documentation requests`,
tools: [searchKnowledgeBase, createTicket, updateTicket],
memory: new ConversationMemory(), // Remember the conversation
guardrails: [
new ContentSafetyGuardrail(),
new ProfanityFilterGuardrail()
]
})
// Example conversation flow
async function handleSupportQuery(userMessage: string, customerId: string) {
const result = await supportAgent.run(userMessage, {
customer_id: customerId,
conversation_context: 'support_ticket'
})
return {
response: response.text,
actions_taken: result.steps.flatMap(step =>
step.toolCalls?.map(tc => ({
tool: tc.name,
args: tc.args
})) || []
),
needs_escalation: response.text.includes('ticket') ||
response.text.includes('escalate')
}
}`4
ADD_SENTIMENT_ANALYSIS
tools/sentiment-analysis.ts
import { Tool } from '@akios/core'
import { z } from 'zod'
const analyzeSentiment = new Tool({
name: 'analyze_sentiment',
description: 'Analyze the sentiment of customer messages to determine urgency and satisfaction.',
schema: z.object({
text: z.string().describe('The text to analyze'),
context: z.string().optional().describe('Additional context about the conversation')
}),
handler: async ({ text, context }) => {
// In practice, use a proper sentiment analysis service
const mockAnalysis = {
sentiment: text.toLowerCase().includes('angry') ||
text.toLowerCase().includes('frustrated') ? 'negative' :
text.toLowerCase().includes('thank') ||
text.toLowerCase().includes('great') ? 'positive' : 'neutral',
confidence: 0.85,
urgency_score: text.toLowerCase().includes('urgent') ||
text.toLowerCase().includes('asap') ? 0.9 :
text.toLowerCase().includes('please help') ? 0.7 : 0.3,
key_phrases: ['password reset', 'billing issue', 'technical problem']
}
return JSON.stringify(mockAnalysis)
}
})
// Enhanced agent with sentiment analysis
const enhancedSupportAgent = new Agent({
name: 'EnhancedSupportAgent',
model: 'gpt-4',
systemPrompt: 'You are an advanced customer support agent with sentiment analysis. Additional guidelines: If sentiment is negative and urgency is high, escalate immediately. If customer seems frustrated, acknowledge their feelings first. Use positive language to de-escalate tense situations. Offer solutions proactively when possible.',
tools: [searchKnowledgeBase, createTicket, updateTicket, analyzeSentiment]
})Advanced Features#
Learning From Interactions
learning-system.ts
import { Agent } from '@akios/core'
class LearningSupportAgent extends Agent {
private knowledgeBase: Map<string, { solution: string, success_rate: number }> = new Map()
async run(input: string) {
const result = await super.run(input)
// After successful resolution, store the solution
if (this.isResolution(result)) {
const key = this.extractProblemKey(input)
const existing = this.knowledgeBase.get(key)
if (existing) {
// Update success rate
existing.success_rate = (existing.success_rate + 1) / 2
} else {
// Store new solution
this.knowledgeBase.set(key, {
solution: response.text,
success_rate: 0.8 // Initial confidence
})
}
}
return result
}
private isResolution(result: any): boolean {
// Check if the response indicates problem solved
return response.text.toLowerCase().includes('resolved') ||
response.text.toLowerCase().includes('fixed') ||
response.text.toLowerCase().includes('solved')
}
private extractProblemKey(input: string): string {
// Simple keyword extraction - in practice use NLP
const keywords = input.toLowerCase()
.replace(/[^ws]/g, '')
.split(' ')
.filter(word => word.length > 3)
return keywords.slice(0, 3).join('_')
}
}
// Usage
const learningAgent = new LearningSupportAgent({
name: 'LearningSupportAgent',
model: 'gpt-4',
tools: [searchKnowledgeBase, createTicket, updateTicket]
})Multi Channel Support
multi-channel.ts
import { Agent } from '@akios/core'
// Support different communication channels
interface ChannelContext {
type: 'chat' | 'email' | 'voice' | 'social'
customer_id: string
thread_id?: string
urgency_multiplier: number
}
class MultiChannelSupportAgent extends Agent {
async handleMessage(message: string, context: ChannelContext) {
// Adjust behavior based on channel
const channelPrompts = {
chat: 'Keep responses brief and conversational',
email: 'Be more formal and comprehensive',
voice: 'Use simpler language, confirm understanding',
social: 'Be friendly and brand-aware'
}
const adjustedPrompt = `${this.systemPrompt}
Channel-specific guidelines: ${channelPrompts[context.type]}
Urgency multiplier: ${context.urgency_multiplier}`
return await this.run(message, {
system_prompt_override: adjustedPrompt,
channel_context: context
})
}
}
// Usage examples
const agent = new MultiChannelSupportAgent({
name: 'MultiChannelAgent',
model: 'gpt-4',
tools: [searchKnowledgeBase, createTicket, updateTicket]
})
// Handle different channels
await agent.handleMessage('My app is crashing!', {
type: 'chat',
customer_id: 'user123',
urgency_multiplier: 1.5
})
await agent.handleMessage('Billing question about last month', {
type: 'email',
customer_id: 'user456',
thread_id: 'thread_789',
urgency_multiplier: 0.8
})Testing your Support Agent#
Verify that your agent can handle both simple queries and escalation scenarios.
typescript
// Scenario 1: Simple query
const query1 = "How do I reset my password?";
const response1 = await supportAgent.run(query1);
console.log('Response 1:', response1);
// Scenario 2: Complex issue requiring human intervention
const query2 = "My account was double charged and I need a refund immediately.";
const response2 = await supportAgent.run(query2);
console.log('Response 2:', response2);Production Considerations
- Rate Limiting: Implement per-customer rate limits to prevent abuse
- Logging: Log all interactions for quality assurance and training
- Fallback: Have human escalation paths for when the agent can't help
- Privacy: Never log sensitive information like passwords or payment details
- Monitoring: Track resolution rates, customer satisfaction, and escalation frequency