DEV Community

shashank ms
shashank ms

Posted on

LLMs in Healthcare: Applications and Opportunities

We are going to build a clinical note structuring agent that reads unstructured physician notes and returns clean, validated JSON. This tool is useful for health tech teams who need to normalize EHR data, generate billing codes, or feed downstream analytics without writing brittle regex. Because clinical notes are often thousands of tokens long, running this on Oxlo.ai makes sense: you pay per request, not per token, so a lengthy discharge summary costs the same as a short vitals check.

What you'll need

Step 1: Configure the Oxlo.ai client

First, we instantiate the OpenAI-compatible client pointing at Oxlo.ai. I use llama-3.3-70b here because it handles medical terminology well, but you can swap in kimi-k2.6 if you are processing discharge summaries that run tens of thousands of tokens.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

# Quick connectivity check
response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Say 'Oxlo.ai client ready'"},
    ],
)
print(response.choices[0].message.content)

Step 2: Define the extraction schema

The system prompt is the contract. It tells the model exactly what fields to extract and how to format them. Keeping this versioned in your repo is a good practice.

SYSTEM_PROMPT = """You are a clinical data extraction engine.
Your job is to read an unstructured clinical note and return a single JSON object with exactly these keys:

- patient_summary: a one-sentence summary of the encounter
- diagnoses: list of confirmed diagnoses mentioned
- medications: list of current medications with dosage if stated
- allergies: list of known allergies
- procedures: list of procedures performed or planned
- follow_up: any follow-up instructions or referrals
- red_flags: list of urgent concerns requiring immediate attention

Rules:
1. Return ONLY valid JSON. No markdown, no explanation.
2. If a field is not mentioned in the note, use an empty list or null.
3. Do not infer information that is not explicitly stated."""

Step 3: Build the extraction function

Now we write a function that sends the raw note to the model and requests strict JSON output. Oxlo.ai supports JSON mode, so we can lock the response format.

import json

def extract_clinical_data(note_text: str) -> dict:
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": note_text},
        ],
        response_format={"type": "json_object"},
    )
    raw = response.choices[0].message.content
    return json.loads(raw)

Step 4: Add a validation pass

Extraction is only useful if it is complete. We add a second call that compares the original note against the draft JSON and flags any missing medications or unsupported diagnoses.

VALIDATION_PROMPT = """You are a clinical data validator.
Compare the original clinical note with the draft JSON extraction below.
Identify any missing fields, unsupported diagnoses, or medications that do not appear in the text.
Return a JSON object with:
- missing_fields: list of fields that should have been populated but were not
- unsupported_items: list of items in the extraction with no evidence in the note
- confidence: high, medium, or low"""

def validate_extraction(note_text: str, draft: dict) -> dict:
    payload = f"Original Note:\n{note_text}\n\nDraft JSON:\n{json.dumps(draft, indent=2)}"
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": VALIDATION_PROMPT},
            {"role": "user", "content": payload},
        ],
        response_format={"type": "json_object"},
    )
    return json.loads(response.choices[0].message.content)

Step 5: Wire everything together

Here is the full script that reads a note, runs extraction, validates the result, and prints the final structured record.

if __name__ == "__main__":
    SAMPLE_NOTE = """
    58-year-old male presents with chest tightness for the past 2 hours.
    History of hypertension and hyperlipidemia. Current meds: Lisinopril 10mg daily,
    Atorvastatin 20mg nightly. Allergic to penicillin (rash).
    Vitals stable. ECG shows ST depression in leads V4-V6.
    Troponin elevated at 0.8 ng/mL. Admitted for NSTEMI management.
    Cardiology consult placed. Plan: aspirin 325mg, clopidogrel 75mg,
    metoprolol 25mg BID. Follow up with cardiology in 1 week.
    """

    print("Extracting...")
    structured = extract_clinical_data(SAMPLE_NOTE)

    print("Validating...")
    validation = validate_extraction(SAMPLE_NOTE, structured)

    final_output = {
        "structured_data": structured,
        "validation": validation,
    }

    print(json.dumps(final_output, indent=2))

Run it

Save the script as clinical_agent.py, replace YOUR_OXLO_API_KEY, and run:

python clinical_agent.py

Expected output:

Extracting...
Validating...
{
  "structured_data": {
    "patient_summary": "58-year-old male with chest tightness, NSTEMI, hypertension, and hyperlipidemia.",
    "diagnoses": ["NSTEMI", "hypertension", "hyperlipidemia"],
    "medications": ["Lisinopril 10mg daily", "Atorvastatin 20mg nightly", "aspirin 325mg", "clopidogrel 75mg", "metoprolol 25mg BID"],
    "allergies": ["penicillin"],
    "procedures": [],
    "follow_up": "Follow up with cardiology in 1 week",
    "red_flags": ["chest tightness", "elevated troponin", "ST depression"]
  },
  "validation": {
    "missing_fields": [],
    "unsupported_items": [],
    "confidence": "high"
  }
}

Wrap-up

This agent gives you a solid foundation for processing clinical text. Two concrete next steps: wire the output into HL7 FHIR Observation and MedicationRequest resources so it slots directly into an EHR pipeline, or run a nightly batch over exported notes. If you scale that batch to thousands of long records, Oxlo.ai's request-based pricing keeps the cost predictable, which matters when a single discharge summary can span thousands of tokens.

Top comments (0)