Skip to content

Repository files navigation

Healthcare Knowledge Navigator

A production-ready medical RAG (Retrieval-Augmented Generation) assistant that answers clinical questions with evidence-based citations, confidence scoring, and real-time source attribution — grounded in PubMed research.

MediChat AI Python React FastAPI Pinecone OpenAI License

image

What it does

You type a clinical question. The system retrieves the most relevant PubMed abstracts from a vector database, ranks them by evidence quality and recency, then uses GPT-4o-mini to write a cited answer grounded entirely in that retrieved evidence — not in the model's memory.

Every fact in the answer links to a numbered source card. Every source card shows evidence type, year, and a confidence score. The system refuses to fabricate information not present in the retrieved context.


One-command setup

git clone https://github.com/your-username/Healthcare_RAG.git
cd Healthcare_RAG
bash setup.sh

That single command:

  1. Checks Python and Node.js versions
  2. Validates your .env API keys
  3. Installs all Python and Node packages
  4. Creates the Pinecone vector index
  5. Ingests 220 real PubMed articles across 3 medical topics
  6. Starts the FastAPI backend on localhost:8000
  7. Starts the React frontend on localhost:5173

Open http://localhost:5173 and start asking clinical questions.


Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                         USER INTERFACE (React)                          │
│                                                                         │
│  ┌──────────────┐  ┌─────────────────────────────┐  ┌───────────────┐   │
│  │   Sidebar    │  │        Chat Panel            │  │  Sources     │   │
│  │              │  │                              │  │  Panel       │   │
│  │ • Chat hist  │  │ • Message bubbles            │  │              │   │
│  │ • Search     │  │ • Inline citation badges ¹²³ │  │ • Numbered   │   │
│  │ • Doc upload │  │ • Confidence ring %          │  │   source     │   │
│  │ • New chat   │  │ • Copy button                │  │   cards      │   │
│  │              │  │ • Suggested chips            │  │ • Evidence   │   │
│  └──────────────┘  └──────────────┬──────────────┘   │   type tags  │   │
│                                   │                  │ • Copy APA   │   │
│                                   │ POST /query      │ • EV legend  │   │
└───────────────────────────────────┼──────────────────┴───────────────┘  │
                                    │
                    ════════════════╪════════════════
                         HTTP · localhost:8000
                    ════════════════╪════════════════
                                    │
┌───────────────────────────────────▼────────────────────────────────────┐
│                        FASTAPI BACKEND (backend_app.py)                │
│                                                                        │
│   POST /query  →  validates request  →  calls Retriever                │
│   GET  /stats  →  returns Pinecone vector count                        │
│   CORS enabled for localhost:5173                                      │
└───────────────────────────────────┬────────────────────────────────────┘
                                    │
┌───────────────────────────────────▼────────────────────────────────────┐
│                      RAG PIPELINE (retrieval/retriever.py)             │
│                                                                        │
│   1. EMBED QUERY                                                       │
│      User question  ──►  OpenAI text-embedding-3-small                 │
│                          (1536-dimension vector)                       │
│                                    │                                   │
│   2. VECTOR SEARCH                 ▼                                   │
│      Query vector   ──►  Pinecone cosine similarity search             │
│                          top-20 candidate chunks returned              │
│                                    │                                   │
│   3. RERANK BY CONFIDENCE          ▼                                   │
│      Each chunk scored:                                                │
│        score = (similarity × 0.5)                                      │
│              + (evidence_weight × 0.3)                                 │
│              + (recency_weight × 0.2)                                  │
│                                                                        │
│      Evidence weights:                                                 │
│        systematic_review → 1.00   rct           → 0.85                 │
│        clinical_trial    → 0.80   guideline     → 0.80                 │
│        fda_label         → 0.75   cohort_study  → 0.65                 │
│        abstract          → 0.55   case_report   → 0.40                 │
│                                    │                                   │
│   4. BUILD CONTEXT                 ▼                                   │
│      Top 5 chunks formatted as numbered [1][2][3] context              │
│                                    │                                   │
│   5. GENERATE ANSWER               ▼                                   │
│      Context + question  ──►  GPT-4o-mini                              │
│      System prompt forces: cite [1][2], stay in context,               │
│      never fabricate, flag conflicting sources                         │
│                                    │                                   │
│   6. RETURN STRUCTURED RESPONSE    ▼                                   │
│      { answer, citations[], confidence_score,                          │
│        confidence_label, sources_used, disclaimer }                    │
└───────────────────────────────────┬────────────────────────────────────┘
                                    │
        ┌───────────────────────────┴──────────────────────────┐
        │                                                      │
        ▼                                                      ▼
┌──────────────────────┐                         ┌─────────────────────┐
│   PINECONE CLOUD     │                         │   OPENAI API        │
│   (Vector Database)  │                         │                     │
│                      │                         │  Embeddings:        │
│  Index: healthcare-  │                         │  text-embedding-    │
│  rag                 │                         │  3-small            │
│  Dimension: 1536     │                         │  (1536 dims)        │
│  Metric: cosine      │                         │                     │
│  Cloud: AWS          │                         │  Chat:              │
│  Region: us-east-1   │                         │  gpt-4o-mini        │
│                      │                         │  (answer gen)       │
│  Each vector stores: │                         │                     │
│  • 1536 floats       │                         └─────────────────────┘
│  • source            │
│  • pmid              │
│  • title             │
│  • year              │
│  • evidence_type     │
│  • url               │
│  • text (800 chars)  │
└──────────────────────┘


INGESTION PIPELINE (run once, then on-demand)
═════════════════════════════════════════════

  PubMed E-utilities API (free, no key)
          │
          │  esearch: query → PMIDs
          │  efetch:  PMIDs → XML
          ▼
  PubMedIngestor
  • Parses XML → PubMedArticle objects
  • Extracts: title, abstract, authors,
    journal, year, pub_types, MeSH terms
  • Classifies evidence type from pub_types
          │
          ▼
  Chunker
  • Strategy 1: Short abstract → 1 chunk
  • Strategy 2: Structured abstract (BACKGROUND/
    METHODS/RESULTS) → split at section headers
  • Strategy 3: Long text → sliding window
    with 50-word overlap between chunks
          │
          ▼
  Embedder
  • Batch embeds chunk text via OpenAI API
  • 100 chunks per API call
  • Returns list of 1536-dim vectors
          │
          ▼
  PineconeStore.upsert()
  • Batches 100 vectors per upsert call
  • ID = source_pmid_chunkN (idempotent)
  • Metadata stored alongside vector
  • Re-runs are safe — upsert overwrites

Project structure

Healthcare_RAG/
│
├── setup.sh                    ← One-command setup and launch
├── backend_app.py              ← FastAPI server (wraps Retriever)
├── .env                        ← Your API keys (never committed)
├── .gitignore
├── requirements.txt
│
├── config/
│   └── settings.py             ← All settings loaded from .env
│
├── ingestion/
│   ├── pubmed_ingestor.py      ← PubMed E-utilities API client
│   └── chunker.py              ← 3-strategy medical text chunker
│
├── embeddings/
│   ├── embedder.py             ← OpenAI embedding wrapper
│   └── pinecone_store.py       ← Pinecone index manager
│
├── retrieval/
│   ├── confidence.py           ← Evidence scoring formula
│   └── retriever.py            ← Full RAG pipeline
│
├── scripts/
│   ├── setup.py                ← Creates Pinecone index
│   └── ingest.py               ← CLI ingestion runner
│
├── files/                      ← React frontend (Vite)
│   ├── src/
│   │   ├── App.jsx
│   │   ├── index.css
│   │   ├── api/
│   │   │   └── client.js
│   │   └── components/
│   │       ├── Sidebar.jsx
│   │       ├── ChatPanel.jsx
│   │       ├── MessageBubble.jsx
│   │       └── SourcesPanel.jsx
│   ├── package.json
│   └── vite.config.js
│
└── tests/
    ├── test_component1.py      ← PubMed ingestor tests
    ├── test_component2.py      ← Chunker tests
    ├── test_component3.py      ← Embedder tests
    ├── test_component4.py      ← Pinecone store tests
    ├── test_component5.py      ← Retriever + confidence tests
    └── test_component6.py      ← Full system integration test

Data sources

Source What it provides API Cost
PubMed E-utilities 36M+ biomedical abstracts, RCTs, systematic reviews Free, no key Free
ClinicalTrials.gov 500K+ trial protocols and results Free, no key Free
FDA OpenFDA Drug labels, adverse events, prescribing info Free, no key Free

All three sources are freely available and require no registration. PubMed is the primary source used in the default setup.


API keys required

Service Purpose Free tier Get it
Pinecone Vector database 1 index, 2GB (enough for ~1M vectors) app.pinecone.io
OpenAI Embeddings + answer generation Pay-as-you-go (~$0.04 per 10K abstracts) platform.openai.com

Manual setup (without setup.sh)

1. Clone and configure

git clone https://github.com/your-username/Healthcare_RAG.git
cd Healthcare_RAG
cp .env.example .env
# Edit .env with your real keys

2. Install Python dependencies

pip3 install pinecone==3.2.2 openai==1.30.0 requests==2.32.3 \
  python-dotenv==1.0.1 fastapi==0.111.0 uvicorn==0.30.0 \
  pydantic==2.7.1 tenacity==8.3.0 tqdm==4.66.4

3. Create Pinecone index

python3 scripts/setup.py

4. Ingest medical data

# Start small to verify everything works
python3 scripts/ingest.py --query "type 2 diabetes treatment" --max 50

# Add more topics
python3 scripts/ingest.py --query "hypertension management" --max 100
python3 scripts/ingest.py --query "sepsis antibiotics protocol" --max 80
python3 scripts/ingest.py --query "heart failure pharmacotherapy" --max 80
python3 scripts/ingest.py --query "atrial fibrillation anticoagulation" --max 60

5. Run all tests

python3 tests/test_component1.py
python3 tests/test_component2.py
python3 tests/test_component3.py
python3 tests/test_component4.py
python3 tests/test_component5.py
python3 tests/test_component6.py

6. Start the backend

uvicorn backend_app:app --reload --port 8000

7. Start the frontend

cd files
npm install
npm run dev

Open http://localhost:5173


How confidence scoring works

Every retrieved chunk is scored by three factors:

confidence = (similarity × 0.50)
           + (evidence_weight × 0.30)
           + (recency_weight × 0.20)

Similarity (50%) — cosine similarity from Pinecone vector search. How closely the chunk's meaning matches the query.

Evidence weight (30%) — based on study design. A systematic review of 50 RCTs is more trustworthy than a single case report.

Recency weight (20%) — papers from the last 2 years score 1.0, papers older than 20 years score 0.45. Clinical guidelines change over time.

The final answer confidence is a weighted average of the top 3 chunk scores, where the highest-ranked chunk contributes most.

Confidence levels shown in UI:

Score Label Ring colour
≥ 85% High Green
≥ 70% Moderate Blue
≥ 55% Low Amber
< 55% Very low Red

Why RAG instead of just asking ChatGPT?

Plain ChatGPT This system
Information source Model's training data (cutoff 2024) Live PubMed abstracts you control
Citations Hallucinated or absent Real PMIDs with working URLs
Up-to-date No Yes — ingest new papers anytime
Domain control None You choose which topics to ingest
Confidence scoring None Transparent formula per answer
Hallucination risk High for specifics Minimised — constrained to retrieved context

Adding more medical data

Run the ingestion script any time to expand the knowledge base:

python3 scripts/ingest.py --query "oncology immunotherapy checkpoint" --max 100
python3 scripts/ingest.py --query "chronic kidney disease management" --max 80
python3 scripts/ingest.py --query "asthma COPD inhaler therapy" --max 80
python3 scripts/ingest.py --query "depression anxiety SSRI treatment" --max 80

Re-ingesting the same topic is safe — Pinecone upserts overwrite existing vectors with the same ID rather than creating duplicates.


Disclaimer

This system is for educational and research purposes only. It is not a substitute for professional medical advice, diagnosis, or treatment. Always consult a qualified healthcare professional for medical decisions.

About

Medical RAG assistant that retrieves PubMed research, ranks evidence by quality, and generates cited clinical answers with confidence scoring — built with Python, Pinecone, OpenAI, and React.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages