Provisa / Ontology

Why your AI agent gives different answers to the same question

Ask an assistant how much revenue came from enterprise clients last quarter. Then ask what enterprise customers spent over the same three months. To you it's one question. The agent may answer it from two different tables, or with two different definitions of revenue, and nothing in either answer tells you which one it used.

An ontology enriches how people and automation understand your data, and how that data connects to the concepts, synonyms, policies, regulations and processes of the business. People read it in the UI and in reports, agents over MCP, and OWL and RDF tools over SPARQL, and each uses it to reason about definitions and data. What reduces variation most, though, is taking the reasoning out of the agent's hands where an answer must be exact: derived views, code resolvers and commands put business logic in the data estate, where every agent gets the same result.

The hidden step

Somewhere inside the agent's reasoning, one step turns your words into a query. Its technical name is text-to-SQL. In a copilot or a reasoning agent you rarely see it run. To write the query, the agent has to decide what your words mean, and the only evidence it has is the names of tables and columns.

Names are weak evidence. "Revenue" might be order_total, net_amount, or order amounts less refunds. "Client" and "customer" are the same thing in one domain and different things in another. "Churn" appears in no column at all; it's a rule someone wrote down once. Each time the agent meets one of these words it guesses again, so a reworded question gets a fresh guess. A better model guesses more fluently. It still guesses from the same names.

Fix the names and descriptions first

Since the agent reads names, start with the names. Many sources do a poor job of describing themselves, and some do none at all: a table called tbl_cust_seg, a column called usr_nm, no description anywhere. Provisa lets you correct that without touching the source, and it is often the largest single gain you can make.

  • Descriptions. Give every table and column a description in the table form, or have AI draft one for you to edit. The description appears in the API schema, in the data catalog, in the table and column listings an agent reads over MCP, and in AI-assisted query generation.
  • Aliases. Rename tbl_cust_seg to customer_segments and usr_nm to user_name. The alias is the name every query language uses, and an agent sees the alias in place of the physical name.
  • Naming conventions and rules. Set how names are cased per source or per table, and strip a prefix such as prod_pg_ from every table's GraphQL name with one rule.
  • Relationships. Register how tables join, so an agent joins along paths your domains agreed.

Good metadata also seeds the ontology. A draft term follows a column's alias, so renaming usr_nm to user name fixes the term along with the column.

Where names fall short, a few simple primitives

Some meaning no name can carry. "Revenue" spans several columns, "client" and "customer" are one idea under two words, and "churn" is a rule. Provisa gives your organization a place to write down what its words mean and where the data for each one lives, and gives the agent a way to read that before it writes a query.

Terms, and the relationships between them

A term is a word your organization uses, with a definition. You don't start from a blank page: every column name becomes a draft term, so cust_id, customerId and CUSTOMER_KEY all land on customer. You add the words no column carries, such as "revenue" or "churn". Typed relationships connect terms. "Client" can be a synonym of "customer", "enterprise customer" a kind of customer, and "revenue" can have order amount and refund amount as its parts.

Bindings

A binding ties a term to the tables or columns that hold its values. customer binds to sales.customers and crm.contacts, and customer email to the email column of each. A term with no binding of its own, like "revenue", reaches data through the terms it relates to.

Approval

People set a term's status. Every term starts as a draft. A steward approves it once it has a definition the organization agrees on. Deprecating and retiring a term are steward decisions too, each with a reason, and a retired term hands its columns to the term that replaces it.

Grounding

Grounding is computed, never set. A term is grounded when a path from it leads down to data. Its chip reads grounded when a path gets there without passing through a draft term, and ~grounded when every path still waits on a term nobody has approved. A term with no path to data gets no chip. Status and grounding sit side by side, so an approved term that reaches nothing stands out.

Two kinds of search

Term discovery answers "what do we mean by active customer?" It returns the term, its definition, its status and the terms around it. Data discovery answers "where is the data about active customers?" It searches table and column metadata and the terms together, and returns the tables and columns either one leads to, each with the route that found it.

Table and column metadata, curated as above, stays the starting point. Terms add meaning and routes where the names fall short, and a table no term reaches is as easy to find as it was before. Terms never decide who may read data. Grants, row rules and masks do that, for an agent exactly as for a person.

Turn guesses into deterministic answers

An agent composes its answers from statistical patterns. That suits open questions. It doesn't suit a business rule, a calculation, a policy check or a lookup that takes several steps, where there is exactly one right answer. Encode those in the model and the agent calls them, instead of composing them afresh each time. Of everything on this page, this does the most to reduce variation.

  • Metrics. A named aggregate defined once, such as net revenue as order amounts less refunds. Each query breaks it out by the dimensions it asks for.
  • Derived views. A dataset defined once in SQL and read like any table.
  • Code resolvers. A Python or Node function that returns rows becomes a governed table, joinable to the rest of the model.
  • Commands. A registered operation, such as a stored procedure, a service call or a Python function, with typed inputs and outputs. An agent invokes it over MCP, and a command can require approval before it runs.

A derived view and a code resolver's table are tables, so terms bind to them and to their columns like any other. A term can lead straight to the logic that computes it: ground "churn rate" in the view or the resolver that calculates it, and an agent that asks about churn rate reads the calculation your organization agreed, instead of writing its own.

Each one lives in the model and is governed like a table, so every agent and every wording of the question gets the same answer.

Standard interfaces for two kinds of automation

People read the ontology on its page in the UI, and in reports, because the ontology is a schema you can query like any other. Agents reach the model over MCP. Tools built on OWL and RDF, such as reasoners, ontology editors and RDF pipelines, reach it over SPARQL 1.1. The endpoint takes queries as the SPARQL protocol sends them, answers SELECT, ASK and CONSTRUCT, and writes results as SPARQL JSON, XML, CSV or TSV, and graphs as Turtle, N-Triples or JSON-LD. Your ontology's classes and properties are its vocabulary, and the ontology itself answers in RDFS, OWL and SKOS, so an RDF tool reads it as it reads any OWL ontology. The same governance applies to every SPARQL query.

Reasoning works in the other direction too. A SPARQL source can name the HermiT OWL reasoner and an axioms document, and Provisa serves the inferred class memberships and properties as governed tables.

A citation records the judgement

When an agent answers from data, its answer carries a citation. The citation names the term the question was taken to mean, with its status and grounding at the time. It shows how that term leads to the tables and columns, and which data was read, down to the row where that matters. It names the statement that ran, the model version, the time of the data and the role whose view the agent saw. Anyone can follow the reasoning from the word to the row and check it. Hand the citation back later and Provisa reproduces the answer, or tells you whether the model, the data or the role's rights changed.

A term is citable on its own. Its address and definition are the organization's agreed meaning of the word, for an agent, a report or a person to point to.

When an answer is wrong, the citation shows where. Maybe "client" was bound to the prospects table, or a synonym joined two words the business keeps apart. Either way it's a specific mistake in shared meaning. You fix it once, on the term, and every later question that goes through the term gets the fix.

A poor ontology hurts more than it helps

An agent guessing from names is wrong in different ways on different days. An agent following a bad binding is wrong the same way every time, with a citation that looks official. Consistency is only worth having when the meaning is right, so Provisa keeps the quality of the meaning in view.

  • Only approved, grounded routes steer an agent to data. A term that reaches no data is never offered as a route to data, and a draft term an agent does see is marked as a draft.
  • Citations expose a wrong binding. Each one names the term and the path that led to the data, so a bad route shows up in the first answer that uses it.
  • Stewards see the impact before they act. Before you approve, retire or bind a term, the page shows what changes: "Approving Region makes 3 terms grounded and gives agents a path to 2 more tables." A stewardship summary lists the ~grounded terms each waiting on one approval, and the approved terms that reach no data.

The primitives are simple on purpose. How much they help your agents depends on how well your stewards use them.

Start with one word

  1. Pick the word behind the questions that come back with different answers.
  2. Check the names and descriptions of the tables and columns it should lead to, and fix them.
  3. Define it and bind it to the data it means, then have a steward approve it.
  4. Ask again and read the citation to see which meaning the agent used and where it led.