Skip to content

Navigation Menu

Sign in
Sign up

Architecture

Sanjeev Azad edited this page Jul 5, 2026 · 5 revisions

Architecture

Two toolchains, one bundle in the middle. FIBO's OWL/RDF is turned into a clean OKF knowledge bundle, which then feeds three consumers: the interactive map (for people), the context packs (for AI agents), and the bridge contribution (for the EDM Council).

System overview

flowchart TB
 subgraph SRC["Sources (pinned, MIT)"]
 FIBO["FIBO OWL/RDF<br/>10 domains"]
 CMNS["OMG Commons<br/>upper ontology"]
 end
 subgraph PY["Python ETL"]
 EX["extract.py<br/>walks owl:Restriction axioms"]
 IM[("intermediate.json")]
 TO["to_okf.py<br/>applies curation overlays"]
 end
 subgraph CUR["Curation (hand-authored, grounded)"]
 NC["nominate_core.py<br/>use-case core sets"]
 BR["bridges.py<br/>cross-domain bridges"]
 OV["examples / definitions / notes"]
 end
 BUNDLE[("knowledge/ OKF bundle<br/>3,104 concepts, 19 bridges")]
 subgraph OUT["Consumers"]
 JS["scripts/okf.js"] --> DATA[("js/data.js")] --> MAP{{"Interactive map<br/>(people)"}}
 EP["export_pack.py"] --> PACK[("export/ context packs")] --> AGENT(("AI agent"))
 EB["export_bridges.py"] --> CONTRIB[("contrib/<br/>EDM proposal")]
 end
 FIBO --> EX
 CMNS --> EX
 EX --> IM --> TO --> BUNDLE
 NC --> TO
 OV --> TO
 BR --> BUNDLE
 BUNDLE --> JS
 BUNDLE --> EP
 BUNDLE --> EB
Loading

Everything left of the bundle is generated; only the curation/ overlays and knowledge/bridges/ are hand-authored. Extraction is deterministic, so the bundle reproduces byte-for-byte.

1. Extract (etl/extract.py)

FIBO ships as OWL/RDF where the interesting relationships hide inside owl:Restriction blank-node axioms on rdfs:subClassOf, not as flat triples. extract.py walks those into a flat out/intermediate.json. fibo_ns.py classifies every IRI into a cluster (FIBO domain / CMNS / LCC) and maps it to a stable path.

2. Build the OKF bundle (etl/to_okf.py)

One markdown file per concept, with YAML frontmatter:

type: FIBO Class
title: "bond"
description: "tradable debt instrument representing a loan..." # from FIBO skos:definition
resource: https://spec.edmcouncil.org/fibo/ontology/SEC/Debt/Bonds/Bond # the audit citation
tags: [SEC, Release]
core: true
use_cases: ["Securities Instruments & Issuance (capital markets)"]
relations:
 - {type: is-a, target: "/FBC/.../DebtInstrument", provenance: fibo}
 - {type: backed-by, target: "/LOAN/.../Mortgage", provenance: curated} # a bridge

3. Curation and use cases

A use case is spec-driven. Dropping a spec under curation/usecases/ adds one, no code change:

flowchart LR
 SPEC["usecases/&lt;uc&gt;.json<br/>facet spec"] --> NC["nominate_core.py<br/>resolve + gate"]
 NC -->|"every id must be a<br/>real FIBO class"| CORE[("curation/&lt;uc&gt;.json<br/>core set")]
 BSPEC["usecases/&lt;uc&gt;-bridges.json"] --> BR["bridges.py"]
 BR -->|"endpoints real AND<br/>FIBO doesn't already draw it"| BFILES[("knowledge/bridges/")]
 EXJSON["&lt;uc&gt;-examples.json<br/>&lt;uc&gt;-definitions.json"] --> TO2["to_okf.py"]
 CORE --> TO2
 TO2 --> BUNDLE2[("knowledge/ bundle")]
 BFILES --> BUNDLE2
 BUNDLE2 --> PACK2["export_pack.py<br/>-&gt; export/&lt;uc&gt;/"]
Loading

Five use cases are curated this way (loan origination, KYC, securities, regulatory reporting, derivatives): 284 core concepts, 19 validated cross-domain bridges. The nominate_core and bridges steps are anti-hallucination gates: they exit non-zero if any id or bridge endpoint isn't a real FIBO class, so a use case can never reference a concept that doesn't exist.

4. The map (scripts/okf.js + okf.config.js + js/)

okf.config.js holds everything that isn't a concept: the domains (split into module sub-clusters), maturity levels, relation styling (curated bridges drawn distinctly), and the interactive flows. scripts/okf.js build emits js/data.js. js/graph.js (forked from Bodhi) renders it with Cytoscape + fcose; the CSS is forked from Bodhi (with our additions). The default view lays out only the visible core, so load stays fast even on the full 3,104-node ontology, and a use-case lens focuses one use case at a time.

5. Agent grounding at runtime

This is the product: an agent answers a financial question grounded in the pack, and every answer carries a checkable FIBO citation.

sequenceDiagram
 participant U as User / task
 participant A as AI agent
 participant R as Retrieval (pack.json)
 participant M as LLM
 U->>A: financial question
 A->>R: search the use-case context pack
 R-->>A: top concepts + FIBO IRIs + provenance
 A->>M: question + grounding context
 M-->>A: answer + "Sources: <FIBO IRIs>"
 A-->>U: grounded, citable answer
 Note over R,M: every concept carries its FIBO IRI,<br/>so the answer is traceable to the standard
Loading

etl/export_pack.py emits each use case's grounding closure as pack.json (RAG records), context.md (prompt injection), and an OKF slice. etl/retrieval.py + etl/mcp_server.py expose it as an MCP retrieval endpoint.

6. The eval (eval/) — grounded vs ungrounded

The value proof runs the same agent twice and scores the difference deterministically (no LLM judge):

flowchart LR
 Q["benchmark question<br/>(grounded in a real pack IRI)"]
 Q --> G["grounded run<br/>(pack injected)"]
 Q --> N["ungrounded run<br/>(bare question)"]
 G --> S["deterministic scorer"]
 N --> S
 S --> R["accuracy · auditability · hallucination"]
Loading

Result across 263 questions in five use cases, on gpt-4o-mini (corroborated on gpt-4o): a +45.3-point aggregate accuracy lift, 97.0% auditable, 0% grounded hallucination. See Value Proof .

Provenance model

Provenance is never blurred. Every relation and every overlaid field is tagged fibo (from FIBO) or curated (authored here). Overlays only fill gaps; they never overwrite real FIBO text. This is what makes an answer auditable and what keeps the EDM Council contribution honest.

The fuller repo-side version is in docs/Architecture.md.

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /