The problem
In Saudi Arabia and the Gulf, WhatsApp is how people contact a business. They expect an answer quickly, in their own dialect, often outside working hours. A small clinic or law firm can't staff that, so leads go cold and appointments slip.
I wanted an agent that could run the front desk end to end, and that a business owner could trust with real customers.
What it does
- Answers FAQs from the business's knowledge base, mirroring the customer's language and register (formal Arabic when they use it, natural Gulf phrasing otherwise).
- Books, reschedules and cancels through a pluggable calendar (Postgres or Google Calendar), offering only slots that are really free as a WhatsApp list.
- Confirms before acting. Every change shows a code-written summary with Confirm / Change buttons.
- Sends reminders as approved templates with Confirm / Reschedule quick replies, and follows up once with leads who didn't book, respecting quiet hours and opt-outs.
- Hands off to staff when a customer is upset, asks for a person, or goes out of scope, with a web inbox for staff to reply and hand the chat back.
Key engineering decisions
Guardrails in code, not just the prompt. Early evals caught the model saying "you're booked" before any booking existed. Instead of a longer prompt, a booking tool is now rejected unless the previous turn asked for confirmation, and all confirmation messages are written by code from the actual database result.
Exactly-once messaging. Reminders must never send twice, even with several workers or a crash mid-send. Each row is claimed with FOR UPDATE SKIP LOCKED and marked sent with the WhatsApp message id in the same transaction. A smoke test runs two schedulers concurrently against real Postgres, and it caught real double-sends before launch.
Postgres as the queue. One Docker image runs three roles (api, worker, scheduler). No Redis, no broker: fewer moving parts for a small business to pay for.
Evaluation-driven development. 46 scripted conversations (23 Arabic, 23 English) replay through the real production path. Grading is programmatic first (bookings, state, facts, language), with an LLM judge on a stronger model only for judgment calls like prompt-injection resistance and a Gulf-dialect rubric. Every case runs three times and releases are gated on 3/3.
Cost control. The knowledge base and an Arabic style guide sit in a cached system prompt, history is capped, and the cheapest model that passes the gate is used.
Results
- 138/138 eval runs passing across both languages
- ~$0.003 per conversation and 2.8s median reply time on the eval set
- 292 unit and integration tests,
mypy --strictclean - Live-tested end to end on a real WhatsApp Business number with approved templates
Hisham Alhussain