06. SOAP Note Generation
SOAP (Subjective, Objective, Assessment, Plan) notes provide the standard format for documenting patient encounters in many healthcare settings. Generating SOAP notes from encounter data—either raw transcripts or structured intake forms—offers significant workflow improvement.
The subjective section captures patient-reported symptoms and history. The objective section contains measurable findings—vital signs, exam results, lab values. The assessment synthesizes findings into clinical impressions. The plan outlines treatment approach.
# soap_generator.py
from dataclasses import dataclass
from typing import Optional, List
@dataclass
class SOAPNote:
subjective: str
objective: str
assessment: str
plan: str
class SOAPNoteGenerator:
"""Generate SOAP-formatted clinical notes from encounter data."""
SOAP_TEMPLATE = """Generate a SOAP note from the following encounter data.
Use professional clinical language appropriate for medical records.
Patient Information:
{patient_info}
Chief Complaint:
{chief_complaint}
HPI (History of Present Illness):
{hpi}
Review of Systems:
{ros}
Vital Signs:
{vitals}
Physical Exam Findings:
{physical_exam}
Lab Results:
{lab_results}
Assessment and Plan (if available):
{assessment_plan}
Format the output as:
S: [Subjective section]
O: [Objective section]
A: [Assessment section]
P: [Plan section]
"""
def __init__(self, ollama_client, model: str = "llama3.2"):
self.ollama = ollama_client
self.model = model
def generate_from_encounter(self, encounter_data: dict) -> SOAPNote:
"""Generate SOAP note from structured encounter data."""
# Validate required fields
required = ["chief_complaint", "hpi"]
for field in required:
if not encounter_data.get(field):
raise ValueError(f"Missing required field: {field}")
prompt = self.SOAP_TEMPLATE.format(
patient_info=encounter_data.get("patient_info", "Not provided"),
chief_complaint=encounter_data.get("chief_complaint"),
hpi=encounter_data.get("hpi"),
ros=encounter_data.get("ros", "Not provided"),
vitals=encounter_data.get("vitals", "Not documented"),
physical_exam=encounter_data.get("physical_exam", "Not documented"),
lab_results=encounter_data.get("lab_results", "Results pending"),
assessment_plan=encounter_data.get("assessment_plan", "")
)
response = self.ollama.generate(prompt, model=self.model)
return self._parse_soap_response(response)
def generate_from_transcript(self, transcript: str,
context: Optional[dict] = None) -> SOAPNote:
"""Generate SOAP note from conversation transcript."""
prompt = f"""Convert this patient encounter transcript into a SOAP note.
Extract relevant clinical information from the conversation.
Use professional clinical language.
Transcript:
{transcript}
Additional Context (if any):
{context or 'None provided'}
Format as:
S: [Subjective]
O: [Objective]
A: [Assessment]
P: [Plan]"""
response = self.ollama.generate(prompt)
return self._parse_soap_response(response)
def _parse_soap_response(self, response: str) -> SOAPNote:
"""Parse LLM output into structured SOAPNote object."""
sections = {"S": "", "O": "", "A": "", "P": ""}
current_section = None
for line in response.split("\n"):
if line.strip().startswith("S:"):
current_section = "S"
line = line[2:]
elif line.strip().startswith("O:"):
current_section = "O"
line = line[2:]
elif line.strip().startswith("A:"):
current_section = "A"
line = line[2:]
elif line.strip().startswith("P:"):
current_section = "P"
line = line[2:]
if current_section:
sections[current_section] += line + "\n"
return SOAPNote(
subjective=sections["S"].strip(),
objective=sections["O"].strip(),
assessment=sections["A"].strip(),
plan=sections["P"].strip()
)
A critical failure mode: the model may generate plausible but clinically inappropriate assessments based on incomplete information. SOAP notes generated from encounter data must clearly indicate uncertainty when diagnoses are implied rather than confirmed. Add system prompts instructing the model to use "consistent with" language when suggesting diagnoses.
Collect a transcript from a standardized patient encounter. Generate a SOAP note, then compare against a gold-standard note written by a clinician. Identify discrepancies in clinical language and assessment accuracy.