Pre-Alpha · Building in Public

The open-source layer between
biomedical data and modern AI.

Openbtk turns EHR data and clinical text into model-ready, de-identified, auditable inputs — and wraps LLM outputs in clinical guardrails. Runs on a laptop or behind a hospital firewall, with any LLM provider.

pip install openbtk View on GitHub PyPI
The Problem

"Ask questions of the discharge summaries" costs six weeks of plumbing.

Every team re-derives the same undifferentiated work — a note parser, a de-identifier that actually catches MRNs and admission-relative dates, chunking that doesn't split "Assessment" from "Plan," entity linking, an LLM that cites codes which don't exist — and then an IRB or an EU AI Act auditor asks exactly what data, model, and config produced a given output. Most teams have nothing to show.

🔐

De-identification you can audit

Not "runs Presidio." An ensemble of rule-based recognizers, clinical NER, and optional LLM adjudication, targeting entity-level F1 ≥ 0.95 on i2b2 2014 with a reproducible, one-command benchmark harness. Every run emits a DeidReport — entity counts, confidence, method attribution — that never contains the PHI itself.

📋

Run provenance as a primitive

Every pipeline execution emits a RunManifest: config hash, component versions, input data digests, guardrail outcomes, timings. Content-addressable, diffable, and designed to satisfy EU AI Act Article 12 record-keeping obligations. openbtk replay reconstructs a run byte-for-byte.

These two things, together, are what nothing else in open source has today.

Architecture

A framework-free, layered core

Strict downward-only imports, mechanically enforced in CI. A registry-mediated plugin model — every extension point is a base class you register against, not a fork you maintain.

graph TD
    L6["L6 · Applications & Recipes
clinical_text_rag · ehr_qa · deidentify_corpus"] L5["L5 · Interfaces
CLI (Typer) · optional LangChain adapter"] L4["L4 · Orchestration
Streaming DAG pipeline executor · RunManifest"] L3["L3 · Cross-cutting Services
llms · embeddings · retrieval · guardrails · terminology · eval · de-id"] L2["L2 · Modality Modules
clinical_text · ehr — imaging/biosignals/genomics gated"] L1["L1 · Core
registry · base classes · config · schemas · errors · provenance"] L6 --> L5 --> L4 --> L3 --> L2 --> L1 classDef l6 fill:#131c33,stroke:#60a5fa,stroke-width:2px,color:#f1f5f9; classDef l5 fill:#131c33,stroke:#7c9bfb,stroke-width:2px,color:#f1f5f9; classDef l4 fill:#131c33,stroke:#967dfa,stroke-width:2px,color:#f1f5f9; classDef l3 fill:#131c33,stroke:#a06ff8,stroke-width:2px,color:#f1f5f9; classDef l2 fill:#131c33,stroke:#aa62f6,stroke-width:2px,color:#f1f5f9; classDef l1 fill:#131c33,stroke:#b455f4,stroke-width:2px,color:#f1f5f9; class L6 l6 class L5 l5 class L4 l4 class L3 l3 class L2 l2 class L1 l1

Domain-aware by default

Built for clinical text and structured EHR data from day one, not bolted on.

Wrap, don't reinvent

MONAI for imaging, medspaCy for clinical NLP. Openbtk won't out-build the specialists.

Streaming by default

Loaders and chunkers stream — target: 10M notes under 4GB RSS.

Safe by construction

PHI-redacting logs on by default. Offsite LLM providers refused by default.

What It Does

Everything between raw data and a trustworthy prompt

🕵️

De-identification

Ensemble rules + NER + optional LLM verifier. All 18 HIPAA Safe Harbor categories.

  • 5 transform modes: redact, surrogate, hash, tag, date-shift
  • Per-patient consistent replacement
  • Output-side PHI leakage guardrail
📄

Clinical Text

Loaders for plain text, MIMIC III/IV, JSONL, CDA/CCD.

  • Section-aware chunking — never splits Assessment from Plan
  • ConText-style negation & uncertainty detection
  • PubMedBERT, BioBERT, ClinicalBERT, SapBERT, MedCPT presets
🧬

EHR & Terminology

FHIR R4, OMOP CDM, HL7v2 into a unified PatientRecord.

  • Structured → narrative timeline serialization
  • Streaming, composable cohort builder
  • SNOMED CT, LOINC, RxNorm, ICD-10/11, UMLS resolution
🔌

Providers

OpenAI, Anthropic, HF local, vLLM, Azure, Bedrock, Vertex.

  • Biomedical model presets (MedGemma, Meditron, BioGPT)
  • Every provider declares sends_data_offsite
  • Structured output validated against a Pydantic schema
🔎

Retrieval

FAISS, Chroma, Qdrant vector stores.

  • Concept-overlap reranking by shared UMLS CUIs
  • Clinical cross-encoder reranking, hybrid dense+BM25
  • Source provenance to exact character offsets
🛡️

Guardrails, Pipelines & CLI

Composable, never-raise guardrail checks.

  • Groundedness, terminology validity, dose plausibility
  • Config-as-data YAML pipelines, not agent control flow
  • openbtk run · validate · deid · replay · doctor
Code

Designed to read like plain Python

deidentify.py
from openbtk.deid import DeidEngine, DeidMode

engine = DeidEngine(mode=DeidMode.SURROGATE, recall_bias="high")
result = engine.deidentify(text, patient_id="hashed-123")

result.text    # "Robert Chen was seen on [DATE-SHIFTED] for..."
result.report  # DeidReport — audit trail, never contains the PHI itself

Planned API — target design, not yet shipped.

pipeline.py
from openbtk.pipelines import Pipeline, Step

pipeline = (
    Pipeline("clinical-rag")
    .add(Step("load",  "loader.clinical_text.plain_text", path="./notes"))
    .add(Step("deid",  "preprocessor.general.deidentify", mode="surrogate"))
    .add(Step("chunk", "chunker.clinical_text.section_aware", max_tokens=512))
    .add(Step("embed", "embedding.clinical_text.pubmedbert"))
    .add(Step("index", "vectorstore.general.faiss", path="./index"))
    .guard("guardrail.general.phi_leakage", at="after:deid", on_violation="block")
)
manifest = pipeline.run()
print(manifest.status, manifest.run_id)  # everything an IRB/auditor will ask for

Planned API — target design, not yet shipped.

Who It's For

A toolkit for builders, not a finished product

Not for clinicians wanting a diagnostic tool. Built for the people wiring biomedical data into AI systems.

Maya
ML Engineer, health-tech startup

Building discharge-summary Q&A on a hospital partner's data — needs de-id reliable enough to survive a security review.

Dr. Alvarez
Informatics postdoc

Studying readmission signals across notes and labs on MIMIC-IV, without needing 300GB of RAM.

Ken
Informatics lead, pharma

Weighing build-vs-buy against a six-figure commercial license — needs on-prem execution and an audit trail QA accepts.

Priya
OSS contributor

Adding a new modality by implementing base classes and registering — without patching the framework core.

Comparisons

Why not just use X?

Openbtk doesn't try to out-build category leaders. It fills the gap between them.

ToolCampWhere Openbtk differs
PyHealth 2.0Predictive DL health toolkitComplementary, not identical — PyHealth predicts, Openbtk is the LLM/agent-era data + safety layer.
MONAIMedical imagingNot reimplemented — wrapped in a future imaging module.
LangChain / LlamaIndexGeneric orchestration & RAGDomain-blind: no FHIR resource, DICOM series, or lab-panel concepts. One isolated optional adapter instead of a fork.
Guardrails AI / NeMo GuardrailsGeneric output validationNo clinical semantics — no dose plausibility, code validity, or chart-groundedness checks.
John Snow LabsCommercial clinical NLPClosed source, license cost excludes academia/startups, no public reproducible eval harness.
AWS / GCP / Azure health AIHyperscaler platformsVendor lock-in and usage-scaled cost. Openbtk competes on portability, auditability, and running on a laptop.
Status

Milestone M0 complete. M1 — the core framework — is next.

Openbtk is pre-alpha today. Follow the milestone-by-milestone build in public on GitHub.

Follow progress on GitHub →