Healthcare Intake
How a clinic uses an AI medical assistant to process patient intake forms with patient identifiers tokenized before the language model sees them
How a clinic uses an AI medical assistant to process patient intake forms with patient identifiers tokenized before the language model sees them.
Note: This scenario relies on detecting patient names. Person detection requires the Python NER sidecar (
GUARDAI_DETECTOR_URL, withdetector.mode: bothoradvanced); in builtin-only mode names are not detected (DOB, SSN, and insurance/health IDs still are, via regex). Setdetection.required_for: [person]in the policy to fail closed if the sidecar is down. See Detector Capabilities.
The Situation
A multi-location primary care clinic processes 200 patient intake forms per day. Each form contains the patient's full name, date of birth, Social Security number, insurance ID, and free-text health complaints. The clinic wants an AI assistant to generate structured intake summaries for physicians, flagging potential conditions and suggesting preliminary questions.
HIPAA is non-negotiable. Direct patient identifiers (name, date of birth, SSN, insurance ID, phone) must not reach a third-party model provider, while the clinical content itself, the symptoms and history, is exactly what the AI needs to reason about. The IT team evaluates several approaches: on-premise models (too expensive to maintain), manual redaction (too slow), and regex stripping (destroys clinical context). None are viable.
The Solution
OGuardAI is deployed as a sidecar container alongside the clinic's EHR integration service. The intake form text passes through OGuardAI before reaching the AI model. PHI is tokenized with semantic metadata so the model can reason about patient context without seeing real identifiers.
Step-by-Step: A Patient Intake
Erika Mustermann, DOB 1985-03-22, submits an intake form at the clinic front desk.
Step 1: Intake Form Arrives
The EHR system receives the digitized form:
Patient: Erika Mustermann
DOB: 03/22/1985
SSN: 123-45-6789
Insurance: HealthPlan ID HP-9920184
Phone: (312) 555-0147
Chief Complaint: I have been experiencing severe headaches for the past
3 weeks, especially behind my left eye. Over-the-counter ibuprofen is not
helping. I also noticed some blurred vision in my left eye yesterday.
My mother had glaucoma.Step 2: OGuardAI Transforms the Form
curl -X POST http://localhost:3000/v1/transform \
-H "Content-Type: application/json" \
-H "X-API-Key: $GUARDAI_API_KEY" \
-d '{
"input": "Patient: Erika Mustermann\nDOB: 03/22/1985\nSSN: 123-45-6789\nInsurance: HealthPlan ID HP-9920184\nPhone: (312) 555-0147\n\nChief Complaint: I have been experiencing severe headaches for the past 3 weeks, especially behind my left eye. Over-the-counter ibuprofen is not helping. I also noticed some blurred vision in my left eye yesterday. My mother had glaucoma.",
"policy": "healthcare-intake"
}'OGuardAI detects five entities:
| Original Value | Entity Type | Token | Metadata |
|---|---|---|---|
| Erika Mustermann | person | {{person:p_001:ad4f97591c16}} | gender: female, language: en |
| 03/22/1985 | date_of_birth | {{date_of_birth:dob_001:674de46dbb79}} | -- |
| 123-45-6789 | ssn | {{ssn:ss_001:196fafc65f05}} | -- |
| HP-9920184 | insurance_id* | {{custom:insurance_id:x_001:1d36c09bcdef}} | -- |
| (312) 555-0147 | phone | {{phone:ph_001:71453119be53}} | -- |
Entity types marked with * are custom types defined via policy rules, not built-in. See the Extending Entities guide.
The safe metadata a token can carry is a fixed set: gender, formality, language, role, belongs_to, legal form, an RTL flag, and a detected honorific. There is no derived demographic metadata, so nothing here tells the model an age band or an insurance carrier; only the entity type and whatever metadata_policy exposes.
The safe text sent to the AI model:
Patient: `{{person:p_001:ad4f97591c16}}`
DOB: `{{date_of_birth:dob_001:674de46dbb79}}`
SSN: `{{ssn:ss_001:196fafc65f05}}`
Insurance: HealthPlan ID `{{custom:insurance_id:x_001:1d36c09bcdef}}`
Phone: `{{phone:ph_001:71453119be53}}`
Chief Complaint: I have been experiencing severe headaches for the past
3 weeks, especially behind my left eye. Over-the-counter ibuprofen is not
helping. I also noticed some blurred vision in my left eye yesterday.
My mother had glaucoma.Clinical symptoms and family history pass through untouched: they are medically relevant, not identifiers.
Step 3: AI Generates a Summary
The AI model receives the tokenized text plus the entity context the policy exposes (here: gender female, language en, for the person token) and generates:
INTAKE SUMMARY for `{{person:p_001:ad4f97591c16}}`
Demographics: Female patient
Insurance: `{{custom:insurance_id:x_001:1d36c09bcdef}}`
Presenting Complaints:
- Severe headaches x 3 weeks, retro-orbital (left)
- Refractory to OTC ibuprofen
- New-onset blurred vision (left eye, 1 day)
Relevant History:
- Family history of glaucoma (mother)
Differential Considerations:
- Acute angle-closure glaucoma (family hx + visual symptoms)
- Migraine with aura
- Cluster headache
- Elevated ICP
Suggested Actions:
- Intraocular pressure measurement
- Visual acuity and field testing
- Fundoscopic exam
- Consider urgent ophthalmology referral given family historyThe model never saw Erika Mustermann's name, SSN, or phone number.
Step 4: Restore for Different Channels
Doctor's review, full restore mode:
curl -X POST http://localhost:3000/v1/rehydrate \
-H "Content-Type: application/json" \
-H "X-API-Key: $GUARDAI_API_KEY" \
-d '{
"output": "<AI summary with tokens>",
"session_state": "<encrypted-blob>",
"output_channel": "internal_summary"
}'The physician sees the complete summary with "Erika Mustermann," full DOB, and insurance ID restored.
Patient portal, masked restore mode:
curl -X POST http://localhost:3000/v1/rehydrate \
-H "Content-Type: application/json" \
-H "X-API-Key: $GUARDAI_API_KEY" \
-d '{
"output": "<AI summary with tokens>",
"session_state": "<encrypted-blob>",
"output_channel": "customer_email"
}'The patient sees their name restored. masked restore keeps the first and last character and replaces every other one, so 123-45-6789 comes back as 1*********9 and HP-9920184 as H********4. Switch the channel rule to partial and add a reveal_last_n restore strategy if a last-four display is required.
Policy Configuration
name: healthcare-intake
version: "1.0"
rules:
- entity_type: "person"
protection_level: 2
action: "tokenize"
restore_mode: "full"
- entity_type: "date_of_birth"
protection_level: 2
action: "tokenize"
restore_mode: "full"
- entity_type: "ssn"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
- entity_type: "insurance_id"
protection_level: 2
action: "tokenize"
restore_mode: "full"
- entity_type: "phone"
protection_level: 2
action: "tokenize"
restore_mode: "masked"
# insurance_id is a clinic-defined custom type. It must be declared in
# custom_patterns before any rule or channel references it, otherwise the policy
# loader aborts startup with "references unknown entity type 'insurance_id'".
custom_patterns:
- entity_type: "insurance_id"
pattern: '\bBC-\d{7}\b'
confidence: 0.9
context_words: ["insurance", "bluecross", "member"]
defaults:
protection_level: 2
action: "tokenize"
restore_mode: "masked"
metadata_policy:
expose_gender: true
expose_formality: true
expose_language: true
expose_role: true
# A channel rule can only TIGHTEN an entity's base restore_mode, never widen it. ssn and
# phone stamp a base of "masked", so they stay masked on every channel, including this one.
channel_rules:
internal_summary:
person: full
date_of_birth: full
ssn: masked
insurance_id: full
phone: masked
customer_email:
person: full
date_of_birth: masked
ssn: masked
insurance_id: masked
phone: masked
log_safe:
person: none
date_of_birth: none
ssn: none
insurance_id: none
phone: noneWhat OGuardAI Made Possible
HIPAA-aligned controls without sacrificing AI quality. Detected direct identifiers are tokenized before they reach the model provider. Clinical symptoms and family history, the medically relevant parts, pass through unchanged so the AI can reason effectively. Detection is never exhaustive: validate coverage against your own intake corpus before treating any deployment as compliant.
Channel-specific restoration. The same AI output serves three audiences: physicians see everything, patients see masked identifiers, and audit logs contain no real values.
Zero workflow disruption. The EHR integration calls OGuardAI as a middleware step. Front desk staff and physicians interact with their existing tools unchanged.
Audit-ready. Every transform and rehydrate operation is logged with entity types and policy applied, never with raw PHI. The compliance officer can demonstrate the data flow to HHS auditors.