A medical-AI harness for healthcare data quality, clinical NLP, and explainable predictive modeling : built on the Harness pattern.
ClinClaw wraps any model (LLM or classical ML) in a reusable execution harness: a tool chain with input checkpoints, structured context, result validation, failure recovery, and rollback. The same pattern powers four domains : healthcare data quality, clinical diagnosis, drug discovery, and health management : so data-science workloads and agentic reasoning share one auditable pipeline.
Design principle: the model is replaceable; the harness is the asset.
Most healthcare AI value is lost not in the model but in everything around it such as dirty records, unvalidated outputs, and brittle glue code. This project treats data quality and reproducible ML pipelines as first-class citizens, in the same spirit as platforms that clean and validate billions of payer/provider records before any model runs.
| Domain | Harness | What it does |
|---|---|---|
| Data quality ⭐ | DataQualityHarness |
Profiles records (completeness/validity/uniqueness/consistency), detects anomalies, extracts & normalizes clinical entities |
| Diagnosis | DiagnosisHarness |
Symptom → differential → workup → diagnosis |
| Drug discovery | DrugDiscoveryHarness |
Target → screen → ADMET → lead optimization |
| Health management | HealthManagementHarness |
Assess → plan → follow-up |
RecordProfiler: completeness, validity (NPI Luhn, ICD-10, ZIP, date, state), uniqueness/dedup, consistency, and an overall quality score.AnomalyDetector: z-score / IQR outlier detection with an optional scikit-learnIsolationForestbackend for multivariate anomalies.ClinicalEntityExtractor: text-mining / NER for medications, conditions, labs, vitals, dosages, and ICD-10 codes, with synonym→canonical ontology normalization (optional spaCy/scispaCy backend).InterpretableClassifier: from-scratch L2-regularized logistic regression (gradient descent) whose coefficients are the feature importances; ships accuracy/precision/recall/F1/AUC.ABTest: two-proportion z-test for comparing model variants or treatment arms (lift, z, p-value, significance).SparkDataQualityPipeline: a PySpark pipeline (load → standardize → dedup → validity flags → anomaly flags → write) mirroring the in-memory harness at record scale.
pip install -e . # core (stdlib + httpx/pydantic/pyyaml)
pip install -e ".[ds]" # + numpy, scikit-learn, pyspark, spacyRun the offline data-quality + NLP + modeling demo (no API key needed):
python examples/data_quality_demo.pyfrom clinclaw import DataQualityHarness
harness = DataQualityHarness(
field_rules={"provider_npi": "npi", "state": "state", "zip": "zip", "enrolled_date": "date"},
key_fields=["provider_npi"],
numeric_fields=["monthly_claims"],
)
report = harness.assess(records=provider_rows, text=clinical_note)
report.quality_score # 0.0–1.0
report.duplicate_rows # de-dup candidates on key fields
report.anomalies # row indices flagged as outliers
report.recommendations # human-readable remediation steps
report.entities # extracted/normalized clinical entitiesBig-data variant:
from clinclaw import SparkDataQualityPipeline
SparkDataQualityPipeline().run(
"s3://claims/raw", "s3://claims/clean",
key_cols=["provider_npi"], string_cols=["specialty", "state"],
validity_rules={"provider_npi": r"^\d{10}$"}, numeric_cols=["monthly_claims"],
)Real output of python examples/data_quality_demo.py on the bundled sample
(data/samples/ — 14 deliberately-dirty provider rows + 3 clinical notes), fully
offline, no API key:
1. DataQualityHarness — provider directory
records analyzed : 14
quality score : 0.7577
duplicate rows : 2
anomaly indices : [9]
recommendations:
- De-duplicate 2 record(s) on key fields.
- Field 'enrolled_date': 1 value(s) fail 'date' validation
- Field 'provider_npi': 9 value(s) fail 'npi' validation
- Field 'specialty': 1 missing value(s)
- Field 'state': 1 value(s) fail 'state' validation
- Field 'zip': 1 value(s) fail 'zip' validation
- Review 1 anomalous record(s) flagged by zscore.
2. ClinicalEntityExtractor — NER + ontology normalization
note: "65M with HTN and T2DM presents with CP and SOB. BP 165/95 ..."
CONDITION : ['chest pain', 'diabetes mellitus type 2', 'hypertension',
'myocardial infarction', 'shortness of breath']
ICD10 : ['I21.9']
3. InterpretableClassifier — explainable model (high-cost member)
test metrics : {'accuracy': 0.7733, 'precision': 0.7273, 'recall': 0.8649,
'f1': 0.7901, 'auc': 0.8414}
top features : claims_norm +1.478 · chronic +0.884 · age_norm +0.391 · er_visits +0.228
4. ABTest — baseline vs new_model (two-proportion z-test)
baseline 0.812 → new_model 0.861 accuracy (+6.03%)
z = 2.9627, p = 0.003 → SIGNIFICANT at alpha=0.05
The provider directory scores 0.76 / 1.0: 9 of 14 NPIs fail the Luhn check
digit, 2 rows are exact duplicates, and the monthly_claims outlier (row 9) is
caught by the z-score detector — all surfaced as actionable recommendations.
Input ─▶ checkpoint ─▶ context ─▶ tool chain ─▶ checkpoint ─▶ reasoning ─▶ validate ─▶ recover
(profiler, anomaly, (deterministic ML
entity-extraction, …) or LLM, pluggable)
The harness layer is model-agnostic: data-quality harnesses reason deterministically (no LLM), while clinical harnesses can plug in MIMO / Claude / GPT / Ollama via the provider interface.
See docs/DATA_QUALITY.md for the data-science design and a requirement-by-requirement capability map.
clinclaw/
├── base.py # BaseHarness pipeline (checkpoints, rollback, dry-run)
├── context.py # structured context builder
├── recovery.py · validator.py
├── data_quality/ # ⭐ profiler, anomaly, NER, interpretable model + A/B
├── diagnosis/ · drug_discovery/ · health_management/
├── agents/ # multi-agent orchestration
├── mcp_tools/ # PubMed / OpenTargets / registry adapters
├── providers/ # pluggable model backends
└── spark/ # PySpark data-quality pipeline
skills/ # declarative skill specs (incl. data_quality/*.yaml)
examples/data_quality_demo.py
data/samples/ # dirty provider records + clinical notes
pip install -e ".[dev]" && pytest # full suite
python tests/test_data_quality.py # data-quality tests, no pytest neededMIT.