abc / DEEPMED_REFERENCE.md
PBThuong's picture
Thiết lập lại thư viện y khoa sạch và cập nhật chroma_db
8eaa451

DeepMed-AI — Project Reference Document

Last updated: 2026-04-14 Author: Pham Ba Thuong Repo: e:\AI\DeepMed Production URL: Hugging Face Spaces (Docker) Version: 3.0.0


1. Tổng Quan

DeepMed-AI là chatbot AI y tế chuyên dụng cho Trung tâm Y tế Khu vực Thanh Ba (TTYT KV Thanh Ba), tỉnh Phú Thọ, Việt Nam. Hỗ trợ y bác sĩ và dược sĩ:

  • Tra cứu thông tin thuốc (tên, hoạt chất, giá, hãng SX, liều dùng, chống chỉ định)
  • Chẩn đoán, phác đồ điều trị, tư vấn y khoa
  • Tra cứu danh mục thuốc nội bộ của TTYT Thanh Ba

2. Kiến Trúc Hệ Thống

2.1. Architecture: HybridRAG

┌──────────────┐     ┌──────────────────────────────────────────────┐
│  React SPA   │────▶│  FastAPI Backend (app/main.py)               │
│  (Vite)      │     │                                              │
│  Port: 5173  │     │  ┌──────────────────────────────────────┐    │
│  (dev)       │     │  │  ChatService (Singleton)              │    │
│  │           │     │  │                                      │    │
│  └───────────┘     │  │  ┌──────────┐   ┌──────────────────┐│    │
│                    │  │  │Fast Mode │   │ Deep Mode         ││    │
│                    │  │  │BM25+Vec  │   │ BM25+Vec → Rerank││    │
│                    │  │  │ k=15     │   │ k=25 → top 5     ││    │
│                    │  │  └──────────┘   └──────────────────┘│    │
│                    │  │                                      │    │
│                    │  │  ┌──────────────────────────────────┐│    │
│                    │  │  │ ChromaDB (Local Persistent)      ││    │
│                    │  │  │ Embedding: MiniLM-L12-v2         ││    │
│                    │  │  └──────────────────────────────────┘│    │
│                    │  │                                      │    │
│                    │  │  LLM: Gemini 2.5 Flash (Google)      │    │
│                    │  └──────────────────────────────────────┘    │
│                    │                                              │
│                    │  SQLite (chat history) via SQLAlchemy        │
│                    └──────────────────────────────────────────────┘

2.2. Hai Chế Độ Retrieval

Mode Retriever k Reranker Khi nào dùng
Fast BM25 + Vector (EnsembleRetriever 50/50) 15 Tra cứu thuốc nhanh, câu hỏi đơn giản
Deep BM25 + Vector (EnsembleRetriever 50/50) → CrossEncoder 25 → 5 ✅ BGE-reranker-v2-m3 Phác đồ, chẩn đoán, điều trị phức tạp

Auto-detect: Hệ thống tự nhận diện Deep mode khi câu hỏi chứa keyword: phác đồ, điều trị, chẩn đoán, xử trí, hướng dẫn, protocol, guideline, bệnh nhân bị, cách điều trị, dùng thuốc gì, nên dùng, kê đơn, toa thuốc, sơ cứu, cấp cứu.


3. Tech Stack

3.1. Backend

Component Technology Version
Framework FastAPI 0.115.12
Server Uvicorn 0.34.2
LLM Gemini 2.5 Flash via langchain-google-genai 2.1.4
Embedding paraphrase-multilingual-MiniLM-L12-v2 via sentence-transformers 3.4.1
Vector DB ChromaDB (local persistent) ≥0.4.0
Keyword Search BM25 (rank-bm25) 0.2.2
Reranker BGE-reranker-v2-m3 (CrossEncoder) via langchain-community
LangChain langchain + langchain-core + langchain-community 0.3.25
ORM SQLAlchemy 2.0.40
DB SQLite (chat history) via pysqlite3-binary
Data Processing pypdf, python-docx, openpyxl, pandas various
Rate Limiting slowapi 0.1.9
Validation Pydantic 2.11.3
PyTorch CPU-only 2.2.2+cpu
Python 3.10-slim (Docker)

3.2. Frontend

Component Technology Version
Framework React 19.2.0
Build Tool Vite 7.3.1
Styling Tailwind CSS + Vanilla CSS (index.css 30KB) 4.1.18
Markdown react-markdown 10.1.0
Icons Font Awesome (CDN)
UI Components DaisyUI 5.5.18
Testing Vitest + Testing Library 4.0.18

3.3. Deployment

Platform Config
Primary: Hugging Face Spaces Docker, port 7860
Docker Multi-stage build (Node 20 → Python 3.10-slim)
Alternative docker-compose (backend:8000, frontend:80)
CI/CD Push via push_hf.bat

4. Cấu Trúc Thư Mục

e:\AI\DeepMed\
├── Dockerfile                  # Multi-stage: frontend build → backend
├── docker-compose.yml          # Local dev: backend:8000 + frontend:80
├── .env.example                # Template env vars
├── push_hf.bat                 # Deploy to HuggingFace Spaces
├── run.py                      # Local runner
│
├── backend/
│   ├── requirements.txt        # Python dependencies
│   ├── pyproject.toml          # Project metadata
│   ├── app/
│   │   ├── main.py             # FastAPI entry + lifespan + SPA serving
│   │   ├── core/
│   │   │   ├── config.py       # Env vars: GOOGLE_API_KEY, paths
│   │   │   ├── logging_config.py
│   │   │   └── state.py        # (minimal)
│   │   ├── api/v1/
│   │   │   ├── api.py          # Router aggregator
│   │   │   └── endpoints/
│   │   │       ├── chat.py     # POST /chat, /clear, /new-chat
│   │   │       ├── health.py   # GET /health
│   │   │       ├── session.py  # GET /sessions, /session/{id}, /history
│   │   │       └── voice.py    # (placeholder)
│   │   ├── services/
│   │   │   ├── chat_service.py # ★ CORE: DeepMedBot + ChatService (713 lines)
│   │   │   └── database_service.py  # CRUD for chat history
│   │   ├── tools/
│   │   │   ├── vector_store.py # Qdrant version (LEGACY, not used in current arch)
│   │   │   ├── document_loader.py   # Drug-aware chunking (for Qdrant version)
│   │   │   ├── llm_client.py   # Gemini 2.5 Flash singleton
│   │   │   └── pdf_loader.py
│   │   ├── models/
│   │   │   └── message.py      # SQLAlchemy Message model
│   │   ├── schemas/
│   │   │   ├── chat.py         # ChatRequest, ChatResponse (Pydantic)
│   │   │   └── session.py
│   │   └── db/
│   │       └── session.py      # SQLAlchemy session factory
│   │
│   ├── data/                   # ★ MEDICAL DATA (Git LFS tracked)
│   │   ├── chroma_db/          # ChromaDB persistent storage
│   │   ├── thông tin thuốc nội bộ/     # 454 drug .md files
│   │   ├── phác đồ bộ y tế/           # 30 MOH guideline PDFs
│   │   ├── phác đồ tại ttytkv thanh ba/ # 8 local protocol PDFs
│   │   ├── các hiệp hội/              # 10 association guideline PDFs
│   │   ├── dược thư quốc gia/         # 1 national formulary PDF (24MB)
│   │   └── medical_book.pdf            # 16MB reference book
│   │
│   ├── storage/
│   │   └── chat_db/            # SQLite DB (medigenius.db)
│   └── tests/
│
└── frontend/
    ├── package.json
    ├── vite.config.js
    ├── tailwind.config.js
    ├── index.html
    └── src/
        ├── App.jsx             # ★ Single-file SPA (722 lines)
        ├── index.css           # Full CSS design system (30KB)
        ├── index.jsx           # React entry point
        └── App.test.jsx

5. API Endpoints

Method Path Description Rate Limit
POST /api/v1/chat Send message → HybridRAG response 15/min/IP
POST /api/v1/clear Clear current session history
POST /api/v1/new-chat Create new session
GET /api/v1/health Health check
GET /api/v1/sessions List all chat sessions
GET /api/v1/session/{id} Get session messages
DELETE /api/v1/session/{id} Delete a session
GET /api/v1/history Get current session history

Request/Response Schema

# ChatRequest
class ChatRequest(BaseModel):
    message: str

# ChatResponse
class ChatResponse(BaseModel):
    response: str
    source: str | None
    timestamp: str | None
    success: bool

6. Dữ Liệu Y Tế (Data Sources)

6.1. Thông tin thuốc nội bộ (data/thông tin thuốc nội bộ/)

  • 454 file .md — mỗi file là 1 thuốc trong danh mục TTYT Thanh Ba
  • Format: # TÊN_THUỐCHoạt chất: ... → nội dung chi tiết
  • Metadata enrichment: drug_name, active_ingredient, ingredient_keywords, doc_type
  • Ví dụ: MIDANTIN, Ceftriaxone 2000, Amoxicillin 250mg, Metformin...
  • Bao gồm: giá thuốc, liều dùng, chống chỉ định, tương tác, bảo quản

6.2. Phác đồ Bộ Y tế (data/phác đồ bộ y tế/)

  • 30 file PDF — Quyết định của Bộ Y tế
  • Các chuyên khoa: Tim mạch, Hô hấp, Tiêu hóa, Thận-Tiết niệu, Nội tiết, Ung bướu, Da liễu, RHM, Lao, Ngộ độc, BPTNMT, COPD...

6.3. Phác đồ tại TTYT KV Thanh Ba (data/phác đồ tại ttytkv thanh ba/)

  • 8 file PDF — phác đồ nội bộ theo chuyên khoa
  • CKL, HSCC, NTH, NTM, Ngoại, Nhi, Sản, YHCT

6.4. Các hiệp hội (data/các hiệp hội/)

  • 10 file PDF — hướng dẫn từ các hội chuyên khoa (VUNA, etc.)
  • Viêm phổi cộng đồng, COPD, Bệnh thận mạn, Nhiễm nấm xâm lấn...

6.5. Dược thư quốc gia (data/dược thư quốc gia/)

  • 1 file PDF (24MB) — Dược thư Quốc gia Việt Nam 2023

6.6. Medical book (data/medical_book.pdf)

  • 1 file PDF (16MB) — sách tham khảo y khoa

7. Cách Hoạt Động Chi Tiết

7.1. Khởi Động (Lifespan)

  1. db_service.init_db() — tạo bảng SQLite
  2. LFS pointer detection — cảnh báo nếu file data < 500 bytes
  3. chat_service.initialize()DeepMedBot():
    • Load embedding model (paraphrase-multilingual-MiniLM-L12-v2)
    • Check ChromaDB có sẵn? → nếu có, skip scan PDF
    • Nếu chưa: quét toàn bộ data/ → chunking (1200 chars, overlap 200) → index vào ChromaDB
    • Build Fast Retriever (BM25 + Vector, k=15)
    • Build Deep Retriever (BM25 + Vector k=25 → BGE-reranker-v2-m3 top 5)
    • Init LLM (Gemini 2.5 Flash, temp=0.2)
    • Build LangChain retrieval chains (history-aware)

7.2. Chat Flow

  1. User gửi message → POST /api/v1/chat
  2. Session ID: từ header X-Session-ID hoặc cookie
  3. Auto-detect mode (Fast/Deep) dựa trên keywords
  4. ChatService:
    • Lưu user message vào SQLite
    • Convert history → LangChain messages (max 5 turns)
    • Run active chain: create_retrieval_chain → retrieve docs → LLM answer
    • Extract [USED_SOURCES: ...] từ LLM output
    • Build reference block (chỉ nguồn LLM thực sự dùng)
    • Lưu assistant response vào SQLite
  5. Return JSON response

7.3. System Prompt

System prompt rất chi tiết (9 nguyên tắc), bắt buộc:

  • Chỉ trả lời từ Context, không bịa
  • PHẢI trả lời giá thuốc nếu có trong data
  • Trích dẫn đúng nguồn, không bịa tên tài liệu
  • Xác định thuốc đúng bằng header [Trích từ tài liệu: TÊN_FILE]
  • Ưu tiên phác đồ Bộ Y tế VN, WHO
  • Kết bằng disclaimer
  • BẮT BUỘC khai báo [USED_SOURCES: file1 | file2 | ...]

8. Environment Variables

# Required
GOOGLE_API_KEY=xxx          # Gemini 2.5 Flash API key

# Optional
FORCE_REBUILD_DB=False      # True = rebuild ChromaDB on startup
DATA_DIR=/app/backend/data
CHROMA_DB_PATH=/app/backend/data/chroma_db
CHAT_DB_PATH=/app/backend/storage/chat_db/medigenius.db
LOG_DIR=/app/backend/logs
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000,http://localhost:7860
SESSION_SECRET=auto_generated

# HF Spaces cache fix (set automatically in Dockerfile)
HF_HOME=/tmp/huggingface
HUGGINGFACE_HUB_CACHE=/tmp/huggingface/hub
SENTENCE_TRANSFORMERS_HOME=/tmp/sentence-transformers
TRANSFORMERS_CACHE=/tmp/transformers
XDG_CACHE_HOME=/tmp/.cache

9. Frontend Features

  • Single-file SPA: App.jsx (722 lines) — không dùng React Router
  • Components: ErrorBoundary, Sidebar, ChatArea, MessageBubble, InputArea
  • Theme: Dark/Light mode (toggle, persist localStorage)
  • Mobile responsive: useIsMobile hook, sidebar backdrop
  • Chat sessions: New, Load, Delete, Download as .txt
  • Quick Questions: 6 preset medical queries
  • Markdown rendering: react-markdown cho bot response
  • Copy message: clipboard API
  • Toast notifications: success/error/info
  • Glass morphism design: .glass-effect class
  • Animated background: floating circles + gradient overlay
  • Status indicator: "AI Ready" pulse ring

10. Deployment (Hugging Face Spaces)

Dockerfile Flow

  1. Stage 1: Node 20 Alpine → npm cinpm run build/app/frontend/dist
  2. Stage 2: Python 3.10-slim → install system deps → install torch CPU → install requirements → copy backend → copy frontend dist → set permissions → run uvicorn on port 7860

Key Docker Issues (Đã Fix)

  • SQLite version: Python 3.10-slim ships SQLite 3.34, ChromaDB cần ≥ 3.35 → monkey-patch pysqlite3-binary
  • HF Cache PermissionError: HF Spaces set HOME=/nonexistent → fix: force all cache to /tmp/
  • Git LFS pointers: Data files are LFS-tracked → MUST git lfs pull before Docker build, or data will be empty stubs
  • Non-root user: appuser:appgroup for security, needs chown for storage dirs
  • ChromaDB batch limit: Max 5461 per batch → batch upload in groups of 5000

Deploy Command

# push_hf.bat
git push hf main

11. Lịch Sử Phát Triển & Các Vấn Đề Đã Giải Quyết

Phase 1: Initial Build (03/2026)

  • Xây dựng backend FastAPI + frontend React
  • Ban đầu dùng Qdrant Cloud cho vector DB
  • Deploy lên HuggingFace Spaces

Phase 2: Qdrant Cloud → ChromaDB Migration (04/2026)

  • Chuyển từ Qdrant Cloud sang ChromaDB local để giảm latency và dependency
  • File tools/vector_store.py vẫn chứa code Qdrant (LEGACY, không dùng)
  • Code ChromaDB hiện tại nằm trong services/chat_service.py

Phase 3: LangGraph → HybridRAG Simplification (04/07/2026)

  • Loại bỏ kiến trúc LangGraph multi-agent phức tạp
  • Thay bằng HybridRAG đơn giản: ChromaDB + BM25 + CrossEncoder Reranker
  • 2 modes: Fast / Deep

Phase 4: UI Modernization (04/08-09/2026)

  • Redesign UI responsive, mobile-friendly
  • Thêm sidebar chat history, dark/light theme
  • Glass morphism, animated background

Known Issues / TODO

  • tools/vector_store.pyLEGACY code cho Qdrant, không dùng nữa nhưng chưa xóa
  • tools/document_loader.py — Version cũ với drug-aware chunking cho Qdrant
  • core/langgraph_workflow.py — Stub file, nội dung trống
  • core/state.py — Stub file, nội dung minimal
  • docker-compose.yml — Lỗi thời, dùng port 8000/80 thay vì 7860
  • agents/ folder — Có file tavily.py nhưng không được import trong main flow
  • tools/duckduckgo_search.py, tools/wikipedia_search.py, tools/tavily_search.py — Search tools không dùng trong HybridRAG hiện tại
  • Database service vẫn gọi là "MediGenius" trong docstring (tên cũ)
  • Frontend: Nút Settings chưa có chức năng

12. Commands

# ── Local Development ──
cd e:\AI\DeepMed\frontend && npm run dev     # Frontend: localhost:5173
cd e:\AI\DeepMed\backend && uvicorn app.main:app --reload --port 8000  # Backend

# ── Docker Build ──
docker build -t deepmed-ai .
docker run -p 7860:7860 -e GOOGLE_API_KEY=xxx deepmed-ai

# ── Force Rebuild ChromaDB ──
FORCE_REBUILD_DB=True uvicorn app.main:app

# ── Run Tests ──
cd frontend && npm test
cd backend && pytest

# ── Deploy to HF Spaces ──
push_hf.bat

13. File Quan Trọng Nhất (Quick Reference)

Mục đích File
Entry point backend/app/main.py
Core logic backend/app/services/chat_service.py (713 lines)
Chat API backend/app/api/v1/endpoints/chat.py
Config backend/app/core/config.py
LLM backend/app/tools/llm_client.py
Frontend SPA frontend/src/App.jsx (722 lines)
CSS frontend/src/index.css (30KB)
Docker Dockerfile (92 lines, multi-stage)
Dependencies backend/requirements.txt
Env template .env.example

14. Lưu Ý Khi Chỉnh Sửa

  1. System prompt nằm trong chat_service.py (2 bản: QA_SYSTEM_PROMPT_FASTQA_SYSTEM_PROMPT_DEEP). Cũng có bản trong llm_client.py (LEGACY).
  2. ChromaDB logic hoàn toàn trong chat_service.py, KHÔNG phải vector_store.py (đó là Qdrant legacy).
  3. Document loading trong chat_service.py dùng _load_documents_from_folder() riêng, KHÔNG phải document_loader.py (đó cũng là Qdrant legacy).
  4. Frontend là single-file React (App.jsx), không có routing. CSS ~30KB custom.
  5. Deploy phải đảm bảo git lfs pull trước khi build Docker, nếu không data sẽ trống.
  6. SQLite monkey-patch PHẢI ở đầu main.py, trước mọi chromadb import.
  7. HF cache paths PHẢI set trước khi import sentence-transformers/transformers.