The Context Engine Studio is now open source.  View on GitHub →
Clinia
Concepts

Relationship Inference

How the Clinia Context Engine constructs a typed graph of clinical relationships between deduplicated entities, and what nodes and edges that graph contains.

Relationship Inference

After entity resolution deduplicates clinical records across sources, the patient graph is a set of isolated nodes: conditions, medications, labs, and so on. Those nodes do not yet know about each other. Relationship inference adds the edges that connect them.

The result is a directed, typed graph where each edge encodes a specific clinical meaning. This structure is what allows the VFS to assemble condition stories that include medications, monitoring labs, and complications without querying across separate tables.

Nodes

Each node in the graph corresponds to one resolved clinical entity. Most entity types map directly to the VFS path categories; the last two are edge endpoints only, so they appear in a fact's relationship list without having a path of their own:

Node typeVFS pathRepresents
condition/conditions/active/, /conditions/resolved/Diagnoses, problems, and clinical findings
medication/medications/current/, /medications/discontinued/Drugs, dosages, and administration records
lab/labs/Laboratory observations and results
allergy/allergies/Allergy and intolerance records
encounter/encounters/{year}/Clinical visits, organized by year
family_history/family_history/Conditions recorded as family history
insurance/insurance/Coverage and payer information
directive/directives/Advance directives and consent records
memory— not a VFS entryWhat a session recorded
narrative— not a VFS entryFree-text content of an ingested document

Nodes carry all field values from their contributing sources, resolved conflicts, and the full provenance trace. See Provenance and Auditability.

memory and narrative are explained under the edges they carry, below.

Edges

Edges are directed and typed. Several mechanisms produce them, and each edge records which one it came from.

Knowledge-base edges are emitted when the clinical knowledge base identifies a known relationship between two entities already in the graph:

Edge typeSource nodeTarget nodeWhat it encodes
prescribed_formedicationconditionMedication is indicated for the condition
monitorslabconditionLab test tracks disease activity or treatment response
has_complicationconditionconditionCondition has another as a known complication
manifestation_ofconditionconditionCondition is a clinical manifestation of another
progression_ofconditionconditionCondition is a later stage or progression of another
risk_factor_forconditionconditionCondition increases risk of another
commonly_comorbidconditionconditionConditions frequently co-occur; represented as A→B and B→A edges
same_disease_axisconditionconditionConditions share the same disease spectrum or axis

Each knowledge-base edge carries a confidence score derived from the strength level in the knowledge base: strong indications produce confidence ~0.90, moderate ~0.75, weak ~0.60.

Temporal inference edges are emitted when timing patterns suggest a linkage that is not in the knowledge base:

Edge typeSource nodeTarget nodeWhat it encodes
occurred_duringconditionencounterCondition onset or recorded date correlates with an encounter

occurred_during uses graded confidence based on how closely the condition onset aligns with the encounter window (0.80 for onset within the encounter period, down to 0.60 for onset within 30 days). It is skipped when an explicit has_reason or occurred_during edge already exists from the source data.

Memory edges are emitted whenever a clinically-anchored memory (symptom or adherence) is matched against the patient's facts. This happens when memories are generated for a session, matching the new memories against existing facts, and again during ingestion, matching newly-ingested condition or medication facts against the patient's existing memories — so a fact ingested after a session can still pick up a link to a memory that predates it. See Memory.

Edge typeSource nodeTarget nodeWhat it encodes
corroboratesmemoryfactConversational statement agrees with the structured record
enrichesmemoryfactConversational statement adds context without contradicting
conflictsmemoryfactConversational statement contradicts the structured record

Memory edges never modify the target fact. A conflicts edge surfaces the disagreement without touching the fact's value, status, or confidence. concern and preference memories produce no edges.

Narrative edges use the same three types, but come from a different place: they are emitted during ingestion, when a fact is adjudicated against the free-text narrative content of the documents the patient's record already contains. Where a memory edge speaks for something said in a session, a narrative edge speaks for something written in a note.

Edge typeSource nodeTarget nodeWhat it encodes
corroboratesnarrativefactThe note states what the structured record holds
enrichesnarrativefactThe note adds context the structured record does not carry
conflictsnarrativefactThe note contradicts the structured record

A narrative edge records the strength of the reading, the reasoning behind it, and the narrative it was adjudicated against; the narrative's own text is read by following that pointer rather than copied onto the edge, so the edge stays in step when the narrative is rewritten. Reading the edge gives you the narrative's title and the reasoning for each verdict — see the _narratives/ leaf under a condition in VFS Paths. It does not give you the note's own wording; for that, read the document under /sources/. Like memory edges, a narrative edge never modifies the target fact: a conflicts edge records the disagreement and leaves the fact's value, status, and confidence alone.

Explicit vs. inferred edges

Whether an edge was stated or inferred matters more than which mechanism inferred it, and the two are handled differently.

Explicit edges are lifted directly from the source data. FHIR reasonReference links and CDA entryRelationship elements are preserved as-is. They are never overridden by inference.

Inferred edges are added by the mechanisms described above — the knowledge base, temporal patterns, memory matching (at memory generation and at ingestion), and narrative verification. For the two that connect facts to each other, the relationship resolver only adds an inferred edge when no explicit edge of the same type already exists between the pair, so the knowledge base cannot contradict structured data that came from a clinician. Memory and narrative edges raise no such conflict: they run between a fact and an endpoint that source data never links to, in edge types no source record states.

Every edge records in the entity's relationship list which mechanism produced it, so the distinction is always visible. The possible values of source are:

  • explicit_reference - Lifted directly from the source data, never inferred
  • knowledge_base - Inferred from a known relationship in the clinical knowledge base
  • temporal_inference - Inferred from how the two entities line up in time
  • llm_inferred - Inferred by a model, as memory edges are
  • narrative_verification - Inferred by adjudicating a fact against narrative content

Where the graph is visible

The relationship graph surfaces in five places:

  • Condition stories (_story.md) are assembled by traversing the graph from a condition node outward to its linked medications, labs, and complications. See Condition Stories.
  • A format=structured read of any condition path returns the full list of typed relationship edges for that node, both explicit and inferred. See VFS Paths.
  • _narratives/ under any condition lists the narratives a narrative_verification verdict links to it, one entry per narrative with the verdicts it holds — the one place the attesting edges (corroborates, enriches, conflicts) are browsable on their own. See VFS Paths.
  • The reconciliation report (GET /v1/patients/{patientId}/reconciliation) lists every inferred edge added during the inference pass. See Review the Reconciliation Summary.
  • The graph query API (GET/POST /v1/patients/{patientId}/graph/edges/relationship/...) reads, lists, and filters relationship edges directly by id, endpoint, type, or source. See API Overview.

On this page