Building a Patient-Facing AI Chatbot for Medical Records
How thirteen iterations turned a basic RAG prototype into a healthcare AI system patients
can actually trust.
The Problem.
Patients have a right to understand their own medical records. But medical data is dense, full
of codes, abbreviations, and clinical jargon that was never designed to be read by a
layperson. A lab result that says “Hemoglobin A1c/Hemoglobin.total in Blood: 7.2%” means
something very specific — but most patients would simply like to know: “What’s my A1C?”
ChartChat was built to bridge that gap. It’s an AI-powered chatbot that sits on top of a
patient’s medical records — structured as HL7 FHIR R4 resources — and lets them ask questions
in plain language. Lab results, medications, allergies, visit history, immunizations, vital signs,
and more — all accessible through a natural conversation.
The first version worked for simple queries. A patient could ask “what are my lab results?” and
get a response. But the distance between “it works” and “it works correctly, safely, and fast
enough for a real patient” turned out to be enormous. What follows is the story of thirteen
iterations that closed that gap.
Privacy as a Foundation.
Before a single line of application code was written, the team made a foundational decision:
all AI models would run inside the same secure environment as the patient data. No patient
information — lab results, diagnoses, medications, clinical notes — would ever leave the
network during any AI operation.
The default approach for most AI projects is to send data to a cloud-hosted service and pay
per query. For healthcare data, that creates a data boundary many organizations cannot or
will not cross. Compliance requirements, audit obligations, and patient trust all pointed the
same direction: the models needed to be co-located with the data.
This added real operational complexity — specialized hardware to manage, models to
update, inference performance to tune. But it eliminated an entire class of privacy concerns
and meant patient data could flow through the AI pipeline without requiring additional legal
review on every query.
The text understanding model was chosen specifically for its built-in strength with medical
vocabulary. It recognized clinical abbreviations like A1C, eGFR, BUN, and LOINC display
names without any custom training — a decision that would pay off significantly when it
came to retrieval quality.
Safety & Guardrails: The Hardest Problem.
When the team started building ChartChat, they assumed safety guardrails would be the straightforward part. They were wrong. Getting a healthcare AI to reliably stay within its boundaries required three complete rewrites of the approach, and every failure taught something essential about how language models behave in clinical settings.
Why a Medical AI Made Things Harder
The first instinct was natural: if you’re building a healthcare application, use a healthcaretrained
model. The initial model understood clinical terminology, could parse lab values
fluently, and knew how to reason about conditions and treatments.
But there was a fundamental tension. A model trained to be maximally helpful with medical
questions also resists not answering them. When a patient asked “should I go to the ER for
this?” — a question ChartChat absolutely cannot answer — the model would try to help
anyway. It would look at the retrieved lab values, reason about them, and hedge while still
engaging. The training objective and the safety objective were in direct conflict.
Attempt 1: Rules-Based Prompting
The team’s first approach was detailed system prompt rules: do not diagnose, do not triage,
do not advise on medication dosing, direct emergencies to 911.
This worked most of the time. But “most of the time” is not acceptable in healthcare. The
failure modes were subtle — not hallucinated diagnoses, but things like answering a triage
question by framing the answer as “what the records show” while still implying safety.
Responding to “is my A1C dangerous?” with a technically factual answer a patient could
read as medical clearance. Engaging with off-topic medical questions using general
knowledge instead of staying scoped to the patient’s actual records.
The line between “explaining what a record says” and “giving medical advice” is
conceptually clear but linguistically very blurry.
Attempt 2: Identity Over Rules
The breakthrough was a shift from writing rules to writing an identity. Instead of “do not give
medical advice,” the system became: you are a records reader, not a clinician. Your only
permitted action is to read what is written. When asked anything beyond that, return a
specific scripted sentence.
Scripted responses turned out to be far more reliable than instructed refusals. When you tell
an AI “don’t do X,” it still has to reason about X to know it shouldn’t. When you give it an exact
sentence to return, it doesn’t need to reason — it just returns the sentence.
Attempt 3: A Layered Architecture
Even the tightest prompt instructions are probabilistic — they work until they don’t. For the highest-risk categories, the team needed a guardrail layer that could never be bypassed, regardless of how a message was phrased.
- Layer 1 — Deterministic upstream check: handles the highest-risk cases and common courtesies. Fast, certain,
- Layer 2 — LLM system prompt: LLM handles the nuanced cases that require language understanding — off-topic questions, triage deflection, medication dosing refusals, scope boundaries. The model handles thes.