Build a Fabric Ontology

The useful test of an ontology is whether it helps an agent answer a business question using the right entities, relationships, and calculations. A diagram full of connected objects is only the beginning.

Microsoft’s updated Fabric ontology experience gives us more to work with: semantic-model measures, richer metadata, natural-language rules, namespaces, inheritance, and an agent that can help create and query the model. This walkthrough builds a small customer-operations ontology and checks it against a result we can calculate independently.

The question is deliberately specific: which customers have an open, high-priority service case at least seven days old, and how much open order value belongs to those customers? The example includes two qualifying cases for one customer, so a careless join can double the commercial amount. That makes the exercise useful for testing meaning as well as connectivity.

What we are building

The main route uses Power BI Desktop to prepare a small semantic model, then the Fabric portal to generate and enrich an ontology. Queries run through the built-in ontology agent. The separate Fabric data-agent integration currently has a documented issue with new-experience ontologies, so it is an optional extension rather than a dependency of this exercise. All ontology capabilities discussed here are preview features.

The example has three entities and two one-to-many relationships.

EntityMeaningIdentifier and connection
CustomerA commercial customer in this demonstrationCustomerID uniquely identifies each customer
OrderOne customer order with a value and statusOrderID is unique and CustomerID connects it to Customer
ServiceCaseOne recorded service issueCaseID is unique and CustomerID connects it to Customer

Keep the responsibilities clear. The semantic model owns the calculations and filtering behavior. The ontology supplies business definitions and source mappings. The agent interprets a question and uses an appropriate source query. Optional graph materialization is unnecessary for this example; current graph projection does not support entities bound to semantic models.

1 Prepare the workspace and sample data

Use a Fabric-enabled workspace and capacity that support the ontology and Copilot experiences in your region. You need permission to publish the semantic model and create an ontology, plus Read and Build access to the model. Ask the Fabric administrator to enable Users can create Fabric items and Users can create ontology preview items, along with the applicable Copilot settings. Contributor or higher is required for ontology-agent changes.

The sample is illustrative, with a fixed snapshot on October 17 2026. AgeDays is a stored snapshot value, so rerunning the exercise next month produces the same expected answer. In a production model, the data owner must define how that age is refreshed and whether it means calendar days, business days, or elapsed hours.

Save the following as three UTF-8 CSV files. The accompanying example folder contains the same files.

Customer.csv

CustomerID,CustomerName
C001,Harbor Supply
C002,Summit Goods
C003,Cedar Office

Order.csv

OrderID,CustomerID,AmountUSD,Status
O101,C001,120000,Open
O102,C001,30000,Open
O103,C002,80000,Open
O104,C003,50000,Closed

ServiceCase.csv

CaseID,CustomerID,Priority,Status,AgeDays,SnapshotDate
S101,C001,High,Open,9,2026-10-17
S102,C001,High,Open,7,2026-10-17
S103,C002,High,Open,6,2026-10-17
S104,C003,High,Closed,12,2026-10-17

In Power BI Desktop, import the files through Get data and Text or CSV. Keep identifiers as text, set AmountUSD to a suitable numeric type, AgeDays to whole number, and SnapshotDate to Date. Name the tables Customer, Order, and ServiceCase.

Create single-direction relationships from Customer[CustomerID] to Order[CustomerID] and ServiceCase[CustomerID], with Customer on the one side. Do not join Order directly to ServiceCase. Multiple orders and cases for a customer would otherwise create a multiplication problem if flattened carelessly.

2 Establish the calculations before adding AI

Create these two measures separately through New measure. Put the first on Order and the second on ServiceCase.

Open Order Value USD =
COALESCE(
CALCULATE(
SUM('Order'[AmountUSD]),
'Order'[Status] = "Open"
),
0
)
Aged High Priority Cases =
COALESCE(
CALCULATE(
COUNTROWS(ServiceCase),
ServiceCase[Status] = "Open",
ServiceCase[Priority] = "High",
ServiceCase[AgeDays] >= 7
),
0
)

Add descriptions explaining the snapshot, the inclusive seven-day threshold, and the exclusion of closed records. Create a table visual with customer name and the two measures. It should show:

CustomerOpen Order Value USDAged High Priority Cases
Harbor Supply1500002
Summit Goods800000
Cedar Office00

These expected values come from the supplied rows and have been checked independently of Fabric. The walkthrough describes a reproducible build; it does not report a completed tenant deployment.

Publish the model to the target workspace as CustomerOperations. Retain this small report as the baseline. If the agent later returns a different number, you now have a defined calculation and a known result to investigate.

3 Generate and inspect the ontology

In Fabric, select Generate Ontology from the semantic-model ribbon or its more-actions menu. Name the item CustomerOperationsOntology. Generation carries tables, columns, relationships, and measures into the ontology structure. Inspect Properties, Relationships, and Metrics on each entity, and review keys and relationship bindings explicitly.

For this sample, the completed model should have three entities, with Customer linked separately to Order and ServiceCase. Confirm that OrderID and CaseID identify records, rather than selecting CustomerID as the key for either child entity. Repeated CustomerID values in those tables are intentional.

Open Ontology agent in Plan mode and use this review prompt:

Review CustomerOperationsOntology against the CustomerOperations
semantic model in this workspace. Make no changes.
Expected entities are Customer, Order, and ServiceCase. CustomerID
is unique only in Customer. OrderID identifies Order and CaseID
identifies ServiceCase. Each child references CustomerID.
List each entity's source, identifier, properties, relationships,
and metrics. Identify missing or ambiguous bindings. Confirm that
the existing measures Open Order Value USD and Aged High Priority
Cases remain available. Do not invent replacement calculations.
Return a concise discrepancy list and a proposed correction for
each discrepancy. Stop for clarification if source evidence is
insufficient to establish a relationship.

Review the proposed changes in the canvas. If a correction is needed, switch to Act mode and request only the approved correction, then inspect the result. Plan mode permits exploration and queries; Act mode applies changes. The prompt supplies a contract the proposal can be checked against, instead of asking the agent to make the ontology generally better.

4 Add the language users actually use

Select Customer, open View Entity Type details, and use the Configure tab’s Metadata section. Add a description such as: A commercial customer identified by CustomerID in the demonstration source model. Add Client as an entity synonym. For ServiceCase, Ticket is a useful synonym. Save with Update. Properties and relationships support descriptions and additional metadata, but their metadata editor does not support synonyms.

Use the following proposed descriptions and metadata for this example:

ObjectContext to record
Customer.CustomerIDStable demonstration customer identifier used to relate orders and cases
Order.AmountUSDOrder amount in USD before filtering by status; unit metadata is USD
ServiceCase.AgeDaysCalendar-day age recorded at the snapshot; threshold includes exactly seven days
ServiceCase.SnapshotDateDate on which the recorded case age was calculated
Customer to ServiceCase relationshipConnects a customer to individual service cases; several cases can belong to one customer

This is where a model starts to become useful beyond the team that created it. The descriptions explain units, grain, and time semantics that column names alone cannot establish. A tag such as owner or sensitivity is descriptive metadata; configure actual permissions separately.

5 Preserve the measures and record the business rule

Inspect the Metrics section on Order and ServiceCase. Each metric should point to the intended measure and source model. Ontology metrics retain a source connection rather than becoming a second independent implementation of DAX. Viewing the original expression through Resolve underlying DAX requires write permission on the source model, and source changes require an ontology refresh.

For this exercise, leave the formulas owned by CustomerOperations. If the organization changes what qualifies as an aged case, change the source measure under its normal review process and refresh the ontology before retesting.

Then open Explorer, Overview, and Rules. Create a rule called Customer service attention with this definition:

A customer requires service attention in this demonstration when
at least one linked ServiceCase has Status Open, Priority High,
and AgeDays greater than or equal to 7 at the recorded snapshot.
Closed cases do not qualify. Report open order value once per
customer using the governed Open Order Value USD measure.
This condition identifies a review queue; it does not authorize
customer communication or changes to source records.

Link it to Customer, ServiceCase, the relevant case properties, and their relationship. Add owner and effective-date metadata, then save. Rules are natural-language definitions available to consumers; ontology does not execute them.

There is an additional current limitation: Microsoft’s documentation says ask_ontology does not yet consider stored rules in its response, although rule listing is available through MCP. We therefore make the qualifying calculation explicit in the measure and test prompt. Saving the rule documents the agreed meaning; successful execution must still be demonstrated.

6 Ask a question with a result you can verify

Use Plan mode for the query. Supply this prompt:

Using CustomerOperationsOntology and its CustomerOperations
semantic model, return customers whose existing Aged High Priority
Cases measure is greater than zero.
For each qualifying customer, return CustomerID, CustomerName,
Aged High Priority Cases, and Open Order Value USD. Use the
existing measures and identify their source model. Show the DAX
query and describe the applied filters.
This sample uses the October 17 2026 snapshot. A qualifying case
is Open, High priority, and AgeDays >= 7. Count each order once;
multiple service cases must not multiply order value. Do not
change the model, contact customers, or update any records.
If a required binding or measure is unavailable, identify it
instead of substituting an inferred calculation.

The expected answer is Harbor Supply, customer C001, with two qualifying cases and USD 150000 in open order value. Summit Goods has an open high-priority case, but it is only six days old. Cedar Office’s case is closed.

One valid reference query against the source semantic model is:

EVALUATE
FILTER(
SUMMARIZECOLUMNS(
Customer[CustomerID],
Customer[CustomerName],
"OpenOrderValueUSD", [Open Order Value USD],
"AgedHighPriorityCases", [Aged High Priority Cases]
),
[AgedHighPriorityCases] > 0
)

The agent need not generate identical DAX. It must preserve the intended semantics. A USD 300000 answer for Harbor Supply is a useful failure signal: the two cases may have duplicated the order total. An answer that excludes the seven-day case has applied the wrong boundary.

Keep a small evaluation record containing the question, generated query, result, source model, test identity, ontology version, and observation time. Include an ambiguity test such as Which clients are at risk. The preferred behavior is to clarify what kind of risk is meant, or explicitly limit the answer to the defined service-attention condition.

7 Extend the model only where the domain needs it

Namespaces can separate concepts that have different owners or meanings. Select + Namespace, create CustomerOperations, and assign the relevant entities and relationships through their configuration pages. [9] For a larger implementation, sales and finance might retain distinct Customer concepts until the business agrees how they relate. Renaming them to match would not resolve the underlying disagreement.

Inheritance is useful when one type is genuinely a specialization of another. If your real domain includes CommercialCustomer and IndividualCustomer, each can derive from Customer through Add entity type, Additional configuration, and Choose entity to inherit from. Current documentation specifies single-parent inheritance. Derived types need their own bindings and entity-level metadata; ordinary relationships are not inherited.

The three sample entities do not need that hierarchy. Customer, Order, and ServiceCase are different kinds of things, so their connections should remain relationships. Also test inherited-instance queries explicitly: Microsoft currently lists problems returning child instances through parent queries in the ontology agent and MCP.

You can later ask the ontology agent to incorporate another related semantic model. Review any reconciliation of customer identities and preserve the source measures. A shared ontology does not imply that every consuming connector can execute a federated query. Establish a new expected result before introducing the second model.

8 Save a version and connect the intended consumer

Open Version history and create a named version such as Customer operations verified v1. Record the source model, snapshot, expected USD 150000 result, and any unresolved limitations. Versions are manually created definition checkpoints. Keep the baseline report and evaluation record with the release so another maintainer can reproduce the checks.

For an external MCP client, the ontology-specific endpoint uses the workspace and ontology item identifiers:

https://api.fabric.microsoft.com/v1/mcp/dataPlane/workspaces/<workspace-ID>/items/<ontology-item-ID>/ontologyEndpoint

Microsoft documents adding that URL as an HTTP MCP server in VS Code, then completing interactive sign-in. The ontology MCP path currently requires paid F2 or higher, or eligible P1 or higher capacity with Fabric enabled; service-principal access has a known issue. After connecting, inspect the available tools and repeat the same test before broadening the task.

The generally available endpoint at fabriciq.svc.cloud.microsoft serves Power BI reports and semantic models and currently excludes ontologies. It is a different integration. Select the endpoint according to the source the agent actually needs.

Foundry IQ provides another documented preview path: create a knowledge base, choose Fabric IQ, select the ontology through OneLake catalog, and attach the knowledge base to a Foundry agent. Use the same expected result there. Adding policy documents or Work IQ context is a separate design step, with its own access and evidence requirements.

Diagnose the failure at the right layer

SymptomFirst check
An entity or relationship is missingInspect generated definitions, identifiers, and bindings before changing the prompt
A governed number is wrongRun the source measure and compare filters, grain, and duplicate rows
A rule appears to be ignoredConfirm the consumer retrieves and applies it; stored rules are not an execution engine
A model change is absentRefresh ontology metrics and retest against the source
A Fabric data agent cannot add the ontologyCheck the documented new-experience issue before redesigning the ontology
Different users receive different resultsExamine source permissions and row-level restrictions with each user’s identity

The last connection deserves particular care. Fabric data-agent ontology context routes questions to underlying sources; it does not promise cross-source joins. Its semantic-model grounding behavior also differs from the built-in ontology agent. Test the chosen consumer instead of assuming that a successful ontology-agent answer transfers unchanged.

The completed example gives you a source calculation, a maintained business definition, an ontology with explicit context, and a repeatable question with a known answer. Preserve those pieces as you extend the domain. The most useful ontology is one that another team can consume, test, and maintain without having to rediscover what the original author meant.

Unknown's avatar

Author: Jason Miles

A solution-focused developer, engineer, and data specialist focusing on diverse industries. He has led data products and citizen data initiatives for almost twenty years and is an expert in enabling organizations to turn data into insight, and then into action. He holds MS in Analytics from Texas A&M, DAMA CDMP Master, and INFORMS CAP-Expert credentials.

Leave a Reply

Discover more from EduDataSci - Educating the world about data and leadership

Subscribe now to keep reading and get access to the full archive.

Continue reading