
Our WhatsApp number is on every page of this site, so people use it at odd hours. Nine in the morning, eleven at night, Sunday afternoons.
For a long time that was a problem. Someone would ask on a Saturday whether we do mobile apps, and the message sat there until Monday. By then they had messaged three other agencies.
Building the thing that answers turned out to be the asy half. A model can hold a sensible conversation about what we do on its first day. The weeks went on everything around that, and mostly on working out when it should say nothing at all.
Chatbot demos are always the same. Customer asks a clean question, bot gives a clean answer, nobody interrupts.
WhatsApp is not like that. Messages arrive in bursts of four. Your sales lead sees the notification and starts replying from his phone while the bot is already writing. People ask for prices we have never published anywhere. Very little of this is a language problem, and most of it is a timing problem.
Four messages in six seconds. Which one do you answer?
Your sales lead starts typing. Who backs off?
After a handover, how long should it stay gone?
What does it say when the answer is not written down anywhere?
How do you stop it confirming a meeting that was never booked?
How does someone get it back once they are done with a person?
Those six questions shaped the build. In every one of them the answer involves a person somewhere, either because the team can override Ami or because Ami stops and goes to find someone.
Before a reply goes anywhere it has been through a short run of checks. Most of them can only stop a reply. One path leads to Ami actually saying something.
So: Ami is not paused in this chat, no newer message has arrived behind this one, nobody from the team has typed anything, and this exact answer has not already gone out. Fail any of them and the message is logged and left alone.
More of the workflow is about staying quiet than about answering.

Nobody types one neat paragraph on WhatsApp. They send hi, then good morning, then the thing they actually wanted, all inside about six seconds. Early on that produced three separate replies, out of order, two of them answering a greeting.
The fix was a three second hold. If another message lands in that window the earlier one is dropped and the newest one answers, having read the lot. The customer sees the typing indicator while that happens, so the pause does not read as the thing being broken.
We tried five seconds first. Five is long enough that people start wondering.
Ami does not answer from whatever the model picked up in training. The site is chunked, embedded and sitting in a vector database, and every question goes through a search against that first.
Two things about that we did not expect. A customer's actual words make a poor query, so the question gets rewritten against the earlier messages before anything is searched. And broad questions have to be searched twice: one pass comes back almost entirely AI services, because that is what the front page is about, and the development and design work barely surfaces.
When the index has nothing, Ami says so. No price, no timeline, no opinion on a tool we have never written about. It offers to have someone confirm instead.
Messages are written to Postgres on Supabase against the customer's number, so coming back on Thursday is not starting from scratch. Ami will not ask your name twice or try to book you a call you already have.
Ami is the first layer on a channel that never closes. It is not standing in for anyone. It handles what it can check, passes on what it cannot, and anybody on the team can take a conversation off it without telling it to stand down.
In practice that comes down to three rules. A colleague's message beats anything Ami was about to send. Nothing gets confirmed that was not read off the live calendar or out of the index. And everything is written down, so whoever picks the chat up reads the conversation rather than a summary of it.

You can tap the button or just ask. Either way Ami tells them someone will be in touch, emails the team the number, the WhatsApp name and the time it came in, and stops replying.
Then it is gone for twelve hours. If somebody does reply, those twelve hours start again from their last message, so it cannot wander back into a live conversation. If a colleague replies while Ami is mid-draft, the draft is binned and nothing gets sent.
Typing bot on its own brings it back, carrying on from wherever the conversation had got to. Admin numbers can mute and unmute it the same way.
Ami books into the team calendar, but only when somebody asks for a call. Thirty minutes, on the hour, nothing sooner than three hours away, nothing further out than a week, and always inside working hours even when it is the one awake at two in the morning.
It reads the calendar before offering a time and again before confirming it, and it does not invent meeting links. The name, the email and a short summary go to the leads sheet whether or not anything ends up booked.
There is nothing unusual in the stack.
Working hours live in one place now. They used to be set in two, which is how we once offered somebody a slot half an hour after everyone had gone home.

None of this needed a better model. It needed a clear idea of when the thing should keep quiet, something worth quoting from, and a team that can override it at any point.
The practical difference is small enough to say in a line. Nobody waits until Monday any more, and when a conversation does reach one of us it arrives with a name and a question already attached instead of starting from hello.