AI-powered clinical documentation tool that converts unstructured clinical input into professionally formatted SOAP notes compliant with medical documentation standards.
Key Capabilities:
✅ Use this skill when:
❌ Do NOT use when:
operative-report-generator⚠️ ALWAYS Required:
Upstream Skills:
medical-scribe-dictation: Convert physician verbal dictation to text inputehr-semantic-compressor: Summarize lengthy EHR notes for SOAP generationdicom-anonymizer: Prepare imaging reports for SOAP inclusionaudio-script-writer: Convert audio recordings to text formatDownstream Skills:
medical-email-polisher: Professional communication of SOAP summaries to patientsclinical-data-cleaner: Standardize extracted data for research databaseshipaa-compliance-auditor: Verify de-identification before sharing documentationdischarge-summary-writer: Generate discharge summaries from SOAP encountersreferral-letter-generator: Create referral letters based on Assessment and Plan sectionsComplete Workflow:
text
Medical Scribe Dictation (audio→text) →
Automated SOAP Note Generator (this skill) →
Physician Review →
EHR Entry /
Medical Email Polisher (patient communication) /
Referral Letter Generator (referrals)
Handle various input formats and prepare for NLP analysis:
python
from scripts.soap_generator import SOAPNoteGenerator
generator = SOAPNoteGenerator()
# Process text input
soap_note = generator.generate(
input_text="Patient presents with 2-day history of chest pain, radiating to left arm...",
patient_id="P12345",
encounter_date="2026-01-15",
provider="Dr. Smith"
)
# Process from audio transcript
soap_note = generator.generate_from_transcript(
transcript_path="consultation_transcript.txt",
patient_id="P12345"
)
Input Preprocessing Steps:
Parameters:
ParameterTypeRequiredDescriptionDefaultinput_textstrYes*Raw clinical text or dictationNonetranscript_pathstrYes*Path to transcript fileNonepatient_idstrNoPatient identifier (MUST be de-identified for testing)Noneencounter_datestrNoDate in ISO 8601 format (YYYY-MM-DD)Current dateproviderstrNoHealthcare provider nameNonespecialtystrNoMedical specialty context"general"verboseboolNoInclude confidence scoresFalse
*Either input_text or transcript_path required
Best Practices:
Identify and extract medical concepts from unstructured text:
python
# Extract entities with context
entities = generator.extract_medical_entities(
"Patient has history of hypertension and diabetes,
currently taking lisinopril 10mg daily and metformin 500mg BID"
)
# Returns structured entities:
# {
# "diagnoses": ["hypertension", "diabetes mellitus"],
# "medications": [
# {"name": "lisinopril", "dose": "10mg", "frequency": "daily"},
# {"name": "metformin", "dose": "500mg", "frequency": "BID"}
# ]
# }
Entity Types Recognized:
CategoryExamplesNotesDiagnosesdiabetes, hypertension, pneumoniaICD-10 compatible where possibleSymptomschest pain, headache, nauseaIncludes severity modifiersMedicationsmetformin, lisinopril, aspirinExtracts dose, route, frequencyProceduresECG, CT scan, blood drawIncludes body siteAnatomyleft arm, chest, abdomenLaterality and locationLab Valuesglucose 120, BP 140/90Units and reference rangesTemporalyesterday, 3 days ago, chronicNormalized to relative dates
Common Issues and Solutions:
Issue: Missed medications
Issue: Ambiguous abbreviations
Issue: Misspelled drug names
Automatically categorize sentences into appropriate SOAP sections:
python
# Classify content into SOAP sections
classified = generator.classify_soap_sections(
"Patient reports chest pain for 2 days. Physical exam shows BP 140/90.
Likely angina. Schedule stress test and start aspirin 81mg daily."
)
# Output structure:
# {
# "Subjective": ["Patient reports chest pain for 2 days"],
# "Objective": ["Physical exam shows BP 140/90"],
# "Assessment": ["Likely angina"],
# "Plan": ["Schedule stress test", "start aspirin 81mg daily"]
# }
Classification Rules:
SectionContent TypeExamplesS - SubjectivePatient-reported information"Patient states...", "Patient reports...", "Complains of..."O - ObjectiveObservable/measurable findingsVital signs, physical exam, lab results, imagingA - AssessmentClinical interpretationDiagnosis, differential, clinical impressionP - PlanActions to be takenMedications, procedures, follow-up, patient education
Multi-label Handling: Some sentences span multiple sections (e.g., "Patient reports chest pain [S], which was sharp and 8/10 [S], with ECG showing ST elevation [O]")
Best Practices:
Parse and normalize timeline information:
python
# Extract temporal relationships
timeline = generator.extract_temporal_info(
"Patient had chest pain starting 3 days ago, worsening since yesterday.
Had similar episode 2 months ago that resolved with rest."
)
# Returns:
# {
# "onset": "3 days ago",
# "progression": "worsening",
# "previous_episodes": [
# {"time": "2 months ago", "resolution": "with rest"}
# ]
# }
Temporal Elements Extracted:
Normalization: Converts relative dates to standardized format:
Critical for accurate medical documentation:
python
# Detect negations and uncertainties
analysis = generator.analyze_certainty(
"Patient denies chest pain. No shortness of breath.
Possibly had fever yesterday but not sure."
)
# Identifies:
# - "denies chest pain" → Negative finding (important!)
# - "No shortness of breath" → Negative finding
# - "Possibly had fever" → Uncertain finding (flag for verification)
Detection Categories:
TypeCuesActionNegationdenies, no, without, absentMark as negative findingUncertaintypossibly, maybe, uncertain, ?Flag for physician reviewHypotheticalif, would, couldNote as conditionalFamily Historyfamily history of, mother hadSeparate from patient findings
⚠️ Critical: Negation errors are high-risk (e.g., missing "denies" → documenting symptom they don't have)
Produce final formatted output:
python
# Generate complete SOAP note
soap_output = generator.generate_soap_document(
structured_data=classified,
format="markdown", # Options: markdown, json, hl7, text
include_metadata=True
)
Output Format:
markdown
# SOAP Note
**Patient ID:** P12345
**Date:** 2026-01-15
**Provider:** Dr. Smith
## Subjective
Patient reports [extracted symptoms with duration]. History of [chronic conditions].
Currently taking [medications]. Patient denies [negative findings].
## Objective
**Vital Signs:** [BP, HR, RR, Temp, O2Sat]
**Physical Examination:** [Exam findings by system]
**Laboratory/Data:** [Relevant results]
## Assessment
[Primary diagnosis/differential]
[Clinical reasoning summary]
## Plan
1. [Action item 1]
2. [Action item 2]
3. [Follow-up instructions]
---
*Generated by AI. REQUIRES PHYSICIAN REVIEW before entry into patient record.*
Export Formats:
FormatUse CaseNotesMarkdownHuman review, documentationDefault, readableJSONSystem integration, researchStructured dataHL7 FHIREHR integrationHealthcare standardPlain TextSimple documentationMinimal formattingCSVData analysis, researchTabular data export
From audio dictation to reviewed SOAP note:
bash
# Step 1: Process audio to text (using medical-scribe-dictation or external)
# Assuming you have transcript: consultation.txt
# Step 2: Generate SOAP note
python scripts/main.py \
--input-file consultation.txt \
--patient-id P12345 \
--provider "Dr. Smith" \
--specialty "cardiology" \
--output soap_draft.md \
--format markdown
# Step 3: Review output
# - Open soap_draft.md
# - Verify medical accuracy
# - Correct any errors
# - Add missing clinical reasoning
# Step 4: Finalize (after physician approval)
# - Copy approved content to EHR
# - Or use for patient communication
Python API Usage:
python
from scripts.soap_generator import SOAPNoteGenerator
from scripts.post_processor import ReviewFormatter
# Initialize
generator = SOAPNoteGenerator()
reviewer = ReviewFormatter()
# Generate draft
with open("dictation.txt", "r") as f:
raw_text = f.read()
draft = generator.generate(
input_text=raw_text,
patient_id="P12345",
encounter_date="2026-01-15",
provider="Dr. Smith",
specialty="internal_medicine"
)
# Add physician review markers
marked_draft = reviewer.add_review_markers(draft)
# Save with warning header
reviewer.save_with_disclaimer(
marked_draft,
output_path="soap_draft_review.md",
disclaimer="REQUIRES PHYSICIAN REVIEW - NOT FOR DIRECT ENTRY"
)
Expected Output Files:
text
output/
├── soap_draft.md # Generated SOAP note
├── entities_extracted.json # Structured medical entities
├── classification_report.txt # Confidence scores for each section
└── review_checklist.md # Items requiring manual verification
Pre-generation Checks:
During Generation:
Post-generation Review (PHYSICIAN MUST CHECK):
Before EHR Entry:
Input Quality Issues:
Medical Accuracy Issues:
Documentation Issues:
Compliance Issues:
Process Issues:
Problem: Poor entity recognition
references/medical_terminology.md for supported termsProblem: Wrong SOAP classification
Problem: Missing temporal information
Problem: Inappropriate certainty level
Problem: Formatting errors in output
Problem: Processing fails or hangs
Available in references/ directory:
clinical_guidelines.md - Standards for medical documentationsample_soap_notes.md - Example SOAP notes by specialtymedical_terminology.md - Supported medical terms and abbreviationsnlp_pipeline_documentation.md - Technical details of NLP processinghipaa_compliance_guide.md - Guidelines for safe handling of PHIspecialty_specific_templates.md - Templates for cardiology, orthopedics, etc.Located in scripts/ directory:
main.py - CLI interface for SOAP generationsoap_generator.py - Core SOAP generation logicentity_extractor.py - Medical NER modulesoap_classifier.py - Section classification enginetemporal_parser.py - Timeline extractionnegation_detector.py - Negation and uncertainty detectionpost_processor.py - Output formatting and review markersbatch_processor.py - Process multiple encountersvalidator.py - Quality checks and compliance validationTypical Processing Time:
System Requirements:
Supported Input Sizes:
ParameterTypeDefaultRequiredDescription--input, -istring-NoInput clinical text directly--input-file, -fstring-NoPath to input text file--output, -ostring-NoOutput file path--patient-id, -pstring-NoPatient identifier--providerstring-NoHealthcare provider name--formatstringmarkdownNoOutput format (markdown, json)
bash
# Generate SOAP from text
python scripts/main.py --input "Patient reports chest pain..." --output note.md
# From file
python scripts/main.py --input-file consultation.txt --patient-id P12345 --provider "Dr. Smith"
# JSON output
python scripts/main.py --input-file notes.txt --format json --output note.json
Risk IndicatorAssessmentLevelCode ExecutionPython script executed locallyMediumNetwork AccessNo external API callsLowFile System AccessRead input files, write output filesLowData ExposureMay process PHI (Protected Health Information)HighHIPAA ComplianceMust be used in compliant environmentHigh
bash
# Python 3.7+
# No external packages required (uses standard library)
Current Stage: Draft
Next Review Date: 2026-03-06
Known Issues: None
Planned Improvements:
⚠️ CRITICAL REMINDER: All AI-generated SOAP notes REQUIRE physician review and approval before entry into patient records. This tool assists documentation but does not replace clinical judgment or medical decision-making.