DeepMedAI / 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
|
Raw
History Blame Contribute Delete
18.9 kB
# 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
```python
# 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ỐC``Hoạ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
```bash
# 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 ci``npm 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
```bash
# 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.py`**LEGACY** 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
```bash
# ── 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_FAST``QA_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.