Anyone at Dutch asks a data question in Slack and gets a governed answer in seconds. Making those answers trustworthy enough for the whole company to run on took real work, and it is what this case study covers.
Every data question funneled to a small BI team.
The bot answered confidently, and was quietly wrong.
Each failure became a permanent, automated control.
A nightly suite grades every answer against truth.
The whole company asks directly, and relies on it.
The answer up top is the simple case. Two harder ones matter more: following up in context, and what happens when the bot doesn't know.
Sanitized exchanges; figures are illustrative.
Dutch runs centralized BI on purpose. End users don't write SQL, and my team governs every data model, so definitions stay consistent across the company. The tradeoff is a queue, because every question about revenue, consults, refunds or retention landed on a small team, and the queue grew faster than we did.
An AI analyst was the obvious answer and the obvious risk. A wrong dashboard looks broken, but a wrong AI answer looks exactly like a right one, delivered with confidence to someone who has no way to check it.
The Slack bot is a thin webhook with no intelligence of its own. The answering logic sits inside Snowflake, next to the data, in two governed layers built with dbt.
a person asks a question in plain English
routes to 1 of 8 semantic views, one per business domain
synonyms, metric definitions and verified queries the AI must use
~70 dbt models, one recipe per metric, shared with every dashboard
Early on I spot-checked one answer against finance. It came back confidently, plausibly wrong.
"I only caught it because I happened to look. Nothing in our process would have caught it otherwise."
The system got sturdier every month. Each failure mode surfaced once, then closed for good.
Underneath all of it is a three-tier evaluation stack, every check graded against truth SQL written independently of the AI layer. The eval code gets the same review and fix discipline as anything else in production, because it needed it. The grader once failed a correct answer over a "$3.14M" it read as 3.14.
sv-drift-audit.yml · on: scheduleAsked in natural language, graded against independent truth SQL within tight tolerances. Failures page Slack before the workday starts.
The same metrics in alternate wordings real users typed. The model is stochastic, so a wording fails only on two consecutive misses. A failing wording becomes a verified query, permanently pinned.
A standing audit pulls real questions from the usage log each month and verifies the answers. The nightly and weekly checks use questions we wrote. This one uses the questions people actually asked. Weak spots turn into new verified queries.
On top of the guardrails from those incidents and the nightly evals, a fixed set of protections ships with every answer.
Never returns names, emails or anything that identifies a person.
Every answer names the table or view the number came from.
Answers about today carry an "as of" timestamp and a note on the pipeline.
When someone flags a wrong answer, the data team is notified in #dash-data-alert automatically.
A hard timeout stops a runaway query from tying up the warehouse.
Off-topic questions get a polite redirect instead of a guess.
The AI layer is configuration, and configuration drifts when humans paste it into consoles. We moved the semantic views into dbt, wired a deploy-on-merge workflow, and retired the console path. Git equals live by construction, and review happens on a pull request like any other code change.
The new path proved itself on day one by refusing to deploy over a permission gap a manual deploy would have hidden for weeks.
edit SQL in a console editor
paste, save, hope git stays current
drift audited after the fact, nightly
open a pull request
merge = deploy, via CI as a service role
drift structurally impossible
Once the governance held, we could add new kinds of questions without loosening any of it. Each new ability rides the same layers, tests and deploy path.
People kept asking which dashboard a number lives on. The bot now searches across 110 production dashboards and returns the best matches, each with a one-line note on what it covers and a link to open it.
We pulled product-analytics events into the governed layer, so the bot answers how content performs by audience. It is tested and deployed exactly like every other metric.