OntoSmith builds knowledge graphs under an ontology a human approves first.
The schema is a flat extraction contract: entity and relation types with definitions and boundary examples. No hierarchy, no axioms: the flatness is what makes per-type quality measurable.
Install from PyPI, pip install ontosmith, and step 1 of the
README runs with no API key:
start with step 1.
The pipeline never asks one model to do everything. Measured seats are filled by the models that won their jobs in measurement, and judgment sits apart from proposing: the judge seat is the exception, because Jev is a pinned component, not a bake-off winner.
Proposes candidate triples for the entity pairs the pipeline enumerates. The parsing and roster work is local and deterministic. Fast, tireless, and not trusted: everything it proposes is checked.
Weighs every candidate against its evidence span and commits: verified, or into the review band. A small model built for exactly one skill: judgment.
Off by default. When you enable it, this seat takes adjudication escalations and evaluation judging, and it never decides a build’s triples. Frontier tokens are spent only where you point them.
Plus a drafting seat you bind yourself, and an embedder
(text-embedding-3-large) for the vector arm of search. Every seat is
configuration, never code. Underneath, Jev judges and Neo4j
stores, and a build requires both; setup is a first-class step in
Connections.
A chunk store returns text and leaves the connections in it implicit. In the graph, each connection is a typed edge with its evidence attached. Three real items from the project’s own records:
“Sabet was a long time aide to former Afghan Prime Minister Gulbuddin Hekmatyar.”
The fact sits inside an article about Sabet. As an edge, it answers to its own subject, with the sentence attached as evidence.
Adjudication appendix item B-193, judged supported. The article is the Wikipedia entry on Abdul Jabar Sabet, via Re-DocRED.
“He returns to his step-brother Quenu, a charcutier and his wife Lisa Quenu (formerly Macquart), with whom he finds refuge.”
Zola never lists his cast. Quenu enters through a family relation in the plot, and the edge makes him a node, linked onward to Florent and Lisa.
Adjudication appendix item B-151, judged supported. Quote spacing is normalized from the tokenized record.
“The term of this Agreement shall be ten (10) years (the “Term”) which shall commence on the date upon which the Company delivers to Distributor the last Sample, as defined hereinafter.”
Defined names are identities inside the document. The build resolves them to their referents, so every later “during the Term” attaches to the same node.
Corpus-profile example in the Legal Contract pack. Corpus: CUAD (The Atticus Project), CC BY 4.0.
The graph below was rendered from an actual build: the shipped legal pack’s reference corpus, judged triple by triple before a single edge was drawn.
See it work, do it yourself, then look inside.
A real build, start to finish: documents in, a judged and queryable graph out.
Install, set the seats, run a small build, then serve, search, and read the evidence.
The pipeline, the gates, the packs, and how the published numbers were audited.
The graph lives in Neo4j: one graph, the current build’s, and a build under a changed ontology replaces it, named in the run, never silent. Search fuses lexical, graph, and vector arms; a graph with no embeddings still answers on two.
A new document type rarely arrives with an ontology ready. The builder drafts
one from your corpus profile and a short brief: by default a skeleton of type names, or,
with a drafting model bound and --llm passed, full definitions and boundary
examples. You review the draft and pin it as a domain pack of your own.
Version-pinned packs, never domain code paths. Every domain pack stands on the same core baseline: core itself is not a domain pack, it is what the domain packs extend. A document type with no pack yet can grow its own.