top of page

Power BI Semantic Models as Accelerators for AI-Driven Insights

  • Jihwan Kim
  • Nov 8
  • 5 min read

In this writing, I’d like to share how I started learning and experimenting with Copilot and AI-driven features in Power BI and Fabric — and what I discovered about the role of semantic models in making them work effectively.


Prerequisites

Before jumping into it, here’s the setup I used for experimenting with Copilot and AI-driven insights in Power BI and Fabric.

  • Power BI Service (Fabric workspace) — The experiments were all performed in a Fabric-enabled workspace, since Copilot and Direct Lake features require a live cloud connection.

  • Capacity — The workspace is running on an F2 capacity, which supports semantic models with Direct Lake storage mode and Copilot integration.

  • Copilot for Power BI — Make sure Copilot is enabled in the tenant and that the workspace is in a supported region. (Microsoft Learn – Copilot in Power BI)

  • Semantic Model Requirements — The model used in this blog post includes both Direct Lake and Import tables, connected to OneLake and designed to represent a simple sales scenario with fact and dimension tables.

Having these prerequisites in place is important — otherwise, Copilot might not respond or may produce limited functionality in the environment.



From Semantic Models to AI Models

When Microsoft introduced Copilot for Power BI, it seemed like a major leap — AI could now write DAX, build visuals, and summarize data in natural language. But after a few experiments, I realized something simple yet critical: Copilot’s accuracy depends entirely on my semantic model.

If my relationships are ambiguous or my measures aren’t clearly defined, Copilot’s responses reflect that confusion. When the model is well-structured, AI explanations sound almost like an experienced analyst.




How Copilot Uses Semantic Models

Behind the scenes, I think Copilot doesn’t “read” raw data — it queries the semantic model metadata: tables, relationships, measures, and hierarchies. When I ask Copilot to “show total sales by region”, it looks for objects that match Sales, Region, and known aggregations.


In this example, I’m using a sample semantic model to experiment with Copilot and AI-driven insights. The model itself is simple, but it demonstrates a Direct Lake + Import composite structure, which makes it ideal for testing modern Fabric capabilities.

This semantic model is live-connected to the Power BI Service, since the Direct Lake table requires a web-connected workspace to query data directly from OneLake. By combining Direct Lake for the fact table and Import for the dimension tables, the model reflects a realistic hybrid scenario — lightweight, responsive, and ready for AI-powered analysis (Sample shown below).


ree


And, for example, when I typed:


“show total sales by region”

ree

ree



“Write a measure for Year-over-Year Sales Growth”

Copilot generated a correct DAX formula using my existing [sales:] measure because the semantic model had a clear relationship with my Date table.


ree

ree

ree




The Examples for the Messy Model

The examples for the messy model and the result of it look like below. At first glance, the query results appear correct — the numbers make sense, and the aggregation logic seems valid. But when I looked closer at the generated DAX code, I realized the model was doing much more work than it should have been.


I tested two versions of the same model:

  1. Clean Model – with clear relationships and the measure called [Sales:]. (example above)

  2. Messy Model – missing some relationships and using a differently named measure [Revenue:] instead of [Sales:]. (example below)


ree


“show total sales by region”

In the messy model, the relationship between the fact table (factinternetsales) and the sales territory dimension (dimsalesterritory) was intentionally removed.

When I asked Copilot to “show total sales by region”, it still managed to generate a valid DAX query — but by using a workaround with the TREATAS( ) DAX function to bridge the tables manually.


Copilot automatically created a virtual relationship by collecting the region keys and applying them in the CALCULATE function using TREATAS.


ree

ree


The output looked correct:

each region’s total sales aggregated properly, even though the physical relationship was missing.



What Happened Under the Hood

Copilot added a note in the generated DAX explaining exactly what it did:

“There is no active relationship between dimsalesterritory and factinternetsales in the provided schema, so we explicitly map region keys to the fact table using TREATAS inside the measure-like expression.”

That single line showed how Copilot compensated for the model gap. It inferred the missing logic from the metadata — a clever move, but also a reminder that AI was fixing a modeling problem that shouldn’t have existed.




“Write a measure for Year-over-Year Sales Growth”

More Complex Example — Year-over-Year Growth

I then went one step further and asked Copilot to create a Year-over-Year Sales Growth measure, but again, in a model where factinternetsales and dimdate were not related.


Copilot generated the following DAX pattern, dynamically creating temporary bindings for the date table and prior-year context using TREATAS():


When executed, the query produced accurate results:



ree

ree



The results were numerically correct — but technically fragile. At first glance, the output looked perfect: the total sales values by region and year aligned with expectations. However, the underlying DAX code told a different story.

Because the model lacked explicit relationships, Copilot had to infer logical connections between tables using the TREATAS() function and temporary variable bindings.


That approach worked for a one-time query, but it introduced hidden dependencies that would be difficult to maintain in a real production model.


The DAX it generated was verbose and tightly coupled to inferred keys — meaning that even a small schema change, like renaming a column or adjusting a relationship, would break the logic. Performance tuning would also become harder, since query folding and caching optimizations rely on explicit model metadata, not on dynamically mapped keys.

In short, the result was correct by coincidence, not by design. It reminded me that AI can compensate for modeling flaws, but it shouldn’t have to. A strong semantic model ensures stability, performance, and transparency — while Copilot’s dynamic DAX generation should remain a tool for acceleration, not correction.




What I Learned

This test showed two important lessons:

  1. Copilot is smart enough to compensate for modeling gaps, but doing so increases query complexity and maintenance risk.

  2. A clean semantic model makes AI smarter. When relationships, naming, and measures are properly defined, Copilot doesn’t need workarounds — it writes clean, efficient DAX instantly.

In other words, AI performs better when the model doesn’t need AI to make workaround.



Closing Thoughts

Copilot’s ability to reason through missing relationships is impressive, but it shouldn’t be the default. These tests reinforced a key takeaway for me: semantic models are still the foundation of accurate, explainable AI.

A well-structured model makes my AI assistant more reliable.



I hope this helps having fun in exploring, experimenting, and improving your semantic models for AI-driven insights in Power BI and Fabric.

Comments


bottom of page