Skip to content

Drug Knowledge-Graph — Phased Build Plan

Date: 2026-06-29 Owner: Gene Lang, PharmD (Director of Pharmacy Operations) · Rx360 Status: 🟡 SCOPE / SEQUENCE / EFFORT — this is the build plan, not the build. Grounded in: AI_Foundation/KB/01_Knowledge_Layer_KB_KG.md (node/edge model + terminology spine) · 02_Retrieval_RAG_GraphRAG.md · 03_Guardrails_Safety_Layer.md · 05_Data_Governance_MLOps.md · Product_Specs/Curated_Drug_KB_and_Tagging_Schema_2026-06-04.md (the fact schema) · Product_Specs/Medication_Intelligence_Engine_PHASED_PLAN_2026-06-04.md.

Why now. The real clinical knowledge-graph was deliberately deferred "until after the 2026-06-26 patent filing." That date has passed. The architecture is fully designed in the AI_Foundation KB; this plan turns that design into an actionable, staged build — what to build, in what order, with what data, and roughly how much effort — so it can be resourced and handed to engineering (Faraz) without re-deriving the design.

What this is (and isn't)

  • Document KG (already shipped, on the docs site): nodes = our deliverables, edges = relationships. Navigational. Done.
  • Drug/clinical KG (this plan): nodes = drugs / classes / conditions / risk markers / interactions / forgiveness profiles / members / events; edges = clinical relationships. This is the substrate the medication-intelligence product reasons over (duplicate-therapy detection, FRID load for the Fall Barometer, interaction screening, forgiveness-aware Smart Scheduling).

Two different graphs. This builds the second.


North-star architecture (from the KB, recapped)

  • Terminology spine — anchor everything to standard codes: RxNorm/RXCUI (drug identity) · RxClass (ATC / MeSH / NDF-RT / FDA EPC / ENZYME for classes) · SNOMED CT + ICD-10-CM (conditions) · OpenFDA / DailyMed SPL (NDC, strength, label rules).
  • Property graph (Neo4j or Amazon Neptune-PG). Node types: Drug · Clinical Drug · Ingredient · Drug class · Condition/Indication · Risk marker (FRID, Beers PIM, anticholinergic burden, NTI, controlled, LASA) · Interaction · Forgiveness/tolerance profile · Member (PHI, access-controlled) · Event (med-input, confirmation, dismissal, fall-signal, med-change, refill, escalation).
  • Edge types: Drug ─IS_A→ Class · Class ─SUBCLASS_OF→ Class · Drug ─HAS_INGREDIENT→ Ingredient · Class ─CARRIES_RISK→ RiskMarker {marker, weight, beersRec, effectiveDate, kbEntryId} · Drug ─INTERACTS_WITH→ Drug {severity, mechanism, management, source, clinicalLineFlag} · Drug ─HAS_TOLERANCE_PROFILE→ ForgivenessProfile {tier, foodRule, missPolicy, kbEntryId, version} · Drug ─INDICATED_FOR / CONTRAINDICATED_FOR→ Condition · Member ─TAKES→ Drug {since, provenance, confidence} · Member ─HAD_EVENT→ Event.
  • Knowledge-as-data, not code: every clinical edge/fact carries the Curated Drug KB tagging-schema provenance — kb_entry_id, status (preliminary|validated), author/approver (no self-approval), clinical_line, evidence_strength, effective_date, version, supersedes. No clinical fact reaches a member without a kb_entry_id + pharmacist sign-off.

Phases

Phase 0 — Foundations (decision + scaffolding)

Goal: the spine and the governance rails exist before any clinical content lands. - Decision: graph DB. Neo4j (mature Cypher, AuraDB managed, GraphRAG tooling) vs Amazon Neptune (AWS-native, fits a BAA/private-cloud posture). Recommend Neo4j AuraDB for velocity unless the AWS-BAA constraint dominates → then Neptune. (Gene/Faraz call.) - Terminology ingest: load RxNorm (RRF), RxClass, SNOMED CT + ICD-10-CM, OpenFDA/DailyMed into a staging store; build the RXCUI↔NDC and RXCUI↔class crosswalks (these already exist partially in the Smart Add / NCPDP work for Faraz — reuse). - Provenance/governance schema from KB 05: every node/edge gets the tagging-schema provenance block; author≠approver enforced; status gates production use; a de-identification gateway sits in front of any Member/Event data (PHI never in the curated layer). - Effort: ~2–3 wks (mostly ingest plumbing + DB choice). Dependencies: none. Risk: SNOMED licensing (UMLS account) — start the license request now.

Phase 1 — Seed the clinical graph from what we already have

Goal: a usable graph for the highest-value reasoning, seeded from existing curated assets — not built from scratch. - Sources to ingest as nodes/edges (all already authored): - Smart_Scheduling/KB/02_Drug_Forgiveness_Tolerance_Data.md (27 classes) → ForgivenessProfile nodes + HAS_TOLERANCE_PROFILE edges. (status: preliminary → flag for Dr. B sign-off.) - Rx360_Shared_Drive/02_Clinical_Data_and_Risk_Analysis/Rx360_Medication_Risk_Database_v1.md + the Fall Barometer FRID tagging → RiskMarker nodes + CARRIES_RISK edges (FRID, Beers, ACB, NTI). - Product_Specs/Scanner_Label_Requirements_KB/ → label/jurisdiction reference (kept as structured side-tables, linked by NDC; not core clinical edges). - Curated Drug KB tagging schema → the per-fact provenance contract (already the standard). - Build the FRID-load query first — it's the single highest-value graph operation (feeds the Fall Barometer's medication category). Validate it reproduces the current Balance Meter med-scoring inputs. - Effort: ~3–4 wks. Dependencies: Phase 0. Risk: preliminary clinical content — everything ships status: preliminary until pharmacist-reviewed; the graph must refuse to surface unreviewed facts to members (Phase 3 rail).

Phase 2 — Retrieval layer (structured-first → vector → GraphRAG)

Goal: the engine answers medication questions by querying the graph, not a free LLM. - Per KB 02: deterministic/structured retrieval first (Cypher/graph lookups serve from the table — identity, class, FRID, interaction, forgiveness), then vector (pgvector→Qdrant/Milvus) for semantic fallback, then GraphRAG for multi-hop ("what about this combination?"). - Self-RAG / CRAG grounding: every generated answer must cite the kb_entry_id(s) it used; ungrounded answers are refused. - Effort: ~4–6 wks. Dependencies: Phase 1 (graph populated). Risk: the temptation to let the LLM "fill gaps" — the rail (Phase 3) must make that impossible for clinical content.

Phase 3 — Deterministic clinical rail (the blast door)

Goal: fail-closed safety — the wellness/clinical line is enforced in code, not prompts. - Per KB 03: defense-in-depth (input moderation → retrieval grounding → output rail). The clinical rail is deterministic: if a response touches clinical_line: true content, it must (a) be served from a status: validated KB entry, (b) carry its provenance, (c) respect member_facing (never | wellness-safe), and (d) fall back to "discuss with your pharmacist" when uncertain — never improvise dosing/clinical advice. - This is the same posture as the existing Medication_Matching_Guardrails + Guardrails_Flow_Map, now enforced at the graph-retrieval layer. - Effort: ~3–4 wks. Dependencies: Phase 2. Risk: this is the load-bearing safety work — do not de-scope it to ship faster.

Phase 4 — Product integration + learning loop

Goal: the graph powers the actual products and improves over time. - Medication Intelligence Engine: Smart Add / med-input resolves to RXCUI → graph enriches with class/FRID/interaction/forgiveness (the engine stops re-deriving these per-app). - Smart Scheduling: consumes ForgivenessProfile for tolerance-aware reminder timing. - Fall Barometer: consumes the FRID-load query + the cross-engine medication-change event (FRID add/remove/dose change → bounded sensitivity watch-window). (Trade-secret scoring stays in the Barometer; the graph supplies inputs, not the score.) - Learning loop (KB 05): Kafka event-stream + FHIR R4/US-Core; member events feed analytics behind the de-identification gateway; pharmacist sign-off remains the gate for any new clinical fact. - Effort: ~6–8 wks (phased per product). Dependencies: Phases 1–3.


Sequencing & rough total

Phase Focus Effort Gating dependency
0 DB choice + terminology spine + governance 2–3 wks UMLS/SNOMED license
1 Seed graph from existing KBs (FRID-load first) 3–4 wks Phase 0
2 Retrieval (structured→vector→GraphRAG) 4–6 wks Phase 1
3 Deterministic clinical rail 3–4 wks Phase 2
4 Product integration + learning loop 6–8 wks Phases 1–3

~5–6 months end-to-end at a steady pace; Phases 0–1 (≈6–7 wks) already deliver standalone value (the FRID-load query + a queryable drug/class/risk graph) and can ship before the rest.

Decisions needed from Gene / Faraz

  1. Graph DB: Neo4j AuraDB (velocity) vs Amazon Neptune (AWS-BAA fit).
  2. Pharmacist reviewer + cadence for moving seeded facts preliminary → validated (Dr. B? Matilda?). The graph is only as shippable as its sign-off pipeline.
  3. Scope of v1: ship Phases 0–1 (queryable graph + FRID load) as a milestone, or hold for the full retrieval+rail stack before any product wiring.
  4. BAA posture for the Member/Event layer (governs where the graph + any PHI-adjacent analytics run).

Risks

  • SNOMED/UMLS licensing lead time — start now (Phase 0 blocker).
  • Preliminary clinical content — the seeded forgiveness/FRID data is design-tier until pharmacist sign-off; the rail (Phase 3) must prevent unreviewed facts from reaching members.
  • Scope creep into the LLM — the discipline is structured-first, LLM-last, rail-always.