An operations app that answers customers, and knows when to stop
A home services company ran sales follow-up on automated sequences that had no judgment in them. I built an internal operations app with a knowledge base, an AI responder that handles only what it should, and a gate that reads every outbound message before it sends and stops the ones that should not go.
- 9 weeks
- Empty repo to production
- 599
- Local water reports indexed, across 278 ZIP codes
- 26
- Queued messages to one customer who had already said no
The situation
The company sells and installs whole-home water treatment. Lead follow-up ran on scheduled sequences, and what the company knew about its own products, pricing, warranty and installation process lived in the heads of the people who happened to pick up the phone.
What was actually broken
- A customer replied "We decided to go another route. Thanks." Someone answered him kindly twenty six minutes later. Two days after that, the automation emailed him his city water quality report, and twenty six further touches were still queued at him, scheduled out to September the following year.
- Nothing was technically broken when that happened. Every rule passed. The sequence did exactly what it had been configured to do, which is the problem with automation that has no judgment in it.
- Answers to customer questions depended on who took the call, because the company knowledge was not written down anywhere a system could reach.
- Local water quality data is the single most persuasive thing you can show a homeowner, and it had to be looked up by hand, one address at a time.
What I built
- An internal operations app on Next.js and Postgres, twenty six tables covering leads, installs, sales, reminders, appointments and a full activity history.
- A knowledge base with vector search over the company documents, so answers come from one source instead of from memory.
- Water quality data indexed for the whole service area, 599 local reports across 278 ZIP codes, so a homeowner's actual report is available during the conversation rather than after it.
- An AI responder that handles a short whitelist of intents on its own, such as rescheduling and booking, and routes everything else to a person.
- An outbound gate. Every automated email and SMS is read cold by a separate model before it sends. If it does not make sense to send, the message is stopped, the rest of that lead's sequence is paused, and the owner gets a text.
- The responder was rehearsed against real message threads with sending disabled, so its behavior on every intent could be read and approved before it was ever switched on.
What changed
- Automated follow-up can no longer keep messaging someone who has already said no.
- Customer answers come from one knowledge base rather than depending on who picked up the phone.
- A homeowner's local water report is on screen during the conversation instead of researched afterwards.
- Every automated send is now inspected before it goes out, and a stopped message raises an alarm someone has to resolve.
Stack
Written up in more detail
How the outbound gate works, and why nothing else caught itThis client is not named. If you want a reference before signing, ask on the call and I will arrange one where the client has agreed to it.