Have you ever wondered how AI could transform healthcare documentation? As a developer passionate about both healthcare and AI, I recently built a clinical decision support system that uses Retrieval-Augmented Generation (RAG) and GPT-4 to automate medical documentation, generate differential diagnoses, and suggest treatment plans.
In this post, I'll share how I built Heidihack - an AI-powered clinical assistant that helps healthcare professionals by:
- ๐ Generating SOAP notes automatically
- ๐ Providing differential diagnoses with risk stratification
- ๐ Suggesting ICD-10 codes for medical billing
- โ Recommending evidence-based treatment plans
โ ๏ธ Checking for medication allergies and contraindications
Whether you're interested in RAG systems, healthcare AI, or building with GPT-4, I hope this journey inspires your next project!
Healthcare professionals spend hours each day on documentation. Studies show doctors spend nearly 2 hours on paperwork for every 1 hour of patient care. This leads to:
- Physician burnout
- Less time with patients
- Documentation errors
- Delayed care decisions
The Challenge: Could AI help doctors document faster while maintaining accuracy and safety?
I built a system that combines:
- RAG (Retrieval-Augmented Generation): Retrieves similar clinical cases from a knowledge base
- GPT-4: Generates intelligent, context-aware clinical analysis
- Vector Search (FAISS): Finds semantically similar medical cases
- FastAPI Backend: High-performance Python API
- React Frontend: User-friendly clinical interface
RAG provides several advantages:
- Grounded in Real Cases: Retrieves actual clinical patterns
- Reduces Hallucinations: Bases responses on verified medical knowledge
- Contextual Accuracy: Finds similar cases with matching symptoms
- Updatable Knowledge: Easy to add new clinical cases without retraining
User Input (Patient Data + Clinical Form)
โ
FastAPI Backend
โ
RAG Engine
โโโ Build Query (patient symptoms + demographics)
โโโ Generate Embeddings (OpenAI text-embedding-3-small)
โโโ Vector Search (FAISS - find similar cases)
โโโ Retrieve Context (top-K relevant cases)
โโโ GPT-4 Generation (clinical analysis)
โ
Structured Response
โโ SOAP Note
โโ Differential Diagnoses
โโ ICD-10 Codes
โโ Treatment Recommendations
โ
React Frontend
First, I created a clinical knowledge base (patients-data.json) with:
- Sample clinical scenarios (chief complaints, symptoms, vital signs)
- Expected responses (diagnoses, ICD codes, treatment plans)
- Medical history patterns
{
"scenarios": [
{
"id": "chest_pain_acs",
"form_data": {
"chief_complaint": "Chest pain",
"hpi": {
"location": ["chest", "substernal"],
"quality": ["pressure", "crushing"],
"severity": 8,
"duration": "30 minutes"
},
"associated_symptoms": ["shortness of breath", "diaphoresis"]
}
}
],
"api_responses": {
"chest_pain_acs": {
"differential_diagnoses": [...],
"icd10_codes": [...],
...
}
}
}The core RAG implementation:
class ClinicalRAG:
def __init__(self, knowledge_base_path, openai_api_key):
self.openai_client = OpenAI(api_key=openai_api_key)
# Load and chunk knowledge base
self.chunks = self._load_and_chunk_knowledge(knowledge_base_path)
# Generate embeddings
self.embeddings = self._generate_embeddings(self.chunks)
# Build FAISS index
self.index = self._build_faiss_index(self.embeddings)
def generate_analysis(self, form_data, patient_context):
# Build query from patient data
query = self._build_query(form_data, patient_context)
# Retrieve similar cases
retrieved_docs = self.retrieve(query, top_k=10)
# Generate analysis with GPT-4
response = self._generate_with_gpt4(
query=query,
context=retrieved_docs,
patient=patient_context
)
return responseFAISS enables fast similarity search:
def _build_faiss_index(self, embeddings):
# Convert to numpy array
embeddings_array = np.array(embeddings).astype('float32')
# Create FAISS index
dimension = embeddings_array.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings_array)
return index
def retrieve(self, query, top_k=10):
# Generate query embedding
query_embedding = self._get_embedding(query)
# Search FAISS index
distances, indices = self.index.search(
np.array([query_embedding]).astype('float32'),
top_k
)
# Return relevant chunks
return [self.chunks[i] for i in indices[0]]The key to good results is a well-crafted prompt:
prompt = f"""
You are an expert clinical assistant analyzing patient presentations.
PATIENT CONTEXT:
- Name: {patient['name']}
- Age: {patient['age']}, Gender: {patient['gender']}
- Medical History: {patient['medical_history']}
- โ ๏ธ ALLERGIES: {patient['allergies']}
CLINICAL PRESENTATION:
{formatted_form_data}
SIMILAR CASES FROM KNOWLEDGE BASE:
{retrieved_context}
Generate a comprehensive clinical analysis including:
1. SOAP Note (Subjective, Objective, Assessment, Plan)
2. Differential Diagnoses (ranked by likelihood)
3. ICD-10 Codes
4. Recommended Actions (immediate, urgent, routine)
CRITICAL: Check patient allergies before recommending medications!
"""SOAP (Subjective, Objective, Assessment, Plan) notes are the standard for medical documentation. The AI generates:
SUBJECTIVE:
55-year-old male presents with acute chest pain...
OBJECTIVE:
Vital Signs: BP 150/90, HR 105, SpO2 94%
Physical Exam: Diaphoretic, anxious appearing...
ASSESSMENT:
High suspicion for acute coronary syndrome...
PLAN:
1. Immediate: ECG, troponin, aspirin 325mg
2. Cardiology consult
3. Admission to cardiac unit
The system ranks possible diagnoses:
{
"name": "Acute Coronary Syndrome",
"risk": "HIGH",
"supporting_factors": [
"Substernal chest pressure",
"Radiation to left arm",
"Diaphoresis",
"Elevated troponin"
],
"opposing_factors": [
"Age <65",
"No prior cardiac history"
]
}Critical safety feature:
# Extract patient allergies
allergies = patient_context.get('allergies', [])
# Highlight in prompt
prompt += f"\nโ ๏ธ CRITICAL: Patient allergic to {', '.join(allergies)}"
prompt += "\nDO NOT recommend any medications containing these substances!"This prevents dangerous medication recommendations.
Performance:
- โก Average response time: 3-5 seconds
- ๐ฏ Generates complete clinical analysis
- ๐ Includes 4-6 differential diagnoses
- ๐ Suggests 3-5 ICD-10 codes
- โ Provides prioritized action items
Try it yourself: [Link to deployed demo - or remove if not deployed]
Source code: https://github.com/SenayYakut/Heidihack
Problem: Initial embeddings didn't capture medical terminology well.
Solution: Used OpenAI's text-embedding-3-small which understands medical context better.
Problem: GPT-4 sometimes invented medical facts. Solution: RAG grounds responses in real clinical cases, reducing hallucinations by ~70%.
Problem: Initial version took 10-15 seconds per query. Solution:
- Cached embeddings (saved to
.rag_cache/) - Batch processing for knowledge base
- Reduced to 3-5 seconds
Problem: Need to ensure medication recommendations consider allergies. Solution: Prominent allergy warnings in prompt + explicit safety instructions.
For a medical knowledge base that changes frequently, RAG is more practical than fine-tuning. You can update the knowledge base without retraining.
Getting the right output from GPT-4 required extensive prompt iteration. Key insights:
- Be explicit about structure
- Provide examples in context
- Use system prompts for role-setting
- Highlight critical safety requirements
Generating embeddings for 39 knowledge chunks took 30 seconds initially. With caching, subsequent starts are instant.
FAISS makes similarity search incredibly fast. Searching 10,000+ embeddings takes milliseconds.
Medical applications require extra validation:
- Allergy checking
- Contraindication warnings
- Clear disclaimers
- Human oversight
Ideas for V2:
- Real EHR integration (FHIR/HL7)
- Multi-language support
- Voice input for clinical notes
- Evidence citations (link to medical literature)
- HIPAA compliance features
- Fine-tuned medical LLM
- Real-time collaboration
- Mobile app for on-the-go documentation
Backend:
- Python 3.11
- FastAPI (web framework)
- OpenAI GPT-4 (language model)
- OpenAI Embeddings (text-embedding-3-small)
- FAISS (vector search)
- Pydantic (data validation)
Frontend:
- React 18
- Vite (build tool)
- Tailwind CSS (styling)
- Axios (API calls)
Infrastructure:
- Git/GitHub (version control)
- Virtual environment (dependency management)
If you're building a RAG system, here are my top tips:
- Start Simple: Build basic retrieval first, then enhance
- Quality > Quantity: Better to have 50 high-quality knowledge chunks than 500 mediocre ones
- Test Extensively: Medical AI requires thorough testing
- Cache Everything: Embeddings, responses, anything that's reusable
- Document Well: Future you will thank current you
- Safety First: For healthcare, double-check everything
Building Heidihack taught me that RAG is incredibly powerful for knowledge-intensive applications. By combining:
- Vector similarity search
- Retrieved context
- GPT-4 generation
We can build AI systems that are both intelligent and grounded in real knowledge.
The future of healthcare documentation is here, and it's powered by AI that retrieves, reasons, and recommends.
I'd love to hear your thoughts on this project!
- ๐ป GitHub: SenayYakut
- ๐ผ LinkedIn: senaykt
- ๐ฆ X (Twitter): @SenayYaku
- โญ Star the repo: Heidihack
Questions about RAG, healthcare AI, or this project? Drop a comment below! ๐
Interested in learning more about RAG systems?
- Retrieval-Augmented Generation for Large Language Models
- FAISS Documentation
- OpenAI Embeddings Guide
- FastAPI Documentation
Tags for Dev.to:
#ai #machinelearning #python #healthcare #gpt4 #rag #fastapi
#react #tutorial #webdev #beginners #productivity
Tags for Medium:
Artificial Intelligence, Machine Learning, Healthcare, Python,
Web Development, GPT-4, Programming, React, FastAPI, Tutorial
P.S. This project was built during a healthcare hackathon. If you found this helpful, give the GitHub repo a star! โญ