DocsOverview

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