← All projects

Case study

The AI-Native Semantic Layer

How a one-person data team replaced a 24-hour analyst queue with governed answers in minutes, then earned back the trust it lost in month one.

Role
Founding data hire, end-to-end owner
Timeline
First business user in under 2 months
Team
Designed the architecture, built the server with heavy AI assistance, worked with the platform team on deployment
Outcomes

Context

I joined Supio as the founding data hire. No analytics function, no data models, no shared definitions. Every operational question, whether pipeline, renewals, or feature adoption, became a request to me, and the queue ran about 24 hours deep.

The deeper problem was pace. Supio shipped new features weekly, and every launch raised questions the existing dashboards had never heard of.

The problem, framed properly

Dashboards assume you know the questions in advance. Ours changed weekly: each launch needed new metrics, and the hand-built dashboard layer accumulated debt faster than one person could retire it.

So the real product problem wasn't “answers are slow.” It was that the system for producing answers couldn't keep pace with the product it was measuring. Fixing the queue meant changing the system, not staffing it.

The options I weighed

Grow an analyst / BI team

Passed

Linear cost that doesn't fix the structure: every weekly launch still adds dashboard debt faster than analysts can retire it. Scaling headcount to chase a treadmill.

Buy a text-to-SQL vendor

Passed

I evaluated the “chat with your data” category and rejected it. Adopting a vendor meant reworking our entire metric layer around its abstractions. That's a bet-the-stack commitment to an immature category, at a cost a one-person data team couldn't justify.

Build thin on open source

Chosen

dbt, DuckDB, YAML metric specs, and an MCP server: every piece portable, nothing proprietary to unwind. If the category standardizes in two years, we swap the serving layer and keep the marts.

Why build won

The deciding argument was market maturity, not technology. In an immature tool category, committing your metric layer to one vendor's abstractions is the most expensive kind of lock-in, because you pay for it precisely when you try to leave. Building thin on open standards kept the definitions ours and made the AI serving layer swappable.

The second argument was governance. An AI that answers from certified metric definitions is an analytics product; an AI that guesses over raw tables is a demo. No vendor in the category treated the semantic layer as the load-bearing part. I did.

What I shipped

dbt models the raw sources into business-ready marts. A YAML semantic layer defines every governed metric on top. DuckDB executes the queries, and an MCP server exposes the whole thing to Claude, where anyone in the company can ask a question in plain English. The query path is tiered on purpose: governed metrics answer first, a read-only fallback restricted to the curated marts answers otherwise and says so, and a question neither path should answer alone goes to human validation.

The layer also changed our own velocity. With definitions living in YAML, adding a metric for this week's feature launch went from an analyst project to minutes of work with AI coding tools. That's what let one person keep pace with a weekly ship cadence.

Architecture
Source systems
raw operational data
→
dbt marts
business-ready entities
→
YAML semantic specs
governed metric definitions
→
DuckDB
query engine
→
MCP server
the AI's contract with the data
→
Claude
where questions get asked

Adoption, and the month it almost died

Sales and RevOps adopted first, because they had the sharpest version of the pain. Every week they asked the same question, “how is the new feature landing?”, about a different feature each time, faster than dashboards could be built. Self-serve answers to that one question were the hook, and the rest of the usage followed.

Then came the month that almost killed it. Two people asked what was, to them, the same question and got two different numbers, and they found out by comparing notes in a meeting. One phrasing matched a governed metric. The other didn't, so it took the SQL fallback, which chose its own filters and grain. Both answers were correct for the query that actually ran, and neither person knew they had taken different paths.

The fixes were the real product work. I promoted that question into a governed metric so both phrasings resolve to one definition, narrowed what the fallback path could touch, made provenance loud enough that a fallback answer reads as a fallback answer, let any requester route an off-path question through human validation, and kept a lightweight regression set of known questions and known answers that I re-ran by hand whenever the semantic layer changed. And I owned the miss publicly rather than explaining it away.

Trust compounds. Today 150 people across five business functions connect their own Claude Desktop and build their own reports against it. That's sustained use across the business, not a launch spike.

Results

<5 min
from question to insight, down from 24 hours
150
people building their own reports
5
business functions self-serving
~2
analyst hires avoided per function

What I'd do differently

Ask before assuming. The tiering caught the class of problem, but when a question is headed for the fallback path, or is ambiguous about grain or time window, the agent should ask a clarifying question instead of picking one. That would have prevented the instance, not just the pattern. For AI data tools, certified definitions and knowing when to say no aren't hardening. They're the product.