DEV Community

Sudeep Hazra
Sudeep Hazra

Posted on

Design semantic views around business questions, not agents

A question in the October r/dataengineering discussion thread caught my attention. A team was building Snowflake Semantic Views for business users and could not decide how to divide them. Should each topic have its own view, or should several views be connected to an agent?

That sounds like a Snowflake configuration question. It is really a modelling boundary question.

I would build semantic views around coherent business questions and stable metric definitions. I would let the agent route users to those views. The agent is an interface and orchestration boundary. It should not determine where the business model begins and ends.

This distinction matters because agents change quickly. Revenue, booking, inventory, and customer definitions usually need to outlive whichever chat interface happens to be fashionable this quarter.

A semantic view is a business contract

Snowflake defines a Semantic View as a schema-level object that maps business concepts to physical data. It contains logical tables, dimensions, facts, metrics, and the relationships between them. Cortex Analyst uses that metadata to generate SQL.

The useful part is not that the model sees friendlier column names. The view decides what a term means.

Consider a travel company asking for "booked revenue." That phrase needs decisions:

  • Does revenue use booking date, departure date, or payment date?
  • Are cancelled bookings excluded?
  • How are refunds represented?
  • Which currency conversion rate applies?
  • Is the metric additive across every dimension?

A description such as "total revenue from bookings" does not answer those questions. It merely gives the ambiguity a nicer label.

The semantic view should capture the accepted definition and the valid join paths. That makes it closer to a versioned business contract than a prompt accessory.

This is also why I would not start from the agent. An agent called travel_assistant may need bookings today, customer value tomorrow, and disruption operations next month. If the semantic model copies the agent's current scope, every new use case pushes unrelated concepts into the same view.

Avoid one view per physical table

Creating one semantic view for every warehouse table feels tidy. It preserves the physical architecture and gives each object a manageable size.

It also asks the consumer to reconstruct the business model.

If fact_booking, fact_payment, dim_route, and dim_customer become four separate semantic views, where does "revenue by destination" live? Which object owns the join between bookings and payments? Which view defines whether a refund reduces booked revenue or appears as a separate measure?

Snowflake's own getting-started guidance begins with business entities, their relationships, metrics, and dimensions. It then maps those concepts to physical data and recommends starting with a simple star schema. That sequence is important. The warehouse tables support the model; they do not define its audience.

A useful semantic view may include several logical tables when they form one understandable analytical subject. For example:

The boundary is not "all travel data." It is the set of concepts needed to answer booking performance questions with consistent grain and joins.

Avoid one giant enterprise view

The opposite design is one semantic view that contains every table, metric, synonym, instruction, and verified query in the warehouse.

This removes the routing decision by making every concept available everywhere. It also creates a model that few people can reason about.

Large views accumulate ambiguous names. status may refer to a booking, payment, flight, customer account, or support case. Relationships multiply, and valid join paths become harder to distinguish from technically possible ones. A change to one business area requires evaluating a shared object used by everyone else.

There is a governance problem too. Different domains may have different owners, release schedules, and access rules. Putting them into one object couples those decisions. The result may be convenient for the first demo and awkward for every production change after it (the usual bargain).

I would split the model when one or more of these conditions appear:

  • The questions serve different business decisions.
  • The core facts have different grains.
  • The metrics are owned and approved by different teams.
  • The relationships between the subjects are optional or ambiguous.
  • The access boundary is different.
  • A change requires a separate evaluation and release cycle.

For a travel platform, that might produce views such as booking_performance, customer_value, and service_disruption. These are examples of business subjects, not a universal naming scheme.

Some questions will cross those boundaries. If cross-domain questions are frequent and have agreed semantics, that is evidence for a composed view designed for that purpose. It is not a reason to merge everything in advance.

Let routing remain routing

Snowflake's Cortex Analyst REST API accepts an array of semantic models or views. For each query, Cortex Analyst chooses the most appropriate one from the list. A client can therefore expose several focused views without asking the user to choose a data source before every question.

That capability gives us a useful separation:

Routing answers, "Which model can handle this question?"

The semantic view answers, "What do these business terms mean, and which SQL relationships are allowed?"

Combining those responsibilities makes both harder to test. When an answer is wrong, the team cannot easily tell whether the router chose the wrong domain, the view defined the metric incorrectly, or SQL generation failed within an otherwise correct model.

There is one limit worth making explicit. Selecting from multiple views does not magically create a governed join across them. Snowflake's API documentation says Cortex Analyst chooses the most appropriate view for a query. If a single question genuinely needs concepts from two domains, model and test that combined analytical path rather than assuming the agent will invent it safely.

Verified queries are tests, not decoration

Descriptions and synonyms help, but a semantic view needs executable evidence.

Snowflake supports verified queries that pair a natural-language question with expected SQL. Its Cortex Analyst evaluation runs generated SQL and compares the result with the verified query. During an evaluation, selected queries are removed from the temporary view so they cannot guide the generation they are supposed to test.

That is a useful design. It turns a familiar business question into regression evidence instead of another prompt example that always looks correct in the demo.

I would keep two sets:

Guidance set
Questions that teach common language and approved patterns

Evaluation set
Questions held out to detect wrong SQL and regressions
Enter fullscreen mode Exit fullscreen mode

The evaluation set should cover more than happy paths. Include common synonyms, ambiguous time periods, filters that previously failed, joins near the edge of the domain, and metrics that look similar but have different definitions.

For booking_performance, useful cases might include:

  • booked revenue for departures next month
  • payments received this month for bookings created earlier
  • cancelled passengers by route
  • refund amount without double-counting partial refunds
  • a question the view should decline because it belongs to service disruption

That last case matters. A reliable semantic boundary needs to say what it does not know.

Ownership matters more than view count

There is no correct number of semantic views. Three coherent views can be better than twelve, and twelve focused views can be better than one. Count is an outcome of the ownership model and question space.

For each view, I would record:

  • the business owner who approves metric meaning
  • the engineering owner who maintains mappings and relationships
  • the source models and expected grain
  • the questions it is designed to answer
  • the questions it must reject or route elsewhere
  • the verified-query guidance and evaluation sets
  • the access roles and release process

Then I would monitor how the model behaves in use. Snowflake exposes an administrator view containing Cortex Analyst requests across semantic models and views. That history can show questions that route poorly, common phrases missing from the model, and domains users try to combine.

Production usage should inform a change, not write directly into the semantic contract. A frequent query may reveal a missing synonym. It may also reveal that two departments use the same phrase for different metrics. Someone still needs to decide which interpretation is valid.

Start with one subject and make it boring

I would begin with one business subject that has an engaged owner, stable source data, and a small set of questions people already ask. Define the grain. Add the metrics and relationships needed for those questions. Build verified queries, keep some for evaluation, and measure the results.

Only then add another subject and routing.

The first success criterion is not that the agent can answer something impressive. It is that the same approved question produces the same correct result after the semantic view changes.

Design the views around business meaning. Let agents discover and route to them. When the interface changes, the definitions should remain useful. That is a much better test of a semantic layer than whether the first chatbot demo looked clever.

Top comments (1)

Collapse
 
omyvnss profile image
Om Yaduvanshi •

the "must reject" list is the part most people skip. everyone writes down what a view answers. writing down what it declines is what keeps it honest when someone asks "revenue by destination" and the answer quietly blends two grains.

verified queries as regression tests feels like the same muscle as event contracts. define the question, pin the answer, watch it drift.