How to Intermediate · 4 min read

How to extract medical information with LLM

Quick answer
Use a large language model like gpt-4o-mini with structured extraction techniques by prompting it to identify and extract medical information. Combine OpenAI SDK calls with a pydantic response model to parse and validate the extracted data reliably.

PREREQUISITES

  • Python 3.8+
  • OpenAI API key (free tier works)
  • pip install openai>=1.0 pydantic

Setup

Install the required Python packages and set your OpenAI API key as an environment variable.

  • Install packages: openai and pydantic
  • Set OPENAI_API_KEY in your environment
bash
pip install openai pydantic
output
Collecting openai
Collecting pydantic
Successfully installed openai-1.x.x pydantic-2.x.x

Step by step

This example uses the OpenAI SDK with gpt-4o-mini to extract medical information from a clinical note. We define a pydantic model to parse the structured response.

python
import os
from openai import OpenAI
from pydantic import BaseModel

# Define a Pydantic model for structured medical info extraction
class MedicalInfo(BaseModel):
    patient_name: str
    age: int
    diagnosis: str
    medications: list[str]

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

prompt = (
    "Extract the following medical information from the clinical note:\n"
    "Patient name, age, diagnosis, and medications.\n"
    "Clinical note: 'John Doe is a 45-year-old male diagnosed with hypertension and diabetes. "
    "He is currently prescribed lisinopril and metformin.'\n"
    "Respond in JSON format with keys: patient_name, age, diagnosis, medications."
)

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": prompt}]
)

text = response.choices[0].message.content
print("Raw LLM output:", text)

# Parse the JSON output using Pydantic
import json

try:
    data = json.loads(text)
    medical_info = MedicalInfo(**data)
    print("Parsed medical info:", medical_info)
except Exception as e:
    print("Failed to parse medical info:", e)
output
Raw LLM output: {"patient_name": "John Doe", "age": 45, "diagnosis": "hypertension and diabetes", "medications": ["lisinopril", "metformin"]}
Parsed medical info: patient_name='John Doe' age=45 diagnosis='hypertension and diabetes' medications=['lisinopril', 'metformin']

Common variations

You can adapt this approach by:

  • Using async calls with await client.chat.completions.create(...) for asynchronous workflows.
  • Switching to other models like claude-3-5-haiku-20241022 with the anthropic SDK for Claude-based extraction.
  • Streaming partial responses for large clinical notes using stream=True in the OpenAI SDK.
  • Extending the pydantic model to include nested fields like lab results or vital signs.
python
import asyncio
import os
from openai import OpenAI

async def async_extract():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    prompt = "Extract patient name and diagnosis from: 'Jane Smith, 60, diagnosed with asthma.'"
    response = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    print(response.choices[0].message.content)

asyncio.run(async_extract())
output
Raw LLM output: {"patient_name": "Jane Smith", "diagnosis": "asthma"}

Troubleshooting

  • If the LLM output is not valid JSON, ensure your prompt explicitly requests JSON format and consider adding examples.
  • If parsing fails, catch exceptions and log the raw output for debugging.
  • For incomplete or partial data, increase max_tokens or split large notes into smaller chunks.
  • Check your API key and environment variables if authentication errors occur.

Key Takeaways

  • Use explicit prompts requesting JSON output for reliable medical data extraction.
  • Validate and parse LLM responses with pydantic models for structured data.
  • Leverage async and streaming options for scalable and responsive extraction workflows.
Verified 2026-04 · gpt-4o-mini, claude-3-5-haiku-20241022
Verify ↗