Semantic Layers, Data Warehouses and AI Agents: How We Built GoStudent's Modern Data Stack
Making explicit what was previously implicit — and why the same approach matters for any business sitting on years of untapped data.
Brutal is the AI and data team born out of GoStudent. GoStudent is the case study: everything below is the stack we built there, in production, and the approach we now bring to other companies.
Every fast-growing company reaches the same inflection point. You have data — lots of it — but you don't trust it. Finance reports a customer number. Marketing reports a different one. Both teams are “right,” depending on which query they ran. Decisions get delayed waiting for someone to reconcile spreadsheets. Your most expensive analysts spend half their time answering “can you just pull that number for me?”
We lived this at GoStudent. And over the past two years, we built our way out of it. This post explains how — and why we believe the same approach can unlock value for any organization with years of accumulated, untapped data.
“We wanted a single version of the truth that every team could trust and act on independently — without waiting for someone to reconcile the numbers.”
The problem with most data setups
Most companies don't have a data problem. They have a definition problem. The data exists. What's missing is a shared, governed understanding of what it means. What counts as an “active customer”? When does a lead become a conversion? Is revenue recognized at charge date or subscription date?
When these definitions live in individual SQL queries, Excel files, or the heads of specific analysts, the organization accumulates what researchers call semantic debt — inconsistent business logic that hides beneath the surface, invisible until something breaks or two reports disagree. Every new hire reinvents the wheel. Every new dashboard is a potential source of contradiction. And when AI agents enter the picture, each one has to reconstruct the same meaning from scratch.
Making definitions explicit, versioned, and shared — the same way software teams treat code — is what changes this.
Our architecture: three layers with a clear job each
We built our stack around three responsibilities, each owned by a dedicated layer. Data flows in one direction: raw → clean → governed metrics → dashboards. At every stage, automated tests gate the next step.
┌──────────────────────────────────────────────────────────────────┐
│ Sources: Stripe, HubSpot, Firebase, Google, Facebook, │
│ internal databases, CRMs, and 25+ more │
└──────────────────┬───────────────────────────────────────────────┘
│
▼ Airflow — scheduled ingestion, one DAG per source
┌──────────────────────────────────────────────────────────────────┐
│ Raw data warehouse (Amazon Redshift) │
│ Everything lands here, unchanged, as a historical record │
└──────────────────┬───────────────────────────────────────────────┘
│
▼ dbt — transformation in layered, tested SQL
┌──────────────────────────────────────────────────────────────────┐
│ Staging → Base → Presentation │
│ Business logic is encoded once, version-controlled, tested │
│ Metrics are defined here as YAML — not in dashboards │
└──────────────────┬───────────────────────────────────────────────┘
│
▼ Lightdash — self-service BI
┌──────────────────────────────────────────────────────────────────┐
│ 50+ dashboards · 1,800+ charts │
│ Any analyst builds on top of governed, pre-defined metrics │
│ No SQL required to answer most business questions │
└──────────────────────────────────────────────────────────────────┘Data moves in one direction. Definitions live in one place. Everyone looks at the same numbers.
Ingestion: bringing all your sources together
Data is only useful if you can reliably collect it. We pull from over 30 sources on a daily schedule — payment processors, CRMs, marketing platforms, product analytics, call centers, payroll systems, and more. Every source has its own ingestion pipeline, each running as an isolated job on AWS with clearly defined retry and failure behavior.
Nothing in the ingestion layer changes the data. Raw records land in Redshift exactly as the source sent them, which means we can always go back, reprocess, and recompute if a business rule changes — the historical record is never overwritten.
The pipelines are also sequenced: transformation only starts once all required upstream sources have landed cleanly. A failure in Stripe ingestion stops the pipeline and alerts the team — rather than silently propagating wrong revenue numbers downstream.
Transformation: business logic as code
Raw data from a payment processor doesn't know what a “customer” means to your business. That's the job of the transformation layer.
We use dbt (data build tool) to write all transformation logic as SQL models — 885 of them — organized into three layers. The staging layer cleans and standardizes raw data. The base layer applies business rules. The presentation layer produces the clean, grain-specific tables that power dashboards and carry the metric definitions. Every layer is independently tested before the next one builds.
Why this matters: one definition, everywhere
Take our definition of a “new customer” at GoStudent's GoCampus division. It requires: a Stripe subscription with a successful or pending charge, no refund, no lost dispute, and a payment that can be traced to a real student account. This definition lives in one SQL model. Every dashboard, every report, every downstream calculation that references “new customers” uses the same logic — automatically, because they all reference the same model.
When the definition needs to change (say, we decide pending charges should no longer count), we change it in one place, run the tests, and every downstream number updates on the next daily run. No spreadsheet reconciliation. No “which version of the query did you use?”
The semantic layer: metrics as a shared language
This is where our stack diverges from most data setups: metric definitions are governed artifacts — owned by the data team, version-controlled, reviewed, and shared — rather than logic buried inside individual charts.
There are dozens of tools and approaches for building a semantic layer — dbt metrics, LookML, Cube, AtScale, and many more. But underneath the different syntaxes and vendor positioning, they all reduce to the same idea: a plain English description and a SQL expression that together explain how each metric is calculated. That combination — human-readable intent alongside machine-executable logic — is what makes a semantic layer useful to both an analyst browsing a dashboard and an AI agent running queries programmatically. The metric becomes self-documenting. Anyone — or any agent — that reads it can see what it means and how to compute it.
In Lightdash, metrics like “lead-to-customer conversion rate” or “collected revenue by center” are defined once in a configuration file alongside the SQL model they belong to. Any analyst can add this metric to a new chart or dashboard without writing SQL. If they want to know how it's calculated, they look at the configuration file — which is version-controlled, reviewed, and documented.
# models/data_model/4_presentation/gocampus/docs/gocampus_leads.yml
columns:
- name: contact_id
meta:
metrics:
gocampus__total_leads:
type: count_distinct
description: "Total number of unique leads"
gocampus__lead_to_customer_rate:
type: number
sql: >
${gocampus__converted_customers} * 1.0 /
NULLIF(${gocampus__total_leads}, 0)
description: "Conversion rate from leads to paying customers"
format: '0.0%'A metric defined once in the dbt repo. Every dashboard that references it uses the same formula — no divergence possible.
Analysts can also toggle between metric variants using dashboard parameters — switching from “revenue by country” to “revenue by center” to “total revenue” without SQL. The variants are pre-defined by the data team; the business user picks from a dropdown.
The grunt work is disappearing
One of the historic objections to building a semantic layer was the sheer volume of repetitive work: every metric needs a description, a SQL expression, a naming convention, a format string. Doing that rigorously across hundreds of models felt expensive. That calculus has changed.
Tools like Claude Code and Codex can handle the mechanical side of metric authoring. Once you encode your team's rules — naming conventions, SQL patterns, how to express a ratio vs. a count, what a description should cover — as instructions or a skill, the agent can generate complete, consistent metric definitions across an entire domain. At GoStudent we use Claude Code for exactly this: a new model gets its metric YAML drafted automatically, following the same patterns as every model before it.
The human role shifts from filling in boilerplate to defining what needs to exist and whether the result is correct — deciding which metrics matter for a domain, what the edge cases are, and whether the generated definition actually reflects business intent. That judgment belongs with a person. The authoring that surrounds it no longer does.
In Q4 2025 — the three months immediately before we introduced Claude Code — the data team was merging around 35 pull requests per month. In the six months that followed, the average rose to 93. Same team size. No new engineers. In fact, we ran this while simultaneously migrating over 50 dashboards from Tableau to Lightdash and onboarding GoCampus — a whole new line of business with its own Stripe accounts, booking system, and studio network — into the data pipeline from scratch. A 2.7× increase in throughput, on top of two of the most demanding initiatives the team had taken on. The step-change — from 35 to 107 in the month after the first Claude-co-authored MR landed — is hard to attribute to anything else.
Governance: opening the floor without losing control
Once the semantic layer is in place and Lightdash is wired to expose only the presentation layer — the outermost, analytics-ready models — the data team can extend authorship of reports to the rest of the company without giving up control over what the numbers mean.
The metrics are vetted, approved, and locked in the repository. A sales manager building a new chart in Lightdash can combine, filter, and visualize any of them — but they cannot redefine what “new customer” means or change how revenue is calculated. Those decisions have been made, reviewed, and encoded. The floor is open; the foundations are fixed.
An AI agent takes this further. A business user can describe what they want to understand and let the agent compose the chart against the governed metric catalogue — without learning the BI interface, without writing SQL, and without any risk of using an unsanctioned definition. The agent operates within the same guardrails as any human user: it can only reference what the data team has sanctioned.
At GoStudent today, we have 50+ dashboards covering acquisition funnels, revenue, churn, NPS, commission calculations, campaign attribution, and product usage. Most of them were built by domain teams, not the data team. When Finance and Marketing disagree on a number, they trace the metric definition to the underlying model and find the discrepancy in the source data — not in someone's query.
What this looks like for a business with years of historical data
The architecture above was designed for an ongoing business generating data daily. The same approach applies to a business sitting on years of historical, unstructured, or siloed data — and in some ways the value is sharper there, because the data has never been queried properly in the first place.
Consider a financial institution with two decades of records spread across spreadsheets, PDFs, legacy databases, and email threads. The first step is ingestion and normalization: getting everything into one place in a consistent format. The second is definition — what does “portfolio performance” mean across that 20-year history? How do you handle different accounting conventions from different eras? These are exactly the problems the three transformation layers of this architecture are designed to solve.
Once the data is clean and the definitions are governed, the analytics becomes meaningful: trend analysis across the full history, patterns that were invisible when the data lived in silos, and a foundation that AI agents can query reliably because the underlying data is structured, tested, and trusted.
“Unstructured historical data is an asset waiting to be unlocked — as long as you have the infrastructure to do it.”
The role of AI in a governed data stack
There is a lot of noise right now about AI agents that can “answer questions about your data.” Most of it overpromises, because the bottleneck is rarely the AI — it's the data underneath it. An AI agent is only as reliable as the data it reads, and inconsistent or undefined data produces unreliable answers regardless of the model.
BCG Platinion has described this as semantic debt — the accumulated cost of inconsistent definitions and undocumented business rules that organizations carry without realizing it. Their research found that in most enterprise AI deployments, the majority of engineering effort goes toward reconstructing meaning rather than building new capability. Every new agent has to rediscover what “customer” means, what counts as “revenue,” what the edge cases are — from scratch.
This is precisely the failure mode that a governed semantic layer prevents. When the definition of “new customer” at GoStudent lives in a single, tested, version-controlled dbt model, every agent that queries it inherits the same answer. There is no reconstruction. The meaning has already been externalized.
The same research highlights a limitation of RAG-based approaches (where agents retrieve documents and summarize them) that is easy to underestimate: documents don't encode business logic, retrieval doesn't guarantee consistency across agents, and the outputs are hard to audit. A semantic layer produces deterministic, repeatable answers. A retrieval pipeline produces probabilistic ones. For business-critical decisions — revenue, churn, customer counts — the difference matters enormously.
The accuracy improvement is measurable. A recent benchmark by Rumiantsau and Fokeev tested three frontier LLMs — Claude Opus 4.7, Claude Sonnet 4.6, and GPT-5.4 — on 100 natural-language questions against a retail dataset, each model evaluated twice: once with only the raw schema, once with the schema plus a concise semantic document describing measures, conventions, and disambiguation rules. Adding the semantic document improved accuracy by 17 to 23 percentage points across all three models. Without it, the models answered correctly 46–51% of the time. With it, 68–69%. Model choice barely mattered — the presence or absence of the semantic layer explained almost all of the variance. The authors' conclusion is precise: the semantic layer doesn't make the model smarter. It changes the task itself — making explicit what was previously implicit.
There is also an organizational dimension that is easy to overlook. Defining what “customer” means requires reconciling assumptions that sales, finance, and legal each hold differently. At GoStudent, we resolved this through the data team acting as a forcing function: a definition only becomes a metric once it has been written down, reviewed, and agreed upon. That process is as much political as technical. BCG's framing is apt — semantic governance is a leadership exercise, not an IT project.
This is the direction we're moving: Airflow orchestrates collection, dbt governs the definitions, Lightdash handles self-service BI, and an AI layer on top answers natural language questions against data that is actually ready for it. The companies that will get the most out of AI agents in the next few years are the ones that have done this groundwork — turning implicit knowledge into governed, machine-readable structure before the agents arrive.
Sitting on years of data nobody trusts?
This is exactly what we build. Tell us what you're working with and we'll tell you what it would take.
BCG Platinion, Lost in Translation: Why AI Agents Cannot Scale Without Semantic Foundations (2025). bcgplatinion.com
Rumiantsau & Fokeev, Semantic Layers for Reliable LLM-Powered Data Analytics: A Paired Benchmark of Accuracy and Hallucination Across Three Frontier Models (2025). arxiv.org/abs/2604.25149