Field
Computer Engineering
Education
UT Dallas
Location
Richardson, TX / Open to relocation
Expected
May 2028
Edition
01 / SEP 2026
Exposure

Project record / 02

Evidence-Grounded ICD-10 Coding Assistant

Foundry/AIP tool suggesting ICD-10 codes with verbatim evidence and validation


Project metadata


Coding workspace with clinical evidence and suggested codes.

Overview

An operational tool that reads unstructured clinical notes, suggests ICD-10 diagnosis codes for medical coders, and grounds every suggestion in verbatim evidence plus a validation check against an official code reference. Built on Palantir Foundry and AIP.


Problem

Hospitals bill insurance using ICD-10 diagnosis codes, a standardized system with roughly 70,000 codes. A human medical coder reads long unstructured clinical notes and hand-assigns codes. The work is slow and detail-heavy, and miscoding carries real consequences: under-coding loses revenue, over-coding or incorrect coding triggers claim denials and compliance audits.

Fully automating this with an LLM is dangerous, because a model can confidently produce a code that does not exist or that is not supported by the note.


User and operational decision

  • User: a medical coder or Clinical Documentation Integrity (CDI) specialist.
  • Decision informed: approve, correct, or escalate the ICD-10 codes for a chart before it goes to billing.
  • Effect: the coder shifts from reading an entire chart and coding from scratch to reviewing evidence-backed suggestions and approving them, while retaining full control of the final decision.

This is a tool that informs a decision, not an analytics dashboard.


What it does

For a selected patient:

  1. Reads the clinical note
  2. Suggests ICD-10 codes, one per identified diagnosis or codeable finding
  3. Shows the verbatim sentence from the note justifying each suggestion
  4. Marks each code validated (green) or unverified (amber) against an official ICD-10 reference
  5. Lets the coder approve each suggestion, writing that decision back into the data model

Architecture

Two Foundry datasets feed a Pipeline Builder pipeline; the output feeds an ontology of two linked object types; a Workshop application is the coder's surface.


Pipeline, stage by stage

Stage 0: Data preparation (local, pre-upload)

Two source files from the challenge's public data extract:

  • PMC_Patients_clean.csv: 167,000+ patient notes (patient_id, patient_uid, patient_note, age, gender)
  • icd_10_codes.csv: about 2 GB, containing embedded_description (a stringified vector embedding), icd_10_code, and description

Local reduction in pandas:

Reduced files: patients_sample_50.csv at ~151 KB, icd10_reference.csv at ~6 MB. The 2 GB original was never uploaded.

Stage 1: Extraction

A Pipeline Builder pipeline (icd_extraction) runs a Use LLM node over each patient_note. Model: Claude Sonnet 4.5 (anthropic-claude-4-5-sonnet). The node writes raw model output to a string column, llm_output.

Extraction prompt:

Design intent: the verbatim-quote requirement forces grounding and makes fabricated findings hard; "only code what is documented" is the accuracy guardrail; structured JSON makes the downstream parse and ontology mapping mechanical.

Stage 2: Parse and explode

Raw llm_output is stripped of markdown code fences, parsed as a JSON array of structs (condition, icd10_code, evidence_quote, confidence), then exploded so there is one row per suggestion, carrying patient_id, patient_uid, and patient_note on every row, with a generated unique suggestion_id.

A checkpoint dataset (patients_with_llm_output) preserves the raw per-patient LLM output, so re-running downstream logic never re-invokes the expensive LLM step.

Stage 3: Validation join

Each suggested code is checked against icd10_reference:

  1. A normalized key norm_code is computed on both sides: uppercase the code, remove all . characters. This handles the dotted vs undotted gap (E11.9 versus E119).
  2. Suggestions are LEFT JOINed to the reference on norm_code.
  3. validation_status is validated when a reference match exists, otherwise unverified.
  4. For validated rows, the reference description is pulled in as canonical_description.

Output dataset validated_suggestions columns: suggestion_id, patient_id, patient_uid, condition, icd10_code, canonical_description, evidence_quote, confidence, validation_status.

An "unverified" result means the code was not found in the reference subset used. Because the reference is a subset of full ICD-10-CM, most unverified codes are real codes simply absent from the reference rather than hallucinated ones. The tool surfaces this uncertainty for human review rather than hiding it.

Stage 4: Ontology

Two object types, with a link and an action:

  • Patient: primary key patient_id, title patient_uid, backed by patients_sample_50. Properties: patient_id, patient_uid, age, gender, patient_note. Read-only.
  • CodeSuggestion: primary key suggestion_id, title condition, backed by validated_suggestions. Properties: suggestion_id, patient_id, condition, icd10_code, canonical_description, evidence_quote, confidence, validation_status, and a boolean approved defaulting to false. Edits enabled so the action can write back.
  • Link: one-to-many, Patient to CodeSuggestions, joined on patient_id.
  • Action: "Approve suggestion", parameter code_suggestion, sets approved = true. The write persists in the writeback layer, so rebuilding validated_suggestions does not reset prior approvals.

Stage 5: Workshop application

A Workshop module ("Coding Assistant"):

  • Left panel: Object List of all Patients, titled by patient_uid. Selection writes to a selectedPatient variable.
  • Right panel, top: Markdown widget bound to the selected patient's patient_note, via an Object-property variable off the active patient.
  • Right panel, bottom: Object Table whose object set is the selected patient's linked CodeSuggestions, produced by a "Get linked objects" traversal along the Patient to CodeSuggestions link. Columns: icd10_code, condition, canonical_description, evidence_quote, validation_status, confidence, approved. Conditional formatting shows validation_status green for validated and amber for unverified.
  • Approve button: action button wired to the "Approve suggestion" action, with its code_suggestion parameter bound to the currently selected suggestion.

Engineering details and gotchas

  • Dotted vs undotted codes: ICD-10 codes appear both as J96.01 and J9601. The join normalizes both sides (uppercase, strip dots) so the validation match does not silently miss.
  • Model identifier resolution: selecting Claude Sonnet 4.5 required the exact internal identifier anthropic-claude-4-5-sonnet; several plausible names (claude-sonnet-4-5, claude-3-7-sonnet, claude-5-sonnet) were rejected first.
  • Markdown fences in LLM output: Sonnet wraps JSON in code fences. Stripped deterministically in the parse step rather than prompt-wrestled.
  • Writeback index provisioning on a branch: a newly created, edits-enabled object type on a branch has its read index ready before its writeback index finishes provisioning, so a headless "approve" call can fail initially. Opening the object type in the UI, or clicking Approve inside the Workshop app in a real user session, bootstraps the writeback index.

Known limitations

  • Prototype scale: 50 sampled notes, not volume-tested.
  • Uncalibrated confidence: the confidence field is present but not yet meaningful.
  • Partial reference: the reference is a subset of full ICD-10-CM, so some "unverified" codes are real but missing rather than wrong.
  • No clinical validation: suggestions are traceable and checkable, but code correctness has not been verified by a certified coder. Output is a suggestion for human review, not authoritative coding.

Data and attribution

  • Patient notes: the PMC-Patients dataset. Zhao, Z., Jin, Q., Chen, F., Peng, T., and Yu, S. (2022), "A Large-scale Dataset of Patient Summaries and Relations for Benchmarking Retrieval-based Clinical Decision Support Systems," arXiv:2202.13876. Source repository: https://github.com/pmc-patients/pmc-patients. Derived from open-access case reports (CC BY-NC-SA).
  • Codes: ICD-10-CM.
  • Patient data is not included in the project repository.

Full stack

Palantir Foundry · Palantir AIP · Pipeline Builder · Ontology · Workshop · Claude Sonnet 4.5 · Python · pandas



Results

ItemValueBasis
Code suggestions generated
500 across 50 patients, roughly 10 per patient
verified
Validated against reference
475 (95%)
verified
Unverified
25 (5%)
verified
Extraction richness vs a smaller model
13 conditions versus 6 on one representative note, with strictly verbatim quotes
verified, n=1