Fabric IQ / hands-on / preview

Build your enterprise IQ

One shared language of your business that people, apps and AI agents all understand.

An agent can read your tables and still get your business wrong. In this sales model, 542 rows do not mean 542 orders. They mean 542 order lines across 32 orders. That distinction is exactly where I want an ontology to earn its keep.

I used the new Fabric ontology experience and its Ontology Agent to turn an existing Power BI semantic model into explicit business concepts, source-backed metrics and a shared sales rule. No new revenue formula. No duplicate data platform. And no pretending that a nice relationship diagram proves the numbers.

7entity types
6relationships
17source-owned metrics

What changes, and what does not?

A Fabric IQ ontology defines the business vocabulary: entities, properties, relationships, metrics, rules and their source mappings. The updated ontology experience extends that vocabulary with features such as namespaces, inheritance, shared properties and source-owned semantic-model measures.

I am using “ontology v2” as shorthand for that new experience, not as an API version. This walkthrough covers one sales domain. It is a useful starting slice of enterprise IQ, not proof that every application or agent in an organization automatically understands it.

SalesAnalytics_ModelData, relationships and existing DAX measures
EnterpriseIQ_SalesBusiness concepts, mappings, metrics and rules
Ontology AgentQuestions grounded in context, executed against the source

The ontology is not a replacement warehouse or a general-purpose query engine. Our sales data stays in its existing source. The source semantic model still owns the DAX. Graph materialization is optional; the schema diagram below is not evidence that an instance graph has been loaded.

Step 1

Prepare the source and permissions

I reused the SalesAnalytics workspace and its existing SalesAnalytics_Model. Everything in this example is AdventureWorks or similar synthetic data. We do not need a real-time stream to prove the business-context layer.

The agent acts with your identity. Ontology access does not grant access to the bound sources or bypass their security. I used my demo administrator account for setup, not as a recommended production access pattern.

Before prompting, know the grain. My source has seven tables, 69 columns and 17 measures. The fact table is at order-line grain; the order dimension represents the header.

The source-to-business mapping reviewed in this run
Source tableBusiness conceptKey
fact_salesorderSales Order LineSalesOrderDetailID
dim_orderSales Order HeaderSalesOrderID
dim_customerCustomerCustomerID
dim_productProductProductID
dim_salespersonSalespersonSalesPersonKey
dim_orderdateOrder Datedate_key
dim_shipdateShip Datedate_key

Your AdventureWorks transformation may use different names, row counts or keys. Substitute your actual model and check its relationships. The results in this article are a baseline for this demo, not universal AdventureWorks totals.

Step 2

Create the new ontology

In the workspace, select New item, search for Ontology (preview) and open it. Enter EnterpriseIQ_Sales, confirm the workspace and select Create.

New Ontology dialog. Annotation 1 marks the name, 2 the SalesAnalytics location, and 3 the Create button.
1. Name the new item. 2. Check its workspace. 3. Create it. Only this dialog is captured, not the surrounding tenant or browser.

Provisioning took roughly two minutes in my run. I waited for the item to finish rather than creating a second one. The portal then displayed You are in the new experience.

Use the portal path for this walkthrough. Microsoft documents that new items created through the Fabric UX use the new experience, while legacy API and CI/CD paths can still produce old-experience items. Reusing an older ontology JSON example is not the same experiment.

Step 3

Yes, use “Start with Ontology agent”

On the empty item, select Start with Ontology agent. This is the route I used, rather than manually drawing seven entities.

Cropped Get started cards with Start with Ontology agent outlined.
The highlighted card opens the agent. Import ontology is a different route.

Keep the agent in Plan mode. It can discover, draft, validate, explain and query, but cannot apply ontology changes. Act mode enables those writes.

Ontology Agent input showing the Plan and Act mode toggle, with Plan selected.
Check this toggle before sending the prompt. Drafting and applying are different operations.

This was my discovery prompt. It names the source, sets a boundary and gives the agent the business distinction it should not guess:

Prompt 1 / Plan mode
Build a sales ontology for the AdventureWorks demo using only SalesAnalytics_Model in this workspace. Stay in Plan mode: discover, draft and validate, but do not apply yet.

Reuse the model's seven tables and six existing relationships, calculated columns and all DAX measures as metrics. Preserve the source model and data unchanged.

Make the business meaning explicit: fact_salesorder is an order LINE, not one row per order; dim_order is the order header; dim_customer and dim_product describe the customer and product. Keep dim_orderdate and dim_shipdate distinct.

Use friendly names where possible, with clear source mappings and original stable identifiers. For sales questions reuse Total Sales, Total Orders and Avg Order Value; do not sum repeated header amounts or invent a new revenue formula.

Show the proposed entities, keys, relationships, metrics and validation warnings, and provide a canvas preview before applying.

A focused prompt matters more than a poetic one. This workspace also contains lakehouses, a warehouse and other experiments. “Use everything” would have been a very different instruction.

Step 4

Review meaning, not just green ticks

The agent discovered the complete model and returned seven entity types, six relationships and all 17 metrics. Its validation reported no warnings.

Agent-generated AdventureWorks preview card showing seven entities, six relationships, 17 metrics, line grain and distinct date roles.
The actual Plan-mode summary. In this run the agent returned a summary card, not a clickable canvas-preview action. Do not mistake that for a saved definition.

The documented agent flow can also expose a read-only canvas preview. Open it if offered and inspect properties, bindings and relationships there. The exact suggestions and preview presentation can vary.

My review focused on four things: the line key was SalesOrderDetailID, not the repeated order ID; all six source joins were represented; Order Date and Ship Date remained separate roles; and sales calculations referred back to existing measures.

Structural validation is not a finance sign-off. This source also has measures named Total SubTotal, Total Tax, Total Freight and Total Due that sum columns on the line fact. Header-level amounts can repeat across lines. Importing a measure does not certify that its aggregation is appropriate.

Read the generated descriptions too. A plausible phrase such as “allocated freight” is not evidence that an allocation actually happened upstream. Keep ambiguous semantics qualified until the source owner confirms them.

Step 5

Apply the reviewed draft

Switch the toggle to Act, then explicitly ask the agent to apply the scoped draft:

Prompt 2 / Act mode
Apply the validated AdventureWorks sales ontology draft now. Only update this EnterpriseIQ_Sales ontology.

Preserve all seven source table bindings, six source relationships and 17 source-owned metrics, friendly names and the distinct date roles as reviewed.

Do not modify any source model or data. Confirm the applied entity/relationship/metric counts and whether the definition was persisted.

The agent confirmed that the definition was persisted. The empty Get started page became the ontology canvas. I also read back the saved definition through the Fabric API: it contained the seven entity definitions, six entity relationships and source-linked measures. This was no longer just a chat proposal.

Saved ontology schema canvas with Sales Order Line connected to Customer, Sales Order Header, Product, Salesperson, Order Date and Ship Date.
The saved schema, cropped to the canvas. Sales Order Line is the central concept. Open the image for the original resolution. No instance graph materialization was performed.

“Publish” in this agent flow means saving the ontology definition in Fabric. It does not publish your data or this article to the internet.

Step 6

Inspect a metric instead of inventing revenue

Select Sales Order Line, open View Entity Type details, then find the Metrics section on Configure. This entity has 17 because the source measures live on fact_salesorder.

Search for Total Sales, open it and use Resolve underlying DAX in the Expression area. The first resolution was slower in my run. The returned expression was the existing source measure:

Metric source card showing SalesAnalytics_Model and the resolved expression SUM(fact_salesorder[LineTotal]).
Total Sales resolves to the source model's DAX. The ontology did not create a competing definition of sales.
Existing source measures / reference, not new definitions
Total Sales = SUM(fact_salesorder[LineTotal])
Total Orders = DISTINCTCOUNT(fact_salesorder[SalesOrderID])
Avg Order Value = DIVIDE([Total Sales], [Total Orders])

Ontology metrics proxy source measures. The source model owns the calculation; ontology adds context and a source link. Source changes are not automatically reflected everywhere: refresh the ontology when reviewing changed measures.

Step 7

Ask a business question, then read the query

Reopen Ontology agent from Home and return to Plan. Querying does not require Act mode. Ask for evidence, not just an answer:

Prompt 3 / Plan mode
Run a read-only post-create validation against the saved ontology and its bound SalesAnalytics_Model.

Across all available data, with no current-date filter, what are Total Sales, Total Orders and Avg Order Value? Reuse exactly those source measures.

Also report the sales order line row count, distinct SalesOrderDetailID count, first and last OrderDate. Show the DAX query actually executed and the returned values.

Explain why sales order line count is not order count, and why Order Date and Ship Date stay separate. Do not change the ontology or source. Do not infer currency.

The agent ran DAX and returned the same three business-metric values as my independent pre-build query against the source model.

Actual agent result: Total Sales 708690.153, Total Orders 32, Avg Order Value 22146.5673, 542 lines, 542 distinct line IDs and order dates on June 1, 2025.
The answer crop, without the surrounding conversation or internal identifiers.
CheckObserved resultWhat it proves
Total Sales708,690.153Matches the source measure baseline
Total Orders32Orders are not line-row counts
Avg Order Value22,146.5673Matches the existing source calculation
Rows / distinct line IDs542 / 542The selected line key is unique in this sample
Order-date range1 June 2025 onlyA current “last 30 days” filter would miss this sample

I have left the values in source units rather than inferring a business currency from formatting. This is also a small, single-day demo: it does not establish performance, seasonality or behavior across a production estate.

The DAX the agent actually executed
Run against the source semantic model
EVALUATE
ROW(
    "Total Sales", CALCULATE([Total Sales], REMOVEFILTERS()),
    "Total Orders", CALCULATE([Total Orders], REMOVEFILTERS()),
    "Avg Order Value", CALCULATE([Avg Order Value], REMOVEFILTERS()),
    "Sales Order Line Row Count", COUNTROWS('fact_salesorder'),
    "Distinct SalesOrderDetailID Count",
        DISTINCTCOUNT('fact_salesorder'[SalesOrderDetailID]),
    "First OrderDate", MIN('fact_salesorder'[OrderDate]),
    "Last OrderDate", MAX('fact_salesorder'[OrderDate])
)

The three metrics explicitly remove query filter context. This does not remove source security such as row-level security. The remaining checks run in the unfiltered standalone query shown here.

Three practical questions through Copilot

Then I switched to Act and asked the Ontology Agent three ordinary sales questions. Copilot executed DAX against SalesAnalytics_Model, using the ontology's Order Date, Customer and Product concepts. I ran equivalent DAX directly against the source model as an independent check. All returned rows and values matched.

QuestionCopilot resultIndependent DAX
Total Sales, Total Orders and Avg Order Value by Order Date year2025: $708,690.15; 32 orders; $22,146.57 average order value. 2025 was the only year returned.Exact match
Which five customers generated the highest Total Sales?Action Bicycle Specialists ($89,869.28); Metropolitan Bicycle Supply ($79,589.62); Bulk Discount Store ($74,160.23); Eastside Department Store ($65,683.37); Riding Cycles ($65,123.46).Same five customers, values and order
Which product categories generated the most Total Sales?Bikes ($574,611.56); Components ($111,075.73); Clothing ($16,087.72); Accessories ($6,915.14). The model contains four categories, not five.Same four categories, values and order

These are the prompts I actually sent in Act mode. You can copy them into your own Ontology Agent conversation:

Prompt: sales by year
Using the source-bound metrics in this ontology, show Total Sales, Total Orders, and Avg Order Value by Order Date year. Identify the year with the highest Total Sales. Use the canonical measures, not a line-row count or repeated order-header amount.
Cropped Copilot answer: 2025, Total Sales $708,690.15, 32 Total Orders and $22,146.57 Avg Order Value.
Copilot used the three canonical source measures. The independent query returned the same values. 2025 is the only Order Date year in this sample.
Prompt: top customers
Which five customers generated the highest Total Sales? Return each customer's CompanyName and Total Sales, sorted from highest to lowest. Use the Customer relationship and the canonical Total Sales measure.
Cropped Copilot answer ranking the five customer companies by Total Sales, with values matching the source-model DAX query.
The Customer relationship supports a useful ranking without manually writing a join or redefining Total Sales.
Prompt: product categories
Which product categories generated the most Total Sales? Show CategoryName and Total Sales, sorted from highest to lowest, and return the top five categories. Use the Product relationship and the canonical Total Sales measure.
Cropped Copilot answer ranking Bikes, Components, Clothing and Accessories by Total Sales.
The Product relationship returns four categories. Copilot correctly reports that the sample has fewer than the requested five.
The independent DAX checks

These queries use the same source measures and dimensions. The displayed dollar sign is the semantic model's format string, not evidence about a customer's business currency.

Measures by Order Date year
EVALUATE
SUMMARIZECOLUMNS(
    'dim_orderdate'[year],
    "Total Sales", [Total Sales],
    "Total Orders", [Total Orders],
    "Avg Order Value", [Avg Order Value]
)
ORDER BY 'dim_orderdate'[year]
Top five customers
EVALUATE
TOPN(
    5,
    SUMMARIZECOLUMNS(
        'dim_customer'[CompanyName],
        "Total Sales", [Total Sales]
    ),
    [Total Sales], DESC
)
ORDER BY [Total Sales] DESC
Sales by product category
EVALUATE
SUMMARIZECOLUMNS(
    'dim_product'[CategoryName],
    "Total Sales", [Total Sales]
)
ORDER BY [Total Sales] DESC
Step 8

Ask the ontology from Microsoft 365 Copilot

The same ontology can now be used from the native Microsoft 365 Copilot experience. This is not Copilot Studio: I published the Fabric Data Agent, kept Work IQ enabled, and selected EnterpriseIQ_Sales_Copilot from the Microsoft 365 Copilot Agent Store. The agent is backed by EnterpriseIQ_Sales, not by a loose prompt over the semantic model.

  1. Open Microsoft 365 Copilot with the account that has access to the Fabric workspace.
  2. Open Agents, choose EnterpriseIQ_Sales_Copilot, and keep Work IQ switched on.
  3. Ask a normal business question in English or Dutch.

For example, I asked: What were total sales by year? Copilot returned 2025: $35,854,355.90. I then asked which customers generated the most sales; the answer ranked the customers using the ontology's Customer relationship and the canonical TotalDue measure.

Microsoft 365 Copilot using EnterpriseIQ Sales Copilot returns total sales by year: 2025, 35,854,355.90.
The answer is produced in Microsoft 365 Copilot by the Fabric Data Agent backed by the ontology.
Microsoft 365 Copilot ranks the top customers by sales using EnterpriseIQ Sales Copilot.
The customer ranking is available without asking the user to know table names, joins, or DAX.

The Dutch route works as well. The same agent answered Welke klanten genereerden de meeste omzet? in Dutch and returned the same ranking, with localized numeric formatting.

Nederlandstalig antwoord van EnterpriseIQ Sales Copilot in Microsoft 365 Copilot met de topklanten op omzet.
Een Nederlandstalige vraag kan dezelfde governed ontology gebruiken.
Step 9

Move the sales rule out of the chat

A good prompt is useful. A business definition that disappears when the conversation ends is less useful. I added a rule to the ontology so its intended interpretation is stored with the concepts.

  1. In Explorer, expand Overview and select Rules.
  2. Select Create rule and enter Sales grain and canonical metrics.
  3. Paste the definition below.
  4. Select Add concept, then select Sales Order Line, Sales Order Header, Order Date and Ship Date on the Entity types tab. Save that selection.
  5. Select Save on the rule page. Reopen it to confirm the definition and links persisted.
Rule definition
Sales Order Line represents one order line, not an entire Sales Order Header. Sales reporting must use the source measures Total Sales, Total Orders and Avg Order Value. Do not use line row count as order count or sum repeated header amounts across lines. Order Date and Ship Date represent different business events and must remain distinct.
Saved sales-grain business rule with its definition and four linked ontology entity types.
The saved rule links the interpretation to the relevant business concepts, rather than leaving it only in an agent prompt.

A rule is context, not an execution engine. Ontology does not enforce this rule, block an incorrect DAX query or send an alert. Consumers must retrieve and use it. The new experience does not currently provide direct Activator integration. The metric test above ran before this rule was added, so it is not evidence that the rule changed the agent's behavior.

The preview boundaries that matter

Ontology Agent is not the same as Fabric Data Agent. I tested the agent inside the ontology item. The current troubleshooting documentation lists a known issue with a separate Data Agent consuming an ontology that uses semantic-model bindings. I did not connect the existing sales Data Agent and will not claim that path works.

The conversation is temporary. During preview, refreshing the page or closing the tab ends the agent conversation; a conversation also cannot continue beyond 24 hours. Save useful prompts and persist reviewed definitions. Do not treat chat history as version control.

Check your own rollout. This was tested on 17 October 2026. The item, agent and documentation are preview surfaces. Labels, suggestions and availability can change. If the new experience or agent is missing, check tenant settings, permissions and current known issues before falling back to legacy instructions.

For a different Fabric IQ use case, my practical guide to Plan in Microsoft Fabric covers planning input and writeback. That is a separate job: an ontology supplies business context, not an editable planning store.

Reproduce and clean up

To reproduce the workflow, use your own seven-table sales model, the mapping above, the three setup prompts and the three Copilot query prompts. Run the displayed DAX against your source model and compare your totals, key uniqueness, relationships and date range. All screenshots here are from the executed demo, cropped to the relevant controls or result.

For cleanup, delete only the new EnterpriseIQ_Sales ontology after checking its consumers. Keep SalesAnalytics_Model and its underlying data. No source cleanup or model rollback is required by this walkthrough. Do not disable tenant settings or delete a shared workspace just to remove this demo.

My take

The interesting part is not that an agent can draw a star-shaped diagram. We have had diagrams for a while.

It is that we can carry an existing semantic investment into a reusable business vocabulary, keep the calculation owner explicit and put the awkward distinctions where consumers can find them. An order line is not an order. Ship date is not order date. Imported does not mean audited.

Start with one domain, preserve the trusted calculations and make the agent show its query. Shared language is useful only when it survives contact with the numbers.

Sources and further reading

First-party documentation checked on 17 October 2026. Where older troubleshooting text differs from the updated overview, verify the current experience and your live behavior rather than mixing the two models.

  1. Ontology overview: the new experience, virtual context layer and optional graph execution.
  2. Use the Ontology Agent: discovery, Plan/Act, previews, queries and conversation lifetime.
  3. Generate from semantic models: permissions, source mappings and review requirements.
  4. Define metrics: source ownership, DAX resolution and refresh behavior.
  5. Define business rules: concept links and the distinction between context and enforcement.
  6. Troubleshooting and current limitations: permissions, queries and the semantic-model-binding Data Agent issue.
  7. Required tenant settings.

Tags: Fabric IQ · Ontology · Power BI · Copilot · Semantic model