One premise, one architectural choice
A context engine is the layer that hands an AI agent, a BI tool, or an app the governed meaning it needs before it answers: what "net revenue" means in this company, which entity a row refers to, and how concepts relate. In the space of a few weeks, three platforms shipped one — Snowflake's Business Ontology and Horizon Context, Databricks' Lakehouse Federation, and Neo4j's Context Engine and contextual retrieval.
They all accept the same premise. They differ on one choice: how tightly the context engine is coupled to the data it contextualizes. This HowTo explains the choice, describes what each platform documents, and walks through building the loosely coupled version — the Virtuoso Open Interoperable Context Engine (VOICE) — with live queries as proof.
What a context engine actually does
Snowflake's two posts name the failure precisely. The trigger is metric drift: "net revenue" means recognized revenue in Finance and bookings in Sales, and the two silently disagree. The reason an agent can't resolve it is that it is a new hire on day one, every time — it can write SQL but cannot tap the colleague who owns the definition.
A context engine is the answer. Snowflake describes its answer as a three-part loop:
Enrich — attach steward-approved definitions and relationships.
Activate — make that meaning available to agents, BI, and apps so they answer from governed definitions rather than guesswork.
Every context engine does some version of these three. What changes between vendors is where the loop runs and whether your data has to move into it.
How tightly do you couple?
Four strategies are on the table. They are not four ways of saying the same thing — they are four different answers to where the context lives and who owns the data.
| Aspect | Snowflake (native) | Databricks (federated) | Neo4j (copy-in) | VOICE (loose) |
|---|---|---|---|---|
| Where context lives | Inside Snowflake's engine (Horizon Catalog) | In the platform's Unity Catalog | A purpose-built context graph | Attached to the data, not owning it |
| Does data move? | Metadata is copied in for collect–enrich–activate | Source stays put; catalog, governance, and agent live in the platform | Entities and relationships are extracted into a property graph | Nothing moves — sources are queried in place over RDF Views |
| Attach mechanism | Metadata connectors + OpenLineage | Federated connections + foreign catalogs + Marketplace shares | Graph loading and entity extraction | RDF Views over any ODBC/JDBC DBMS + SPARQL-FED |
| Identifier system | Catalog-scoped, domain-qualified names | Unity Catalog namespace (catalog.schema.table) | Internal graph node ids | HTTP IRIs — hyperlinks that work as cross-platform super-keys |
| Agent coupling | Cortex Agent + business_ontology tool, in-platform | Genie, wired to catalogs in-platform | GraphRAG + agent memory over the graph | OPAL agents + agent-rdf-memory, loosely coupled |
| Governance | Steward approval + RBAC | Unity Catalog (credentials stay in the platform) | Graph access controls | SHACL + WebID/ACL/ABAC + PROV-O; access stays with the data |
| Standards & portability | Platform feature | Standard SQL; catalogs/governance/agent in the platform | Vendor graph model | W3C RDF/SPARQL/SPARQL-FED/OWL/PROV-O + ODBC/JDBC/R2RML — a portable graph |
Databricks
Neo4j
VOICE
VOICE — the loosely coupled context engine
The Virtuoso Open Interoperable Context Engine combines three pieces:
- Virtuoso — a converged engine holding relational tables and RDF graphs in one quad store, queried with SQL, SPARQL, SPASQL, and more.
- agent-rdf-memory — the agent's own context kept as queryable RDF named graphs.
- OPAL — agents assembled from skills and function tools, loosely coupled to the data space.
Its defining move is the hyperlink as identifier. Every row and concept gets an HTTP IRI that works as a cross-platform super-key — a key that keeps its meaning outside its own database. This is the Platinum Layer discipline: governed meaning expressed as dereferenceable Linked Data, not a vendor-defined catalog scope.
The result is a context engine whose coupling points are all standards — which is what lets one question reach every source, and lets any component be swapped without rewriting the rest.
Build a loosely coupled context engine — eight steps
Each step is grounded in one of the live demos in the proof section. The three VOICE posts walk versions of these steps against a specific vendor; here they are consolidated.
1Model business meaning as an open ontology
Turn governed concepts into first-class things, not glossary prose. "Net Revenue" and "revenue recognition policy" become classes and instances in an RDF/OWL/SKOS ontology, connected by standard relationship vocabularies — rdfs:subClassOf, schema:hasPart, prov:wasDerivedFrom, skos:exactMatch. Snowflake's Business Ontology expresses the same idea with a fixed, typed relationship set inside the platform; VOICE expresses it in the vocabularies that already exist, so the ontology is a portable artifact.
2Attach your sources without migrating them
Create an RDF View over any ODBC/JDBC-accessible DBMS — Microsoft SQL Server, PostgreSQL, Databricks, native Virtuoso tables, a Snowflake-style estate. SPARQL over an RDF View is compiled to SQL and run against the source tables at query time — the row lives in its own database, and only the answer travels. Proof: 5.3 and 5.5.
3Compute governed numbers in place
Governed computation — the "Net Revenue" an agent should cite — becomes an RDF View plus SPASQL (SPARQL embedded inside SQL), computed over the source without copying it. The metric carries provenance, not just a value.
4Federate across the estate
Join your holdings with third-party reference data in one query with SPARQL-FED's SERVICE clause (or a SPASQL statement that wraps SPARQL inside SQL), re-federated on every run. This is the open-standards expression of Databricks' "one query, full picture". Proof: 5.2.
5Give every row a hyperlink
Make each entity addressable by an HTTP IRI — the Platinum Layer. A hyperlink works as a cross-platform super-key: unlike a catalog.schema.table namespace or an internal key, it resolves to a description of that entity outside its own database. Proof: every result row in section 5 projects an IRI.
6Govern with SHACL, WebID/ACL, and PROV-O
Map steward review to SHACL shape validation, role-based access to WebID-TLS + ACL/ABAC (access stays with the data), and change history to PROV-O provenance. You get the governed-context discipline without binding it to one vendor's catalog.
7Couple agents loosely
Use OPAL to assemble agents from skills and function tools over MCP and Agent-2-Agent, and agent-rdf-memory to hold the agent's own context as queryable RDF. The model, the agent, and the data space can each change independently — the opposite of an agent wired to one catalog in one platform.
8Verify live with SPARQL
Every claim is a query you can run. The six demos in the next section are the verification step — each opens a specific fragment in the live value-prop app and executes against demo.openlinksw.com.
Live examples — run them yourself
Each demo runs against https://demo.openlinksw.com/sparql and opens a specific fragment id in the Virtuoso value-prop app. Row counts are from live runs made while preparing this article (2026-11-14).
5.1 · Three hops from tenant to warehouse table — graph walk across Snowflake, Databricks, BigQuery▼
PREFIX skg: <http://demo.openlinksw.com/schemas/ScaleKG/>
PREFIX schema: <http://schema.org/>
SELECT ?tenantIri ?tenant ?workloadIri ?workload ?tableIri ?tableName ?source
FROM <http://demo.openlinksw.com/ScaleKG#>
WHERE {
?tenantIri a skg:Tenant ; schema:name ?tenant .
?workloadIri skg:forTenant ?tenantIri ; schema:name ?workload ; skg:readsFrom ?tableIri .
?tableIri schema:name ?tableName ; skg:inSource ?sourceIri .
?sourceIri schema:name ?source .
}
ORDER BY ?tenant ?workload ?tableName
Live result: 9 rows — tenants (Acme Retail, Borealis Bank, Cobalt Health, Dunmore Logistics) linked to workloads and tables sourced from Snowflake, Databricks, and BigQuery.
5.2 · Replication topology and the access-control gap — governance in one query▼
PREFIX skg: <http://demo.openlinksw.com/schemas/ScaleKG/>
PREFIX schema: <http://schema.org/>
SELECT ?linkIri ?sourceDb ?fromRegion ?targetDb ?toRegion ?syncMode ?rbacReplicated
FROM <http://demo.openlinksw.com/ScaleKG#>
WHERE {
?linkIri a skg:ReplicationLink ;
skg:replicatesFrom ?sourceIri ; skg:replicatesTo ?targetIri ;
skg:syncMode ?syncMode ; skg:rbacReplicated ?rbacReplicated .
?sourceIri schema:name ?sourceDb ; skg:hostedOn/skg:inRegion/schema:name ?fromRegion .
?targetIri schema:name ?targetDb ; skg:hostedOn/skg:inRegion/schema:name ?toRegion .
}
ORDER BY ?sourceDb
Live result: 3 replication links (acme, borealis, cobalt production → replicas), all flagged rbacReplicated = 0 — the access-control gap a context engine must not silently inherit.
5.3 · Most-stocked products — SQL Server read as a graph, in place▼
PREFIX nw: <http://demo.openlinksw.com/schemas/Northwind/>
SELECT ?product ?name ?unitsInStock ?unitPrice
FROM <http://demo.openlinksw.com/Northwind#>
WHERE {
?product a nw:Products ;
nw:productname ?name ; nw:unitsinstock ?unitsInStock ; nw:unitprice ?unitPrice .
}
ORDER BY DESC(?unitsInStock)
LIMIT 10
Live result: 10 rows — Rhönbräu Klosterbier (125), Boston Crab Meat (123), Grandma's Boysenberry Spread (120), and seven more.
5.4 · SQL Server customers as hyperlink entities — every customer a dereferenceable IRI▼
PREFIX ns: <http://demo.openlinksw.com/schemas/northwind-sqlserver/>
SELECT ?customer ?customer_id ?company_name
FROM <http://demo.openlinksw.com/northwind-sqlserver#>
WHERE {
?customer a ns:customers ;
ns:customerid ?customer_id ; ns:companyname ?company_name .
}
ORDER BY ?customer_id
LIMIT 10
Live result: 10 rows — ALFKI "Alfreds Futterkiste", ANATR "Ana Trujillo Emparedados y helados", and eight more, each linked to a description page.
5.5 · Databricks tables through an R2RML RDF View — no migration, no copy▼
SELECT ?type (COUNT(?s) AS ?n)
FROM <http://demo.openlinksw.com/databricks-bakehouse-r2rml#>
WHERE { ?s a ?type }
GROUP BY ?type
ORDER BY DESC(?n)
Live result: 5 entity types — Transaction (3,333), Customer (300), CustomerReview (204), Franchise (48), Supplier (27).
Frequently asked questions
What is the difference between a "context engine" and a knowledge graph?▼
Does loose coupling mean I lose the "turnkey" experience?▼
SERVICE clause; addressing a row is a hyperlink. What you give up is the requirement that the context live inside one platform.Do I have to move my data into Virtuoso?▼
How does this compare with Databricks Lakehouse Federation?▼
What does VOICE add to the Snowflake governed-context picture?▼
Is the "Platinum Layer" just a naming convention?▼
Core terms
The layer that supplies an agent, BI tool, or app with governed meaning (definitions, relationships, provenance, access) before it answers.
An architecture in which components attach through standards (ODBC/JDBC, RDF/SPARQL, HTTP IRIs) so each can change independently.
The Virtuoso Open Interoperable Context Engine: Virtuoso + agent-rdf-memory + OPAL.
A mapping that projects relational tables as an RDF graph, so SPARQL compiles to SQL against the source at query time.
The SPARQL extension whose SERVICE clause federates a query across multiple endpoints.
SPARQL embedded inside SQL in a single statement, joining graph and relational results.
The discipline of addressing every row and concept with a dereferenceable hyperlink that works as a cross-platform super-key.
OpenLink's agent framework: agents assembled from skills and function tools, loosely coupled to a data space.
The VOICE posts and the offerings they respond to
The VOICE posts this article draws on (each has a live-queries section):
- Snowflake Governed Context vs VOICE — meaning on open standards
- Databricks Lakehouse Federation vs VOICE — an open federation layer
The offerings they respond to: