Future Proof Datasets

The integration of AI into data analytics has been a game-changer, but simply plugging an AI assistant into your reports isn’t a magic fix. When it comes to preparing semantic models for AI, the old adage rings true: garbage in, garbage out. If you don’t provide your AI with the proper context, it won’t give you the useful answers.

Think of Copilot like onboarding a new employee. Give them a proper manual, explain how things work, and they’ll do the job well. Leave them to figure it out alone, and the results will be inconsistent at best.

We tested garbage in, garbage out principle – comparing two versions of the same semantic model, one prepared for AI and one left as-is. The difference was significant.

The results justified our efforts in preparing our semantic models for AI; making them future proofed.

For organisations running Kinetic on‑premise, whether in their own data centre or a hosted environment, this shift raises important questions about long‑term support, security, and strategic planning. This article outlines what’s changing, what it means for customers, and the practical paths forward.

Prepped vs. Unprepped: The Night and Day Difference

When interacting with business users, an AI needs to understand intent, navigate ambiguity, and pull the exact right data. Here is how our prepared models outperformed the baseline models across several scenarios:

1. Explaining Logic Clearly:

We asked both models: “How is the Invoice Value measure calculated?”. Both gave way different answers.

The AI-prepared model returned a clear, business friendly, accurate description of the measure because we had instructed it to do so.

Checking the DAX logic confirmed it was exactly right output for a business user.

The unprepared model completely misread the question and returned a long table of individual invoice details with values and discounts — technically data, but completely useless for the question asked.

2. Using the Correct Measure:

When asked about invoice sales, the AI-prepared model correctly reached for the Invoice Value measure rather than confusing it with related measures like Invoice Value MTD, YTD, Last Year, or Invoice Difference.The unprepared model had no way to distinguish between them.

3. Clearing Up Ambiguity:

Business questions are rarely perfect. We asked both models about job cost.

The AI-prepared model responded by asking a clarifying question: “Do you mean actual or estimated job cost?” — exactly the right response when the question is ambiguous. The unprepared model simply returned estimated job cost without acknowledging that any ambiguity existed.

4. Looking at the Right Data:

We asked both models for the balance of an account for a fiscal period.

The AI-prepared model asked the right follow-up questions: Which Book ID should it use? Is the user looking for the period-end balance or the cash movement during the period?
The unprepared model was lost entirely, searching the wrong tables and measures.

I asked same follow up question from both semantic models for fair comparison but still the unprepared model failed to even find the account asked for.

5. Avoiding Blind Assumptions:

We asked both models about pending invoices.

The AI-prepared model returned both customer and supplier pending invoices, understanding the question could apply to either. The unprepared model assumed we only cared about customer invoices.

6. Guiding Users Toward the Right Prompt:

We asked both models about the highest-selling order.

The AI-prepared model understood we meant sales value and also recognised an ambiguity in our data: we have two perspectives on sales — invoice sales and order sales — so it asked which one we wanted. It successfully directed the user to the right prompts. The unprepared model blindly suggested invoice sales without addressing correct ambiguity.

7. Understanding the Data’s Date Range:

We asked both models a question that fell outside the available date range of the dataset.

The AI-prepared model responded directly that there are no sales in the current year. Simple, accurate, helpful. The unprepared model linked the issue to a possible data model misconfiguration — despite the fact we have a proper central date table. It didn’t recognise the question was simply out of range.

8. Understanding the Data’s Date Context:

We asked both models about highest decrease in sales. The AI-prepared model asked for a date range clarification first — decrease compared to which periods? The unprepared model used an existing year-over-year difference measure directly, which returned nothing because no date filter was in context.

when given the full prompt: “Which parts had the highest decrease in invoice sales in 2024 compared to 2023?”

AI prepared model generated correct DAX that explicitly filters by year and calculates the drop amount properly.

// DAX query generated by Fabric Copilot with "Which parts had the highest decrease in invoice sales in 2024 compared to 2023?"
// Parts with highest decrease in Invoice Value in 2024 vs 2023 (top 10 by drop amount)
DEFINE
  // Invoice value per part for 2024 and 2023
  VAR _PartInvoiceByYear =
    SUMMARIZECOLUMNS(
      Part[PartNum],
      Part[PartDescription],
      "Invoice 2024",
        CALCULATE(
          [Invoice Value],
          'Date'[Year] == 2024
        ),
      "Invoice 2023",
        CALCULATE(
          [Invoice Value],
          'Date'[Year] == 2023
        )
    )
  // Add absolute drop amount = 2023 - 2024
  VAR _PartInvoiceDrop =
    ADDCOLUMNS(
      _PartInvoiceByYear,
      "Drop Amount",
        [Invoice 2023] - [Invoice 2024]
    )
EVALUATE
  // Keep only parts where 2024 < 2023, take top 10 by largest drop
  TOPN(
    10,
    FILTER(
      _PartInvoiceDrop,
      [Drop Amount] > 0
    ),
    [Drop Amount],
    DESC
  )
ORDER BY
  [Drop Amount] DESC,
  Part[PartNum] ASC

Calculation check of unprepared model answer:

// DAX query generated by Fabric Copilot with "Which parts had highest decrease in sales?"
// Parts with the highest decrease in invoiced sales value vs last year.
// Uses [Invoice Value Last Year Difference] = [Invoice Value] - [Invoice Value Last Year].
// Negative values indicate a decrease. We return the 10 parts with the largest (most negative) drop.
DEFINE
  // Summary of invoice value and YoY difference per part
  VAR _PartSalesSummary =
    SUMMARIZECOLUMNS(
      'Part'[PartNum],
      'Part'[PartDescription],
      "Invoice Value", [Invoice Value],
      "Invoice Value Last Year", [Invoice Value Last Year],
      "Invoice Value Difference", [Invoice Value Last Year Difference]
    )
  // Keep only parts with a decrease in sales (negative difference)
  VAR _PartsWithDecrease =
    FILTER(
      _PartSalesSummary,
      NOT ISBLANK([Invoice Value Difference]) &&
      [Invoice Value Difference] < 0
    )
  // Top 10 parts with the greatest decrease (most negative difference)
  VAR _TopDecreases =
    TOPN(
      10,
      _PartsWithDecrease,
      [Invoice Value Difference],
      ASC
    )
EVALUATE
  _TopDecreases
ORDER BY
  [Invoice Value Difference] ASC,
  'Part'[PartNum] ASC

Even when given the exact same prompt as the AI-prepared model, it still failed.

We eventually got the unprepared model to produce a correct answer, but only by being very explicit about the calculation: “Show me invoice sales by part, split by 2024 and 2023, sorted by highest decrease in yearly sales.”

Data descriptions

To get these results, we didn’t just organize the data; we enriched it. We added detailed descriptions to every item in the semantic model. By pulling descriptions straight from the Epicor data dictionary, Copilot was able to deeply understand the context of the data.

The Payoff: A Seamless Reporting Experience

Once the heavy lifting of preparing the data is done, the everyday benefits for users are massive. This preparation works across any form of Copilot interacting with our reports, whether in the Power BI app, standalone Copilot, or Power BI services.

Other Features Worth Knowing:

Summarize Complex Visuals:

If a visual isn’t clear, hit the Copilot summary icon in the top right. It will explain what the visual shows — and it works across filter states too.

Apply Filters Painlessly:

Instead of manually applying filters across report pages, you can ask Copilot to do it. It applies the filter and offers a Keep filters option to save your selection.

Copilot can also summarise all pages of a report under a given filter.

Standalone copilot does summary even better than the report copilot.

Final Thought

The work you put into preparing your semantic model pays off across every form of AI interaction with your data. It’s not just about getting better answers, it’s about getting answers you can actually trust.

Thanks to Microsoft’s Chat with Your Data in a Day and Chris Webb’s blog, which guided much of what we applied here.

Haider Shah

Power BI Developer

Haider is a Power BI Developer at Blue Sky ERP