Patient Education AI Agent: Personalized Health Information Delivery
Build an AI agent that delivers personalized health education by retrieving condition-specific content, adapting reading levels, supporting multiple languages, and tracking patient comprehension.
Why Patient Education Needs AI
Nearly 9 out of 10 adults struggle to understand health information presented in its typical clinical form. When a physician says "you have been diagnosed with Type 2 diabetes mellitus," many patients leave the office without truly understanding what that means for their daily life. A patient education agent bridges this gap by delivering condition-specific information at the right reading level, in the right language, through the right channel — and checking whether the patient actually understood it.
Content Retrieval and Structuring
The agent draws from a curated library of clinical education materials and structures them for the specific patient context:
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
class ReadingLevel(Enum):
ELEMENTARY = "elementary" # Grade 3-5, Flesch-Kincaid 80-100
MIDDLE_SCHOOL = "middle_school" # Grade 6-8, Flesch-Kincaid 60-80
HIGH_SCHOOL = "high_school" # Grade 9-12, Flesch-Kincaid 40-60
COLLEGE = "college" # College level, Flesch-Kincaid 20-40
class ContentFormat(Enum):
TEXT = "text"
BULLET_POINTS = "bullet_points"
QA = "question_answer"
VISUAL = "visual_guide"
@dataclass
class EducationContent:
id: str
condition: str
topic: str
content_text: str
reading_level: ReadingLevel
language: str = "en"
format_type: ContentFormat = ContentFormat.TEXT
sources: list[str] = field(default_factory=list)
last_reviewed: str = ""
@dataclass
class PatientProfile:
patient_id: str
preferred_language: str = "en"
reading_level: ReadingLevel = ReadingLevel.MIDDLE_SCHOOL
conditions: list[str] = field(default_factory=list)
allergies: list[str] = field(default_factory=list)
preferred_format: ContentFormat = ContentFormat.BULLET_POINTS
class ContentRetriever:
def __init__(self, content_library: list[EducationContent]):
self._library = content_library
def find_relevant_content(
self, condition: str, patient: PatientProfile
) -> list[EducationContent]:
matches = []
for content in self._library:
if content.condition.lower() != condition.lower():
continue
if content.language != patient.preferred_language:
continue
if content.reading_level != patient.reading_level:
continue
matches.append(content)
return matches
Reading Level Adaptation
When content at the patient's reading level is not available, the agent adapts existing content. The Flesch-Kincaid readability score guides the transformation:
import re
import math
class ReadabilityAnalyzer:
def flesch_kincaid_grade(self, text: str) -> float:
sentences = self._count_sentences(text)
words = self._count_words(text)
syllables = self._count_syllables(text)
if sentences == 0 or words == 0:
return 0.0
grade = (
0.39 * (words / sentences) +
11.8 * (syllables / words) -
15.59
)
return round(grade, 1)
def _count_sentences(self, text: str) -> int:
return len(re.findall(r'[.!?]+', text)) or 1
def _count_words(self, text: str) -> int:
return len(text.split())
def _count_syllables(self, text: str) -> int:
words = text.lower().split()
count = 0
for word in words:
word = re.sub(r'[^a-z]', '', word)
if not word:
continue
vowels = re.findall(r'[aeiouy]+', word)
syllables = len(vowels) if vowels else 1
if word.endswith('e') and syllables > 1:
syllables -= 1
count += max(syllables, 1)
return count
class ContentAdapter:
SIMPLIFICATION_RULES = {
"hypertension": "high blood pressure",
"diabetes mellitus": "diabetes (high blood sugar)",
"myocardial infarction": "heart attack",
"cerebrovascular accident": "stroke",
"dyspnea": "difficulty breathing",
"edema": "swelling",
"hyperlipidemia": "high cholesterol",
"osteoarthritis": "joint wear and tear",
}
def __init__(self):
self.analyzer = ReadabilityAnalyzer()
def simplify(self, text: str, target_level: ReadingLevel) -> str:
target_grade = {
ReadingLevel.ELEMENTARY: 4.0,
ReadingLevel.MIDDLE_SCHOOL: 7.0,
ReadingLevel.HIGH_SCHOOL: 10.0,
ReadingLevel.COLLEGE: 14.0,
}[target_level]
# Replace medical jargon with plain language
simplified = text
for term, replacement in self.SIMPLIFICATION_RULES.items():
simplified = re.sub(
re.escape(term), replacement, simplified, flags=re.IGNORECASE
)
# Break long sentences
current_grade = self.analyzer.flesch_kincaid_grade(simplified)
if current_grade > target_grade:
simplified = self._break_long_sentences(simplified)
return simplified
def _break_long_sentences(self, text: str) -> str:
sentences = re.split(r'(?<=[.!?])s+', text)
result = []
for sentence in sentences:
words = sentence.split()
if len(words) > 20:
# Split at conjunctions
midpoint = len(words) // 2
first_half = " ".join(words[:midpoint]) + "."
second_half = " ".join(words[midpoint:])
result.extend([first_half, second_half])
else:
result.append(sentence)
return " ".join(result)
Comprehension Tracking
Delivering information is not enough — the agent needs to verify the patient understood it:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
@dataclass
class ComprehensionCheck:
question: str
correct_answer: str
patient_answer: Optional[str] = None
understood: Optional[bool] = None
class ComprehensionTracker:
def generate_checks(self, content: EducationContent) -> list[ComprehensionCheck]:
checks = []
if "medication" in content.topic.lower():
checks.append(ComprehensionCheck(
question="Can you tell me in your own words when you should take this medication?",
correct_answer="[Patient should mention timing and frequency]",
))
checks.append(ComprehensionCheck(
question="What should you do if you miss a dose?",
correct_answer="[Patient should describe the missed-dose protocol]",
))
if "diet" in content.topic.lower():
checks.append(ComprehensionCheck(
question="Can you name two foods you should limit based on what we discussed?",
correct_answer="[Patient should identify restricted food categories]",
))
return checks
def evaluate_response(self, check: ComprehensionCheck, response: str) -> bool:
# In production, use an LLM to semantically compare
# the patient's response against the expected answer
check.patient_answer = response
check.understood = len(response.split()) >= 5 # Simplified heuristic
return check.understood
Delivery and Follow-Up
The agent sends materials through the patient's preferred channel and follows up:
class EducationDelivery:
def prepare_package(
self, patient: PatientProfile, contents: list[EducationContent]
) -> dict:
package = {
"patient_id": patient.patient_id,
"language": patient.preferred_language,
"format": patient.preferred_format.value,
"materials": [],
"follow_up_date": "3 days",
}
for content in contents:
package["materials"].append({
"topic": content.topic,
"content": content.content_text,
"sources": content.sources,
})
return package
FAQ
How does the agent determine a patient's reading level?
The agent uses a combination of signals: the patient's self-reported education level from intake forms, the reading level of their message responses (analyzed with Flesch-Kincaid scoring), and provider notes about communication preferences. It defaults to a 6th-grade reading level, which is the recommended standard for patient health materials per the AMA.
Can the agent deliver education materials in languages other than English?
Yes, but with important caveats. The content library must contain clinically reviewed translations — not machine-translated versions. The agent should never auto-translate medical content with general-purpose translation tools, as medical terminology requires specialized translation. When content is not available in the patient's preferred language, the agent flags this for staff to arrange interpreter services.
How does the agent handle patients who do not want to engage with education materials?
The agent respects patient autonomy. It documents that education was offered and declined, which satisfies clinical documentation requirements. It can offer alternative formats (a short video instead of a document, for example) but does not repeatedly push materials on an uninterested patient.
#HealthcareAI #PatientEducation #HealthLiteracy #ContentPersonalization #Python #AgenticAI #LearnAI #AIEngineering
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.