LattikBlog
← Back to blog

Data Platform

Your AI Agent Doesn't Have a Query Problem. It Has a Data Modeling Problem

AI-driven analytics promises plain-language answers, but the real bottleneck isn't the agent — it's the fragmented, duplicated data underneath. Here's why, and what we can do about it.

Thomas Zhenhua Wang11 min read

The promise of AI-driven analytics is simple: ask a question in plain language, get an answer. No SQL. No waiting on the data team. Just insight, on demand.

It doesn't always work. And it's not the agent's fault.

Try asking your analytics agent something like this:

"What's the average session length for paying users in Brazil?"

Sounds trivial. But which users table?

In our data warehouse, we have dim_all_users which has a country field — it's the user's resident country. We also have dim_all_payments_users which has another country field, but it's the invoice country — where the payment was processed. A data scientist will likely reach for dim_all_payments_users because it already has the payment info and a country column right there. Why join another table? But the person who asked the question meant the country where the user lives, not the country on the invoice. The query runs. The numbers look plausible. Nobody catches the mistake.

And that's a two-table question. Now try these:

"How many paying users in Brazil who saw an ad in the last 30 days clicked the signup button last week, and what was their average session length?"

"Break down last week's signup conversion rate by country, acquisition channel, and subscription tier — but exclude users flagged by the trust team."

"For users who churned last quarter, what were their top 5 most common activity patterns in the 90 days before churn, segmented by market?"

Each question is reasonable. Each requires joining half a dozen tables that were built independently, by different teams, at different times, for different purposes. We blame the agent. We blame the prompt. We blame the data engineers. But the real problem is simpler: the way we model data is broken, and AI agents are just the latest victims.

The Sprawl Nobody Talks About

Most companies have something like a dim_all_users table — a core dimension table that collects user-level attributes like country, gender, and age bucket. It's well-maintained, widely used, and foundational to dozens of downstream pipelines.

Now imagine the Payments team needs to add payments-related user attributes. The right move, in theory, is to add those columns to dim_all_users. Nobody does this. Modifying a core table can introduce latency for every downstream consumer. It touches pipelines owned by other teams. It requires cross-team coordination and review.

But there's a simpler reason nobody talks about: large organizations maintain thousands of data pipelines. Many of the complex ones span hundreds, sometimes thousands, of lines of transformation logic. No one wants to reach into someone else's thousand-line pipeline and risk breaking something they don't fully understand. The code is the only documentation, and even that often isn't enough.

So the Payments team weighs their options. They could propose adding their columns to dim_all_users — but that means filing a request with the team that owns it, waiting for review, coordinating a migration, and accepting the risk that their changes slow down every downstream pipeline. That process could take weeks. Meanwhile, their product manager needs payment analytics by the end of the quarter. The tradeoff calculation is quick: move fast, deliver business value now, deal with the data debt later. They build their own table, dim_all_payments_users, and move on.

Everyone calls this pragmatic. It is. It's also where the mess starts.

Multiply this across every team — Marketing, Growth, ML, Trust, Ads — and you get a dozen tables that all describe the same entity at the same granularity. Each one lives in a different place. Each one is owned by a different team. And anyone who needs the full picture has to join them all back together. Nobody planned this architecture. It emerged, one "pragmatic" decision at a time.

Duplication Is Bad. Silent Divergence Is Dangerous.

Table sprawl is annoying. What comes next is actually dangerous.

When the Payments team built dim_all_payments_users, they brought along a country field — they needed it for their analyses. But their use case is invoicing, so the country they capture is the invoice country — where the payment was processed. Meanwhile, the country in dim_all_users is the user's resident country — where they live.

Now two versions of country exist in two different tables with two different meanings. The column names are identical. The meaning is not. And no data consumer will notice the difference unless they dig into the pipeline code behind each table.

This is silent definition drift. Remember the question from the opening — "What's the average session length for paying users in Brazil?" A data scientist using dim_all_payments_users for convenience gets users whose invoices were processed in Brazil. A data scientist using dim_all_users gets users who live in Brazil. Two dashboards, two different numbers, both labeled "users in Brazil." One happens to be right. Neither data scientist knows which — or that the other definition even exists.

And this isn't limited to dimension tables. The same pattern plays out with any table at a fixed granularity level. Imagine a table keyed at the user, game, and interface level that tracks user activity. The Ads team needs to collect ad-related attributes at that granularity. The Growth team is tracking a different set of attributes at the same level. Each team builds their own table rather than contributing to a shared one — and the same sprawl, duplication, and divergence follow. Every time.

ML Engineers Pay the Same Tax

This isn't just an analytics problem. ML engineers hit it too — they just react differently. Instead of building downstream tables, they skip the warehouse entirely and go straight to the most upstream data source — a raw event log, a click stream, a logger table — and derive the features they need from scratch.

Ask them why and you'll hear perfectly good reasons. They want full control over how a feature is computed, end to end. They don't want to wait for upstream ETL pipelines to finish transforming the data — if they can grab the same information directly from the source, they skip the transformation delay and get better SLA. They want features sliced in ways that existing tables don't support — clicks in the last 7 days, not 30. And above all, they don't want their model to break because another team changed a pipeline upstream.

Fair enough. But the cost is real. Five different teams compute "user click count" from the same logger table — five pipelines doing the same work, five times the compute, five engineers spending weeks building feature pipelines instead of building models. Every new model starts with "first, let me build my features" instead of "let me grab the columns I need." That's not a data quality problem. It's an engineering waste problem, and it slows down every ML team in the organization.

The ML world has its own name for this. They call it "feature engineering." A more honest name would be "re-deriving attributes that already exist somewhere else because nobody trusts anyone else's pipelines."

AI Agents Can't Fix This. Stop Pretending They Can

Now add AI agents to this picture. Every data platform vendor is shipping a "talk to your data" feature. The pitch: a business user asks a question in plain language, the agent figures out the schema, writes the SQL, and delivers the answer.

Think about what we're actually asking the agent to do. Navigate a maze of overlapping tables with duplicated columns and divergent definitions. Figure out which dim_users table is the right one. Understand the difference between country in table A and country in table B. That context lives in people's heads — not in the data, and not even in the pipeline code. If you read the pipeline, all you see is a different calculation. No one documents why it's different. The reasoning was decided in a meeting, a Slack thread, or someone's head, and never made it into the codebase.

The popular answer? Give the agent a semantic model — a curated layer that maps business concepts to specific tables and columns. But let's be honest about what a semantic model actually is: yet another manually maintained artifact, subject to the same drift, staleness, and localized ownership problems as the underlying pipelines. When the data layer changes, someone has to update the semantic model to match.

Some teams go further, writing custom skills and prompts that guide agents toward the right tables. But these are team-specific, manually maintained, and don't scale. They're workarounds, not solutions.

The uncomfortable truth is that prompt engineering and skills development around data agents mostly make the inefficient parts of the workflow faster. They don't make the workflow less inefficient.

Many times, the agent simply can't get there at all. The relationships between tables, the meaning of columns, the subtle differences between similar fields — none of this is captured in the schema alone. There isn't enough information for the agent to reason correctly, no matter how many tokens it spends trying. This isn't a theoretical concern. Current state-of-the-art text-to-SQL systems achieve only 67-86% accuracy on benchmarks [1], and performance drops further with complex joins and real-world schemas. AWS has noted that enterprise databases are often optimized for storage rather than retrieval, resulting in complex schemas that demand specialized expertise just to query [2]. Google's text-to-SQL research confirms that even with the right schema, LLMs still make logical mistakes with complex joins and aggregations [3].

And even when an agent does produce a working query, the cost is real. The agent burns tokens reasoning over a complex schema. The resulting multi-join query is expensive to execute. The more complex the query, the more likely the agent gets it subtly wrong — returning a plausible but incorrect answer that no one catches. Most teams aren't paying close attention to these costs yet — the novelty of AI-generated queries still outweighs the scrutiny. But it's only a matter of time before organizations start looking at the token spend, the compute bills, and the quiet inaccuracies, and start asking the question they should have asked from the beginning: is the problem the agent, or the data it's working with?

What If We Stopped Layering and Started Fixing

What if the problem isn't the tools, the agents, or the people — but the physical layout of the data itself?

Today, the picture looks like this: every team maintains their own table, each with overlapping columns (including their own version of country), and anyone who needs a complete view has to join them all together.

Today: every team builds their own table — 6 tables, 6 versions of "country"

What if instead, all of these lived in a single wide table — with each team contributing their own columns independently?

After: one wide table, teams contribute independently

Each team writes on their own schedule. No shared pipeline. No coordination. And when a downstream consumer queries the table, they only read the column groups they actually need. If your query only touches the country and is_flagged, only the core and trust groups get read — and only those groups need to have landed. The payments and ads teams could be hours behind, and it wouldn't matter.

Selective read: only core and trust column groups are read for a query on country and is_flagged

No joins. No complex SQL. No ambiguity about which country is the right one. And that question from the top of this post — "What's the average session length for paying users in Brazil?" — doesn't require an agent to navigate six tables, pick the right country, and hope for the best. It's one table, a few columns, and a WHERE clause.

In the next post, we'll dig into the technical details of how to put such a system together.


References

  1. Promethium, "LLM & AI Models for Text-to-SQL: Modern Frameworks and Implementation Strategies"
  2. AWS, "Enterprise-grade natural language to SQL generation using LLMs"
  3. Google Cloud, "The Six Failures of Text-to-SQL (And How to Fix Them with Agents)"