OpenAI / AI Engine
KaiVox uses OpenAI GPT-4o as its AI brain — handling all voice conversations, intent detection, sentiment analysis, and fallback responses. One platform-level API key serves all tenants.
Environment Variable
| Key | Value | Required |
|---|---|---|
OPENAI_API_KEY | sk-... — from platform.openai.com → API Keys | ✅ Yes — AI will not work without this |
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
ConversationEngine — How It Works
App\Services\ConversationEngine is the central AI handler. It is called by both VobizService and TwilioService on every speech input from a caller.
Processing Pipeline
-
Build system prompt The engine assembles a multi-part system prompt:
- AI persona from the tenant's
ai_personasettings (name, voice style, language) - Industry pack prompt from
industry_vertical_packstable (if tenant has selected a pack) - Local intelligence context from
LocalIntelligenceService::buildAiContext()— current holidays, weather disruptions, seasonal context, cultural greetings - Knowledge Brain context from
KnowledgeService::buildAiContext()— up to 8 FAQ/SOP/pricing items, max 3000 chars
- AI persona from the tenant's
-
Intent detection Before sending to OpenAI,
IntentRouter::detect()runs a keyword scan on the caller's speech. Detected intents:emergency,speak_to_human,complaint,book_appointment,cancel_appointment,hours,pricing,location,general. -
OpenAI API call The conversation history (system prompt + all previous turns) is sent to
gpt-4ovia a Guzzle HTTP POST tohttps://api.openai.com/v1/chat/completions. The response text is extracted and returned. -
Emergency escalation check If intent is
emergencyorspeak_to_human, the engine creates anEscalationQueuerecord and adds escalation instructions to the AI response. -
Log the AI action Every significant event (intent detected, response generated, escalation triggered, failover activated) is logged via
AiActionLog::record()to theai_action_logstable.
System Prompt Structure
You are Aria, the AI receptionist for Pragati Women's Hospital.
Speak in a warm, professional, and caring tone.
Always respond in English. Keep responses under 3 sentences.
BUSINESS CONTEXT:
Industry: Healthcare (Medical)
Working hours: Mon-Sat 9am-7pm, Sunday closed.
Emergency line: Call 102 for ambulance. For emergencies say: "Please call 102 immediately."
Doctors available: Dr. Meera Patel (Gynecology), Dr. Anita Shah (Obstetrics).
LOCAL CONTEXT:
Today is Saturday, 9 Aug 2026. Time in Asia/Kolkata: 10:30 AM.
Upcoming holiday: Independence Day (15 Aug) — clinic will be closed.
Season: Monsoon. Mention that the clinic is easily accessible via covered parking.
KNOWLEDGE BASE:
[FAQ] Appointment booking: Call us or use the app to book. Same-day slots available Mon-Fri.
[PRICING] Consultation fee: Dr. Patel ₹500, Dr. Shah ₹600. Ultrasound ₹800.
[POLICY] Cancellation: Please cancel at least 2 hours before your appointment.
Intent Detection
App\Services\IntentRouter uses keyword matching (no extra API call) to classify the caller's intent before OpenAI processes it.
| Intent | Example Trigger Words | Action Taken |
|---|---|---|
emergency | "emergency", "chest pain", "bleeding", "accident" | Creates escalation record, returns emergency routing response |
speak_to_human | "speak to someone", "real person", "transfer me" | Creates escalation record, AI tells caller they'll be connected |
complaint | "complaint", "unhappy", "terrible", "refund" | Logs complaint intent, escalation suggested |
book_appointment | "book", "appointment", "schedule", "slot" | AI guides booking flow using available slots data |
cancel_appointment | "cancel", "reschedule", "postpone" | AI confirms cancellation details |
hours | "open", "hours", "timing", "when" | AI reads working hours from tenant config |
pricing | "price", "cost", "fee", "how much" | AI reads from knowledge base pricing items |
location | "where", "address", "location", "directions" | AI returns address from tenant profile |
general | (catch-all) | OpenAI handles normally |
Sentiment Analysis
After a call ends, KaiVox runs a second OpenAI call to analyse the full conversation transcript. The result is stored on the call_logs record.
| Field | Values | DB Column |
|---|---|---|
| Sentiment | positive / neutral / negative | sentiment |
| Quality score | 0–100 (AI-rated conversation quality) | quality_score |
| Summary | 1–2 sentence summary of what was discussed | ai_summary |
| Call outcome | booked / enquiry / complaint / unknown | call_outcome |
A negative sentiment on a call triggers the call_negative_sentiment automation trigger — which can fire automations like notifying the owner or moving the customer to a complaint pipeline stage.
Failover System
Every OpenAI call is wrapped in FailoverService::withFallback(). If OpenAI throws an exception (timeout, rate limit, 500 error), the failover system:
- Catches the exception
- Logs a
failover_activatedevent inai_action_logs - Returns an intent-aware fallback response (not a generic error)
emergency → "This sounds urgent. Please call emergency services at 102 immediately."
book_appointment → "I'm having a brief technical issue. Please call back in a moment to book."
speak_to_human → "Let me connect you to our team. Please hold."
general → "I'm sorry, I didn't quite catch that. Could you please repeat your question?"
AI Persona Editor
Each tenant can customise their AI persona at Settings → AI Persona:
- Name — e.g. "Aria", "Kai", "Max"
- Voice style — professional, friendly, formal, casual
- Language — English (Indian), English (US), Hindi (future)
- Greeting message — first thing the AI says on answering
- Escalation message — what AI says when transferring to a human
AI Prompt Versioning
Prompt changes are tracked in the ai_prompt_versions table. Super Admins can view and revert to any previous version via Super Admin → AI Prompts. Tenants can A/B test prompts via Settings → Voice A/B Testing.
Troubleshooting OpenAI
| Problem | Cause | Fix |
|---|---|---|
| AI doesn't respond, call ends | OPENAI_API_KEY missing or invalid | Check .env, verify key at platform.openai.com |
| AI gives generic error response | Failover activated — OpenAI returned error | Check ai_action_logs table for failover_activated events |
| AI doesn't know business info | Knowledge Brain empty or AI context too long | Add items in Knowledge Brain; check AI Preview in Knowledge settings |
| Wrong language / tone | AI persona not configured | Settings → AI Persona — set name, style, greeting |
| High OpenAI costs | Long conversation histories accumulate tokens | Reduce max conversation turns; shorter knowledge context |