Tổng quan

Medical Patient Simulator Service

Hệ thống mô phỏng bệnh nhân ảo cho giáo dục y khoa. Sử dụng LLM kết hợp RAG (Retrieval-Augmented Generation) để tạo ra các ca bệnh thực tế, hỗ trợ sinh viên và bác sĩ thực hành hội chẩn, chẩn đoán, và điều trị.

Công nghệ

Framework FastAPI (Python)
LLM Google Gemma 4 (gemma4_service)
RAG Retrieval-Augmented Generation từ patient_data/
Data Source File JSON trong patient_data/
Port 8025 (FastAPI), proxy: 443
Base URL (public) https://pnt.badt.vn/virtualpatient/

Base URL

https://pnt.badt.vn/virtualpatient

External: https://dv.badt.vn/ai/virtualpatient/ | Internal: http://localhost:8025

Xác thực

Bearer Token Authentication Required

API này yêu cầu Bearer token trong Authorization header. Liên hệ admin để nhận API token.

Cách dùng

Authorization: Bearer YOUR_API_TOKEN
Lưu ý bảo mật
  • Không chia sẻ token công khai hoặc commit vào source code
  • Dùng environment variables để lưu token
  • Admin endpoints yêu cầu token có quyền admin

API Endpoints

GET /

Root info — trả về thông tin service cơ bản.

Example Response

{
  "message": "Medical Patient Simulator RAG System",
  "status": "running",
  "version": "1.0.0"
}
GET /ui

Web UI — giao diện người dùng trên trình duyệt.

GET /health

Health check cơ bản — trả về trạng thái service và các thành phần.

Example Response

{
  "status": "healthy",
  "llm_provider": "gemma4",
  "llm_client_initialized": true,
  "rag_system_initialized": true,
  "llm_api_status": "healthy",
  "model": "google/gemma-2-9b-it"
}
GET /health/deep

Deep health check — kiểm tra chi tiết: LLM latency, patient files, disk usage, uptime.

Example Response

{
  "status": "healthy",
  "request_id": "a87a88de",
  "llm_latency_ms": 2.13,
  "model": "google/gemma-2-9b-it",
  "patient_files_count": 0,
  "patient_data_disk_usage_mb": 2.6,
  "uptime_human": "0h 27m 28s"
}
POST /chat

Chat với bệnh nhân ảo. Đây là endpoint chính cho tương tác hội thoại.

Request body

{
  "message": "Bệnh nhân có triệu chứng gì?",
  "patient_id": "benhnhan001",
  "session_id": "session-uuid-v4",
  "language": "vi"
}

Example Response

{
  "response": "Tôi bị đau đầu nhiều, kèm sốt nhẹ và mệt mỏi...",
  "patient_id": "benhnhan001",
  "session_id": "session-uuid-v4",
  "patient_info": {
    "name": "Nguyễn Văn A",
    "age": 45,
    "diagnosis": "Tăng huyết áp"
  }
}
POST /chat-optimized

Chat optimized — phiên bản tối ưu, nhanh hơn cho chat thông thường.

Request body (giống /chat)

{
  "message": "Xin chào bác sĩ!",
  "patient_id": "benhnhan001",
  "session_id": "session-uuid-v4",
  "language": "vi"
}
GET /clinical-data/{patient_id}

Lấy dữ liệu lâm sàng đầy đủ của bệnh nhân theo ID.

Path Parameters

patient_idstring (required)ID của bệnh nhân

Example

curl https://pnt.badt.vn/virtualpatient/clinical-data/benhnhan001 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
GET /clinical-data/{patient_id}/summary

Tóm tắt hồ sơ bệnh nhân — bản rút gọn các thông tin quan trọng.

Path Parameters

patient_idstring (required)ID của bệnh nhân
GET /prompt-config

Lấy cấu hình prompt hiện tại của hệ thống.

POST /prompt-config

Cập nhật cấu hình prompt.

Request body

{
  "system_prompt": "Bạn là bệnh nhân ảo...",
  "temperature": 0.7,
  "max_tokens": 500
}
GET /patients

Liệt kê tất cả bệnh nhân có trong hệ thống.

Example Response

{
  "patients": [
    {
      "id": "benhnhan001",
      "name": "Nguyễn Văn A",
      "age": 45,
      "diagnosis": "Tăng huyết áp"
    }
  ],
  "total": 1
}
POST /voice-interaction

Tương tác giọng nói với bệnh nhân ảo. Gửi file audio, nhận response text kèm tư vấn.

Request (multipart/form-data)

audiofile (required)File audio (.wav, .mp3, .ogg)
patient_idstring (required)ID bệnh nhân

Example (cURL)

curl -X POST https://pnt.badt.vn/virtualpatient/voice-interaction \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "audio=@/path/to/question.wav" \
  -F "patient_id=benhnhan001"
GET /admin/files

Quản lý file admin — liệt kê các file trong thư mục admin.

Yêu cầu quyền admin
GET /admin/read-file

Đọc nội dung file từ server.

Query Parameters

file_pathstring (required)Đường dẫn file
POST /admin/save-file

Ghi nội dung vào file trên server.

Request body

{
  "file_path": "...",
  "content": "Nội dung file..."
}
DELETE /admin/delete-file

Xóa file trên server.

Request body

{
  "file_path": "..."
}
Hành động phá hủy — cần thận trọng!

Chat với bệnh nhân ảo

Tương tác với bệnh nhân ảo qua text. Hệ thống sử dụng RAG để lấy thông tin từ hồ sơ bệnh nhân, sau đó LLM tạo ra câu trả lời phù hợp với vai trò và bệnh cảnh.

Cơ chế hoạt động

  1. Nhận message + patient_id
  2. RAG truy xuất thông tin bệnh nhân từ file JSON
  3. LLM sinh câu trả lời dựa trên context (bệnh sử, triệu chứng, tuổi, giới...)
  4. Trả về response kèm patient_info

Ví dụ Python

import requests
import os

url = "https://pnt.badt.vn/virtualpatient/chat"
headers = {
    "Authorization": f"Bearer {os.getenv('API_AI_TOKEN')}",
    "Content-Type": "application/json"
}
data = {
    "message": "Chào bác sĩ, tôi bị đau bụng từ sáng",
    "patient_id": "benhnhan001",
    "language": "vi"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()
print(result["response"])

Ví dụ cURL

curl -X POST https://pnt.badt.vn/virtualpatient/chat \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Bệnh nhân có tiền sử bệnh gì?",
    "patient_id": "benhnhan001",
    "language": "vi"
  }'

Clinical Data & Patient Summary

Truy xuất thông tin chi tiết của bệnh nhân từ hệ thống RAG.

1. Lấy dữ liệu lâm sàng đầy đủ

curl https://pnt.badt.vn/virtualpatient/clinical-data/benhnhan001 \
  -H "Authorization: Bearer YOUR_API_TOKEN"

2. Lấy tóm tắt bệnh nhân

curl https://pnt.badt.vn/virtualpatient/clinical-data/benhnhan001/summary \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Ví dụ Python

import requests
import os

token = os.getenv("API_AI_TOKEN")
headers = {"Authorization": f"Bearer {token}"}

# Full clinical data
resp = requests.get(
    "https://pnt.badt.vn/virtualpatient/clinical-data/benhnhan001",
    headers=headers
)
print(resp.json())

# Summary
resp = requests.get(
    "https://pnt.badt.vn/virtualpatient/clinical-data/benhnhan001/summary",
    headers=headers
)
print(resp.json())

Quản lý bệnh nhân

Liệt kê và quản lý danh sách bệnh nhân trong hệ thống.

Danh sách tất cả bệnh nhân

curl https://pnt.badt.vn/virtualpatient/patients \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Lưu ý

  • Mỗi bệnh nhân có một file JSON riêng trong thư mục patient_data/
  • File JSON chứa: thông tin nhân khẩu, bệnh sử, tiền sử, thuốc, xét nghiệm...
  • Khi thêm bệnh nhân mới, cần tạo file JSON tương ứng
  • Hệ thống RAG tự động index dữ liệu bệnh nhân

Voice Interaction

🎤 Tương tác giọng nói với bệnh nhân ảo

Gửi câu hỏi dạng audio, server thực hiện: Speech-to-TextRAG + LLMText-to-Speech. Kết quả trả về gồm text và audio.

Cơ chế

  1. Upload file audio (câu hỏi của bác sĩ/sinh viên)
  2. Medical Transcribe service chuyển audio → text
  3. RAG truy xuất thông tin bệnh nhân
  4. LLM sinh câu trả lời
  5. Text-to-Speech chuyển response → audio
  6. Trả về cả text và audio

Ví dụ Python

import requests
import os

files = {
    "audio": ("question.wav", open("question.wav", "rb"), "audio/wav")
}
data = {"patient_id": "benhnhan001"}

response = requests.post(
    "https://pnt.badt.vn/virtualpatient/voice-interaction",
    headers={"Authorization": f"Bearer {os.getenv('API_AI_TOKEN')}"},
    files=files,
    data=data
)

result = response.json()
print("Response text:", result["response"])

# If audio returned, save it
if "audio" in result:
    with open("doctor_response.wav", "wb") as f:
        f.write(result["audio"])

Định dạng audio hỗ trợ

Input WAV, MP3, OGG (16kHz mono khuyến nghị)
Output WAV (PCM 16-bit, dùng Text2Speech service)
Max file size 25 MB

Cấu trúc Patient Data (JSON)

Mỗi bệnh nhân là một file JSON trong patient_data/. Cấu trúc mẫu:

{
  "patient_id": "benhnhan001",
  "name": "Nguyễn Văn A",
  "age": 45,
  "gender": "nam",
  "diagnosis": "Tăng huyết áp giai đoạn 2",
  "medical_history": "Tăng huyết áp 5 năm, đái tháo đường type 2",
  "symptoms": "Đau đầu, chóng mặt, mệt mỏi",
  "medications": ["Amlodipine 5mg", "Metformin 500mg"],
  "allergies": ["Penicillin"],
  "test_results": {
    "blood_pressure": "160/95 mmHg",
    "blood_sugar": "7.2 mmol/L",
    "cholesterol": "6.8 mmol/L"
  },
  "lifestyle": {
    "smoking": false,
    "alcohol": "social",
    "exercise": "ít vận động"
  }
}
Patient Data Directory

Thư mục chứa dữ liệu bệnh nhân: /đường_dẫn_project/patient_data/. Hệ thống tự động quét và index tất cả file JSON khi khởi động.

Admin File Management

Yêu cầu quyền admin

Các endpoint admin yêu cầu token có quyền admin. Sử dụng cẩn thận vì có thể đọc/ghi/xóa file tùy ý trên server.

List files

curl https://pnt.badt.vn/virtualpatient/admin/files \
  -H "Authorization: Bearer ADMIN_API_TOKEN"

Read file

curl "https://pnt.badt.vn/virtualpatient/admin/read-file?file_path=/path/to/file" \
  -H "Authorization: Bearer ADMIN_API_TOKEN"

Save file

curl -X POST https://pnt.badt.vn/virtualpatient/admin/save-file \
  -H "Authorization: Bearer ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "file_path": "/path/to/file.json",
    "content": "{\"key\": \"value\"}"
  }'

Delete file

curl -X DELETE https://pnt.badt.vn/virtualpatient/admin/delete-file \
  -H "Authorization: Bearer ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "file_path": "/path/to/delete.json"
  }'

Error Codes

Code Error Description
400 Bad Request Tham số request không hợp lệ
401 Unauthorized Bearer token thiếu hoặc không hợp lệ
404 Not Found Patient ID không tồn tại
422 Validation Error Request validation failed
500 Internal Server Error Lỗi LLM hoặc RAG service
503 Service Unavailable LLM hoặc RAG backend chưa sẵn sàng
504 Gateway Timeout Request timeout (>60s)

Tài liệu bổ sung