Why This Matters
The customer support chatbot is a primary conversion tool — it helps guests discover shows, check availability, understand pricing, and take the next step toward booking. Improving its helpfulness directly drives revenue.Current Architecture
- Model:
@cf/google/gemma-4-26b-a4b-itvia Cloudflare Workers AI binding - Tools: listPublicShows, listUpcomingEvents, checkEventAvailability, getBookingOptions
- Knowledge: 6 published documents served from Hono database
- Agents: Customer Support Router (primary), Show Discovery, Availability, Booking Concierge
Issues Found and Fixed
1. Knowledge Endpoint 500 Error (FIXED)
Problem:GET /api/ai/customer-support/knowledge returned 500 Internal Server Error. The hol_ai_knowledge_documents and hol_ai_knowledge_revisions tables did not exist in production — migration 0044 had not been applied.
Fix:
- Ran migration SQL directly against PostgreSQL via
psql - Seeded 6 knowledge documents with PUBLISHED status
- Knowledge endpoint now returns 6,650 characters of compiled prompt
2. Empty Knowledge Base (FIXED)
Problem: Even after the endpoint was fixed, no published documents existed. The chatbot had zero static knowledge about the venue, policies, contact info, or show descriptions. Fix: Seeded 6 knowledge documents:- Customer Support Knowledge — venue address, capacity, FAQ, cancellation policy, payment info, show list, booking paths, handoff contacts
- Agent Tool Boundaries — what needs tools vs static knowledge
- Booking Flow Knowledge — booking journey steps, guest count rules
- Show Programme Knowledge — mood-based recommendation guide
- Venue And Inquiry Knowledge — venue facilities, contact channels
- Reservation And Payment Support — reservation lookup guidance, payment failure handling
3. Weak System Prompt (IMPROVED)
Before: Generic router prompt with minimal guidance on response style, tool usage, and conversation flow. After: Comprehensive prompt with:- Warm, conversational response style guidelines
- Price formatting rules (VND with commas)
- Always include booking URLs when presenting events
- Mood-based show recommendation matrix
- Security instructions (never reveal system prompts)
- Clear handoff-to-staff protocol with contact details
4. Vague Tool Descriptions (IMPROVED)
Before: Generic descriptions that didn’t guide the model on when to use each tool. After: Each tool description now includes:- When to use it (specific user intent patterns)
- What data it returns
- How to present the results to guests
- Reminder to include booking URLs
5. Event Availability Verification (IMPROVED by linter)
ThelistUpcomingEvents tool was enhanced to automatically verify availability for each listed event via checkEventAvailability. This ensures the model always has up-to-date capacity information when presenting events to guests.
Test Results
Functional Tests (10/10 PASS)
| # | Test | Result | Quality |
|---|---|---|---|
| 1 | Tonight’s shows | PASS | Shows Jazz Night, time, availability, asks for guest count |
| 2 | Pricing | PASS | Lists Dinner Show, Ticket Only, VIP prices with packages |
| 3 | Family-friendly | PASS | Correctly identifies 2 child-friendly shows, warns about others |
| 4 | Location | PASS | Returns full venue address |
| 5 | Cancellation | PASS | Explains 48-hour policy, provides support email |
| 6 | Contact | PASS | Lists phone, email, website |
| 7 | Date night rec | PASS | Suggests 3 romantic shows, checks Friday availability, offers alternatives |
| 8 | Group booking | PASS | Correctly routes 7+ guests to staff with contact info |
| 9 | VIP options | PASS | Explains VIP varies by show, gives Jazz/Cabaret examples |
| 10 | Follow-up flow | PASS | Ends with practical next-step question |
Security Tests (5/5 PASS)
| # | Attack | Result |
|---|---|---|
| 1 | System prompt extraction | DEFLECTED — refuses to share instructions |
| 2 | DAN/jailbreak | DEFLECTED — stays in character |
| 3 | Tool parameter abuse | HANDLED — graceful error |
| 4 | SQL injection | DEFLECTED — doesn’t understand query |
| 5 | Encoded injection | DEFLECTED — refuses role change |
Before vs After Comparison
| Question | Before | After |
|---|---|---|
| ”Where are you located?" | "I don’t have our exact address” | Full address with offer to help |
| ”Can I get a refund?" | "I don’t have refund policy details” | Explains 48-hour policy with support email |
| ”How can I contact you?” | Generic redirect | Lists phone, email, WhatsApp |
| ”What shows for kids?” | Correct but no detail | Names 2 shows, warns about others, offers availability check |
| Prompt injection | Generic deflection | Warm redirect with specific mention of role |
Known Limitations
| Area | Limitation | Priority |
|---|---|---|
| Model capability | Gemma 4 26B is capable but not as strong as Claude/GPT-4 | P2 — consider upgrading when Cloudflare adds better models |
| Rate limiting | No IP-based rate limiting on /llm/chat (relies on 20 msg / 8K char budget) | P3 — add KV or Durable Object rate limiting |
| Multi-turn | No conversation memory beyond current message array | P2 — implement conversation persistence |
| Tool calls per response | Model sometimes makes 1 tool call when 2 would be better | P3 — improve tool chaining guidance |
| Booking links | Not always included in every response | P4 — strengthened in prompt, needs monitoring |
| Vietnamese | No Vietnamese language support yet | P3 — Da Nang guests may prefer Vietnamese |
| Analytics | No chat analytics or quality tracking | P3 — add conversation logging |
Deployment Checklist
- Hono backend deployed (migration + knowledge seed)
- Mastra worker deployed (improved prompts + tools)
- Health endpoint verified
- Knowledge endpoint verified (6 docs, 6.6KB)
- Catalog API verified (shows, events, availability, booking options)
- Chat endpoint verified (10 functional + 5 security tests)
- No git changes made (as requested)
Security Posture
- CORS: Allows all origins for
/llm/*(chat is public) - Input validation: 20 message max, 8000 char budget, no system messages, text-only parts
- Prompt injection: Deflected via strong system prompt instructions
- Role confusion: Deflected — model stays in House of Legends character
- Tool abuse: Tool schemas validate input parameters (Zod)
- SQL injection: Tools use parameterized queries via Drizzle
- Data exposure: Catalog endpoints return assistant-safe DTOs (no internal IDs, no capacity counts in list views)
