Chatboty prešli dlhú cestu od rule-based systémov. Moderný AI chatbot rozumie kontextu a rieši skutočné problémy.
Architektúra moderného chatbota
┌────────────────────────────────────────────────┐
│ Frontend │
│ (Chat UI, Voice, Messaging) │
└────────────────────┬───────────────────────────┘
│
┌────────────────────▼───────────────────────────┐
│ API Gateway │
│ (Auth, Rate Limiting, Logging) │
└────────────────────┬───────────────────────────┘
│
┌────────────────────▼───────────────────────────┐
│ Orchestration Layer │
│ (Intent Detection, Context Management) │
└────────────────────┬───────────────────────────┘
│
┌────────────────────▼───────────────────────────┐
│ LLM Layer │
│ (OpenAI, Claude, Mistral) │
└────────────────────┬───────────────────────────┘
│
┌────────────────────▼───────────────────────────┐
│ Knowledge Layer │
│ (RAG, Vector DB, Business Logic) │
└────────────────────────────────────────────────┘
Step 1: Základný chat
// app/api/chat/route.ts
import { streamText } from 'ai'
import { openai } from '@ai-sdk/openai'
const SYSTEM_PROMPT = `Si customer support agent pre e-shop.
Pravidlá:
- Odpovedaj stručne a priateľsky
- Pri otázkach o objednávkach žiadaj číslo objednávky
- Ak nevieš, povedz to a eskaluj na človeka
- Používaj slovenčinu`
export async function POST(req: Request) {
const { messages } = await req.json()
const result = await streamText({
model: openai('gpt-4o'),
system: SYSTEM_PROMPT,
messages
})
return result.toDataStreamResponse()
}
Step 2: RAG pre firemné dáta
import { openai } from '@ai-sdk/openai'
import { retrieveDocuments } from '@/lib/rag'
export async function POST(req: Request) {
const { messages } = await req.json()
const lastMessage = messages[messages.length - 1]
// Retrieve relevant documents
const docs = await retrieveDocuments(lastMessage.content)
const systemWithContext = `${SYSTEM_PROMPT}
Relevantné informácie z databázy:
${docs.map(d => d.content).join('\n\n')}
Použite tieto informácie pri odpovedi.`
const result = await streamText({
model: openai('gpt-4o'),
system: systemWithContext,
messages
})
return result.toDataStreamResponse()
}
Step 3: Tools pre akcie
import { tool } from 'ai'
import { z } from 'zod'
const tools = {
getOrderStatus: tool({
description: 'Získa stav objednávky',
parameters: z.object({
orderId: z.string().describe('Číslo objednávky')
}),
execute: async ({ orderId }) => {
const order = await db.orders.findUnique({ where: { id: orderId } })
if (!order) return { error: 'Objednávka nenájdená' }
return {
status: order.status,
estimatedDelivery: order.estimatedDelivery,
items: order.items
}
}
}),
createTicket: tool({
description: 'Vytvorí support ticket',
parameters: z.object({
subject: z.string(),
description: z.string(),
priority: z.enum(['low', 'medium', 'high'])
}),
execute: async ({ subject, description, priority }) => {
const ticket = await createSupportTicket({ subject, description, priority })
return { ticketId: ticket.id, message: 'Ticket vytvorený' }
}
})
}
Step 4: Conversation memory
import { Redis } from '@upstash/redis'
const redis = new Redis({ url: process.env.REDIS_URL })
async function getConversationHistory(sessionId: string) {
const history = await redis.lrange(`chat:${sessionId}`, 0, 20)
return history.map(h => JSON.parse(h))
}
async function saveMessage(sessionId: string, message: any) {
await redis.lpush(`chat:${sessionId}`, JSON.stringify(message))
await redis.expire(`chat:${sessionId}`, 60 * 60 * 24) // 24h
}
Step 5: Human handoff
const ESCALATION_TRIGGERS = [
'hovoriť s človekom',
'skutočný agent',
'nespokojný',
'sťažnosť'
]
function shouldEscalate(message: string): boolean {
return ESCALATION_TRIGGERS.some(t =>
message.toLowerCase().includes(t)
)
}
async function handleMessage(message: string, sessionId: string) {
if (shouldEscalate(message)) {
await notifyHumanAgent(sessionId)
return {
content: 'Prepájam vás na nášho kolegu. Prosím počkajte.',
metadata: { escalated: true }
}
}
// Normal AI response
return await generateAIResponse(message)
}
Frontend (React)
'use client'
import { useChat } from 'ai/react'
export function ChatWidget() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat()
return (
<div className="fixed bottom-4 right-4 w-96 bg-white rounded-lg shadow-xl">
<div className="h-96 overflow-y-auto p-4">
{messages.map(m => (
<div key={m.id} className={`mb-4 ${m.role === 'user' ? 'text-right' : ''}`}>
<span className={`inline-block p-3 rounded-lg ${
m.role === 'user' ? 'bg-blue-500 text-white' : 'bg-gray-100'
}`}>
{m.content}
</span>
</div>
))}
{isLoading && <div className="text-gray-400">Píšem...</div>}
</div>
<form onSubmit={handleSubmit} className="border-t p-4">
<input
value={input}
onChange={handleInputChange}
placeholder="Napíšte správu..."
className="w-full p-2 border rounded"
/>
</form>
</div>
)
}
Metriky na sledovanie
- Resolution rate - % vyriešených bez eskalácie
- CSAT - spokojnosť zákazníkov
- Response time - čas do prvej odpovede
- Containment rate - % konverzácií bez human handoff
Záver
Moderný chatbot nie je len LLM wrapper. Je to systém s RAG, tools, memory a human handoff. Začnite jednoducho a iterujte na základe reálneho používania.