The temptation is obvious: the model is good at SQL, so hand it the schema and let it write queries. The problems show up in week two. A revenue figure that disagrees with the finance dashboard because the model summed a different column. A join through the wrong key that silently doubled rows. A confident answer about customer_tier, which does not exist.
The catalogue is the contract
In InsightViz the model is never given a table. It is given the semantic model’s catalogue: dimensions and metrics with business names, descriptions and synonyms, and no SQL at all. Its job is to pick from that list. The compiler turns the pick into SQL.
That is the whole prompt surface. Three consequences follow.
Joins are the model’s, not the LLM’s
The semantic model declares orders.customer_id = customers.id once. The compiler includes the join when a query touches customers and leaves it out otherwise. The LLM cannot choose a wrong key because it never chooses a key.
Metrics mean one thing
net_revenue is SUM(orders.amount - orders.discount) in the dashboard, in Explore and in every AI answer, because all three compile the same name through the same definition. When finance changes the definition, it changes once.
Invented columns are refused, not hallucinated into SQL
A query naming customer_tier fails at compile time with unknown dimension, and the model reads that error and tries again with something that exists. Every name in a query must be in the catalogue. That rule is also what makes column-level security hold by construction: a dimension a person may not see is simply not in their catalogue, and a query naming it is refused before any SQL exists.
Row policies ride the same path
A row policy is a filter the compiler adds to WHERE for anyone it applies to. The AI does not know it is there. It asks for sales by region and gets the regions that person is allowed to see, and the answer says so in the “how was this computed” panel.
The loop
The model has two tools: run_query and draw_chart. It queries, looks at a sample of the result, refines — when unsure how a category is spelled it asks for the distinct values first — and then answers in words. The whole trace is on the message: the logical query, the SQL, the rows it saw. Trust comes from that, not from a claim about accuracy.
What this costs
A catalogue has to exist, and someone has to write it. That is the honest price of the approach, and the reason the AI also does the boring work: deriving a first model from an extract, naming three hundred columns, writing synonyms. The model you ask questions of is the model it helped you write.