# Taxonomy, ontology, semantic layer, context layer: what's the difference?

> Taxonomies, ontologies, semantic layers and context layers are showing up across analytics, integration and AI. Here’s what each one does, how they relate, and where Taxi and Orbital fit.

Source: https://orbitalhq.com/blog/2026-09-09-taxononmy-vs-ontology
Date: 2026-09-09

Analytics teams have been talking about semantic layers for a while. (So have we.)

But with the rise of AI, a wider set of terms - **taxonomy, ontology, semantic layer, context layer** - has moved into mainstream architecture discussions.

To make enterprise AI work at scale, it needs to understand more about how the organisation models its world: what things are, how they relate, where those concepts appear in real systems, and what matters for the task at hand.

So, here's how we think about the terminology:

| Layer              | What it answers                                                                                         |
|--------------------|---------------------------------------------------------------------------------------------------------|
| **Taxonomy**       | **What kinds of things exist, and how are they classified?**                                            |
| **Ontology**       | **How are those things related, and what can we assert about them?**                                    |
| **Semantic layer** | **How do those meanings map onto the concrete data and capabilities in our systems?**                   |
| **Context layer**  | **Given that semantic map, what is relevant right now, how do we get to it, and how can we act on it?** |

These ideas aren't coming from one corner of the market. dbt, Snowflake and Databricks have invested heavily in semantic layers for analytics and AI. Data catalogue vendors such as Atlan are talking about context layers. MCP has made exposing tools and capabilities to AI much easier - which makes the next problem more obvious:

> **Once an agent can reach hundreds of systems, how does it know how their data relates, what matters, and how they fit together?**

So, let's take a look at these concepts, and how they work together

## A taxonomy is agreeing what to call things

_Image: Taxonomy: a shared language for naming things_

Taxonomies are the smallest building block. They give us a way to name, define and classify concepts.

For example, a database might have a column:

```sql
email_address VARCHAR(255)
```

or, if you're unlucky:

```sql
eadd VARCHAR(255)
```

The schema tells us how the value is stored; the field name only hints at what it means. Across systems, the same concept is often named differently.
As we've [written before](/blog/2023-01-16-using-semantic-metadata#field-names-are-a-bad-proxy-for-semantics), field names are a bad proxy for meaning.

A taxonomy gives that concept a stable name and definition, independent of any particular system.

**Note**
We'll show examples in two languages: [Taxi](https://taxilang.org), our open-source ontology language, and [OWL](https://www.w3.org/OWL/), the W3C standard for describing ontologies.

We think Taxi is a pretty concise way of expressing this stuff, but we'll leave you to form your own opinion.


    ```taxi Taxi
    type PersonalData

    [[ An electronic mail address used to contact a person ]]
    type EmailAddress inherits PersonalData

    type Name inherits PersonalData
    type PhoneNumber inherits PersonalData

    // Taxonomies aren't limited to scalar values, but
    // Taxi usually keeps shared semantics scalar,
    // so systems can share meaning without sharing structure.
    type Party
    type Person inherits Party
    type LegalEntity inherits Party
    ```

    ```turtle OWL
    @prefix : <https://example.com/schema#> .
    @prefix owl: <http://www.w3.org/2002/07/owl#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

    :PersonalData a owl:Class .

    :EmailAddress a owl:Class ;
        rdfs:subClassOf :PersonalData ;
        rdfs:label "Email address" ;
        rdfs:comment "An electronic mail address used to contact a person" .

    :Name a owl:Class ;
        rdfs:subClassOf :PersonalData .

    :PhoneNumber a owl:Class ;
        rdfs:subClassOf :PersonalData .

    :Party a owl:Class .

    :Person a owl:Class ;
        rdfs:subClassOf :Party .

    :LegalEntity a owl:Class ;
        rdfs:subClassOf :Party .
    ```


There's more going on here than giving `email_address` a nicer name. We've defined what `EmailAddress` means, classified it as `PersonalData`, and created a vocabulary that can be shared across an organisation.

As we'll see [later](#a-semantic-layer-connects-the-abstract-model-to-real-systems), once that vocabulary is attached to APIs, datasets or catalogues, software can find data by meaning, apply governance rules, and recognise the same concept across otherwise unrelated systems.

Taxonomies can classify bigger business concepts too: `Person` and `LegalEntity` can both be kinds of `Party`. What they generally don't describe is how those concepts relate. They don't tell us that a person **works for** a legal entity, or that a billing account **belongs to** one.

That's where an ontology adds more.

## An ontology maps how the business fits together

_Image: Ontology: a model of the things in your business, and how they relate_

Our taxonomy gave us some concepts: `Person`, `LegalEntity`, `BillingAccount`, `Order`, `EmailAddress`.

An ontology starts to describe what we know about those concepts - particularly the relationships between them.


    ```taxi Taxi
    relationship hasEmail: Person -> EmailAddress
    relationship worksFor: Person -> LegalEntity

    relationship belongsTo: BillingAccount -> LegalEntity
    relationship hasContact: BillingAccount -> Person

    relationship placedBy: Order -> BillingAccount
    ```

    ```turtle OWL
    :hasEmail a owl:ObjectProperty ;
        rdfs:domain :Person ;
        rdfs:range :EmailAddress .

    :worksFor a owl:ObjectProperty ;
        rdfs:domain :Person ;
        rdfs:range :LegalEntity .

    :belongsTo a owl:ObjectProperty ;
        rdfs:domain :BillingAccount ;
        rdfs:range :LegalEntity .

    :hasContact a owl:ObjectProperty ;
        rdfs:domain :BillingAccount ;
        rdfs:range :Person .

    :placedBy a owl:ObjectProperty ;
        rdfs:domain :Order ;
        rdfs:range :BillingAccount .
    ```


Put together, those relationships form a model that software can navigate:

```text
Person ──worksFor──> LegalEntity
                         ↑
                      belongsTo
                         │
                  BillingAccount
                    ↑         ↑
               hasContact   placedBy
                    │         │
                  Person    Order
```

This is a big part of why companies like Palantir put so much emphasis on ontologies. Once this knowledge is explicit, it becomes reusable: software can understand how an order relates to a legal entity, or how a person relates to an account, without reconstructing that knowledge from API names and schemas each time.

### Ontologies tend to be abstract

Importantly, none of this says anything about **where the data lives**. Ontologies usually describe the domain independently of the systems that implement it.

`Person worksFor LegalEntity` is a statement about the business. It doesn't say that a `Person` JSON object contains a `worksFor` field, or that the relationship lives in the CRM.

That's useful: the model can stay stable while systems change underneath it. But there's a trade-off:

> **If the ontology remains entirely abstract, you now have two representations of the organisation: the conceptual model, and the collection of systems that actually implement it.**

Those two can drift. The ontology may describe customers, accounts and orders beautifully, while the real implementation is scattered across API fields, database joins, event payloads and application logic.

Taxi keeps the ontology abstract without leaving it disconnected from the real systems. Schemas can explicitly link themselves to the concepts and relationships they implement.

That bridge between the abstract model and the concrete data and capabilities in your systems is the **semantic layer**.

## A semantic layer connects the abstract model to real systems

_Image: Semantic layer: connects your business model to the systems that represent it_

So far, the taxonomy and ontology have been abstract. A semantic layer connects those concepts to the data and capabilities that actually exist in our systems.

### This idea is already familiar in analytics

Tools such as dbt let teams define entities, dimensions and metrics over warehouse models, so concepts such as `NetRevenue` don't have to be reimplemented independently in every dashboard or report.

A simplified dbt definition might look something like:

```yaml
semantic_models:
  - name: sales
    model: ref('fct_sales')

    measures:
      - name: gross_revenue
        agg: sum
        expr: gross_amount

      - name: credit_notes
        agg: sum
        expr: credit_note_amount

metrics:
  - name: net_revenue
    type: derived
    type_params:
      expr: gross_revenue - credit_notes
      metrics:
        - name: gross_revenue
        - name: credit_notes
```

Taxi supports the same idea of making business calculations reusable, although it models them as semantic types:

```taxi
type GrossRevenue inherits Decimal
type CreditNotes inherits Decimal

type NetRevenue = GrossRevenue - CreditNotes
```

The abstractions are different - dbt is purpose-built around analytical models, aggregations and joins - but the principle is the same: **give business meaning and logic a stable definition, then connect it to the data that implements it.**

### The same idea applies to operational systems

Suppose our ontology contains:

```taxi
relationship hasEmailAddress: Person -> EmailAddress
relationship worksFor: Person -> LegalEntity
```

And the CRM exposes:

```taxi
model EmployeeRecord satisfies Person {
    email: EmailAddress?
    employer: CompanyRecord?
}

model CompanyRecord satisfies LegalEntity
```

`EmployeeRecord` is a concrete schema; `Person` is the abstract concept it represents. Likewise, `employer` is a field in that schema, while `worksFor` is the more general relationship in the ontology.

Another system might realise the same relationship through a database join, identifier or API call; the ontology stays the same.

### The semantics can live with the schemas you already have

This doesn't require replacing OpenAPI, Avro or Protobuf. Taxi metadata can be embedded directly into those formats:


    ```yaml OpenAPI
    components:
      schemas:
        EmployeeRecord:
          type: object
          properties:
            email:
              type: string
>             x-taxi-type:
>               name: acme.EmailAddress
    ```

    ```json Avro
    {
      "type": "record",
      "name": "EmployeeRecord",
      "fields": [
        {
          "name": "email",
          "type": "string",
>         "taxi.dataType": "acme.EmailAddress"
        }
      ]
    }
    ```

    ```protobuf Protobuf
    message EmployeeRecord {
      optional string email = 1
>       [(taxi.dataType) = "acme.EmailAddress"];
    }
    ```


The existing specification remains the source of truth for structure; Taxi adds the connection back to the shared taxonomy and ontology.

The ontology says `Person worksFor LegalEntity`. The semantic layer tells us **how that statement is realised in the systems we actually have**.

## A context layer surfaces what's relevant now

_Image: Context layer: provides the right data and capabilities for the task at hand_

At this point we have a semantic map of the organisation: what things mean, how they relate, and where they can be found.

A context layer uses that map to surface the information relevant to a particular request.

For example:

> Jimmy's on the phone. Show me his open orders, unpaid invoices, and outstanding support tickets.

The context here spans multiple domains: Jimmy himself, his orders, invoices and tickets, plus things like permissions, provenance and authoritative sources.

There are two broad ways to provide it.

One is to copy the data into a central store - a warehouse, knowledge graph or index - and query it there. That makes querying simpler, but requires pipelines to keep another copy of the data in sync, and that copy can become stale.

The harder approach is to fetch context from systems of record when it's needed: find Jimmy in the CRM, use that result to call the Orders API, query invoices from a database, then fetch tickets from support.

That's harder than querying data loaded into Snowflake overnight. But the source systems remain authoritative, the data stays where it belongs, (avoiding vendor lock-in), and the context reflects what's true now.

### TaxiQL describes the context you want

TaxiQL is designed around this second model. A query describes the data required in semantic terms, without specifying which APIs or databases should provide it:

```taxi
given { EmailAddress = 'jimmy@demo.com' }

find { Person } as {
    name: PersonName
    orders: Order[](OrderStatus == 'OPEN')
    invoices: Invoice[](InvoiceStatus == 'UNPAID')
    tickets: SupportTicket[](TicketStatus == 'OPEN')
}
```

There's deliberately no `JOIN`, API URL or service name in that query.

Using the semantic layer, a runtime such as Orbital can work out a route through the available systems: perhaps looking Jimmy up in the CRM, using the identifiers it discovers to call the Orders and Support APIs, and querying invoices from a database. The query describes the context required; the runtime works out how to assemble it.

That's the distinction: the semantic layer tells us **how the organisation's concepts map onto its systems**. The context layer uses that map to **assemble what's relevant for the task at hand**.

## Why AI has pulled these ideas together

Analytics teams made business meaning explicit because otherwise different reports produced different answers. Integration teams have always needed the same kind of knowledge across systems, but much of it ended up buried in mappings, transformations and orchestration code.

AI has both problems at once. An agent needs to understand what the data means, but it also needs to navigate across systems to find or change it.

MCP helps with one part of that problem by standardising how AI applications discover resources and invoke tools. It doesn't tell an agent what your company means by `Customer`, which source is authoritative for an order, or how the output of one operation relates to the input of another.

We've seen the practical effect in our own [orchestration benchmark](/blog/2026-01-20-agentic-orchestration-research-paper): planning accuracy dropped to unusable levels once agents faced a few hundred plain OpenAPI endpoints, and recovered when we added semantic metadata.

That's why these previously separate ideas are starting to converge. AI needs both the **meaning** of the organisation and a way to apply that meaning across the systems where work actually happens.

## Where Taxi and Orbital fit

Taxi gives us one language for the first three parts of this picture: shared concepts, relationships, and the mappings from those concepts onto APIs, databases and streams.

Orbital is the runtime piece. It uses those definitions to fulfil requests against the systems available at query time - working out which operations to call, how data flows between them, and assembling the context the consumer asked for.

That's why we think of Orbital as a context layer built on an operational semantic layer. Taxi describes the map; Orbital uses it.
