remember() takes, entity_types and relationship_types, advise khora which entities and relationships to extract. This flat list can work for simple content, but says nothing about how to describe a type, when two mentions are the same entity, or what to infer. ExpertiseConfig is the next level up: a complete, reusable domain ontology that tells Khora not only which types to extract but how to describe them, how to recognise the same entity across sources, what new edges to infer, how confident to be, and what prompt to extract with.
ExpertiseConfig (call it ontology) and pass it via expertise= on the same call. The next section shows the whole define-then-use in one block.
What an ontology bundles
OneExpertiseConfig carries all of this, most of it optional, with sensible defaults:
A minimal ontology in Python
The three building blocks (ExpertiseConfig, EntityTypeConfig, RelationshipTypeConfig) are importable straight from khora:
Entity types: attributes, identifiers, aliases
AnEntityTypeConfig is more than a label. Three fields shape extraction and matching:
attributes:{required: [...], optional: [...]}, a soft schema that nudges the LLM to pull the fields you care about.identifiers: the attributes that identify the same entity across documents (e.g.emailfor a person,repo_urlfor a service). These drive deduplication.aliases: alternative type labels, so a model that emitsCOMPANYstill lands on yourORGANIZATIONtype.
Relationship types
source_types / target_types constrain which entity types an edge may connect (["*"] means any). bidirectional: true marks symmetric edges like COLLABORATES_WITH.
A relationship type’s
source_types / target_types must reference entity type names that exist in the same ontology (or *). An edge that points at an undeclared type is dropped.Cross-source entity unification (correlation rules)
Correlation rules merge the same real-world entity seen through different sources, the canonical “the Slack@ada and the Gmail ada@acme.com are one person” problem. A rule matches on match_fields (or a regex pattern), scoped to entity_types:
email, url, id) at high confidence (0.85–0.95). Match on names only at lower confidence (0.7–0.8), since names collide.
Inferring new edges (inference rules)
Inference rules derive relationships that were never written down, from ones that were. Each rule is awhen → then: a list of conditions to match, and the edge to create. The matcher walks chains of relationships and supports three linking shapes:
then.source / then.target pick which matched entities form the new edge, by ordinal (first.source, second.target, …):
Confidence thresholds
The ontology carries its own thresholds, and the extractor drops anything below them, a per-ontology precision knob:Expansion behavior
expansion controls the optional expansion phase of ingestion:
Authoring in YAML and loading it
For anything beyond a couple of types, YAML is the natural home. It keeps the whole ontology in one reviewable file. Load it withExpertiseLoader:
PERSON/TEAM/SERVICE entities and the MEMBER_OF / OWNS edges, then infers Ada COLLABORATES_WITH Bob and Ada/Bob CONTRIBUTES_TO billing-api.
Composing ontologies with extends
Ontologies are versioned and inherit. A config can extends one or more parents. The loader resolves the chain and merges: entity/relationship types add-or-override by name, rules combine (later wins on a name clash), prompts/confidence/expansion are overridden by the child:
{{ parent_prompt }} and iterate the merged {{ entity_types }}. Loading hiring above yields the types PERSON, ORGANIZATION, CANDIDATE and a prompt that embeds the parent’s text plus the live type list.
The built-in type hierarchy
Inference and relationship rules match through a built-in subtype map, so a rule written for a general type also fires on specific ones:EMPLOYEE and EXTERNAL_PERSON satisfy a rule expecting PERSON. COMPANY / DEPARTMENT / TEAM satisfy ORGANIZATION, and CALL satisfies EVENT. You can write rules against broad types and still match a richly-typed graph.
Engine notes
VectorCypher supports ontology-driven typed extraction via theentity_types / relationship_types kwargs, and runs expansion, so it honours correlation_rules, inference_rules, and the expansion block.
Ingestion
Where the ontology plugs in: the three-phase write path.
Workloads example
A runnable
ExpertiseConfig in the resume-search walkthrough.API reference
ExpertiseConfig and the ontology dataclasses.Retrieval
The read path that queries what extraction produced.