silver / README.md
Song
readme
07ac3fd
metadata
title: 銀髮餐桌助手
emoji: 🥄
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860

銀髮餐桌助手 - RAG 系統

本文件描述銀髮餐桌助手的 RAG(Retrieval-Augmented Generation)系統架構與實作細節。

RAG 系統概述

銀髮餐桌助手採用 RAG 技術為台灣銀髮族(65歲以上)提供智能營養飲食諮詢服務。RAG 系統透過檢索相關知識庫文檔,增強 AI 回應的準確性和可靠性,確保所有營養建議基於權威來源。

核心功能

  • 知識檢索:基於用戶問題從知識庫中檢索相關文檔
  • 相似性搜索:使用向量嵌入實現語義級相似性匹配
  • 文檔增強生成:將檢索到的文檔作為上下文,提升 AI 回應品質
  • 個人化回應:結合用戶健康檔案提供客製化建議

知識庫來源

知識庫內容托管在 Hugging Face Dataset

  • Dataset: pcreem/dietinstruction
  • 本地資料夾 backend/data/ 用於存放下載的檔案
  • 系統啟動時會自動從 Hugging Face 下載知識庫檔案

主要文檔

文件 內容
每日飲食指南手冊.pdf 衛福部每日飲食指南
高齡營養飲食質地衛教手冊.pdf 高齡者飲食質地指導
慢性病飲食原則.md 糖尿病、高血壓、高脂血症等慢性病飲食指南

文檔格式支援

  • **Markdown (.md)**:主要知識庫格式
  • **PDF (.pdf)**:支援 PDF 文件載入

自動下載機制

RAG 服務啟動時會檢查本地 backend/data/ 資料夾:

  • 若資料夾不存在或為空,自動從 Hugging Face Dataset 下載知識庫
  • 若已有檔案,則使用本地版本

所有文檔經過處理後存入向量資料庫,供相似性搜索使用。

系統架構流程圖

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   User Query    │────►│   Chat Service  │────►│   RAG Service   │
│   (問題輸入)    │     │   (聊天服務)    │     │   (RAG服務)     │
└─────────────────┘     └────────┬────────┘     └────────┬────────┘
                                 │                      │
                                 │                      ▼
                                 │            ┌─────────────────┐
                                 │            │   Embeddings    │
                                 │            │   (向量化)      │
                                 │            └────────┬────────┘
                                 │                      │
                                 │                      ▼
                                 │            ┌─────────────────┐
                                 │            │  Supabase       │
                                 │            │  pgvector       │
                                 │            │  (向量資料庫)   │
                                 │            └────────┬────────┘
                                 │                      │
                                 │                      ▼
                                 │            ┌─────────────────┐
                                 │            │   Similarity    │
                                 │            │   Search        │
                                 │            │   (相似性搜索)  │
                                 │            └────────┬────────┘
                                 │                      │
                                 │                      ▼
                                 │            ┌─────────────────┐
                                 │            │ Relevant Docs   │
                                 │            │ (相關文檔)      │
                                 │            └────────┬────────┘
                                 │                      │
                                 ▼                      ▼
                        ┌─────────────────┐     ┌─────────────────┐
                        │   LLM Response  │◄────│   Context       │
                        │   (AI回應)      │     │   Integration   │
                        └─────────────────┘     └─────────────────┘

核心組件說明

RAG 服務 (rag.py)

RAG 服務是系統的核心模組,負責文檔處理和向量搜索。

class RAGService:
    """RAG service for document management and similarity search."""
    
    def __init__(self):
        # 初始化 OpenAI 向量化模型
        self.embeddings = OpenAIEmbeddings(...)
        # 初始化 Supabase 向量存儲
        self.vector_store = SupabaseVectorStore(...)
        # 初始化文檔分塊器
        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=1000,
            chunk_overlap=200
        )

聊天服務 (chat_service.py)

聊天服務整合 RAG 能力,提供 AI 對話功能。

class ChatService:
    """Chat service for AI-powered conversations with RAG integration."""
    
    def __init__(self):
        # 初始化 LLM 模型
        self.llm = ChatOpenAI(...)
        # 整合 RAG 服務
        self.rag_service = get_rag_service()

資料庫設置 (setup_rag_db.py)

設置 pgvector 擴展和文檔表結構。

文檔處理流程

流程步驟

┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   載入文檔   │───►│   文檔分塊   │───►│   向量化     │───►│   存入資料庫 │
│   Loader    │    │   Chunker   │    │ Embedding   │    │   Storage   │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘

1. 文檔載入

支援多種文檔載入器:

# PDF 載入
loader = PyPDFLoader(str(file_path))
documents = loader.load()

# Markdown 載入
loader = UnstructuredMarkdownLoader(str(file_path))
documents = loader.load()

2. 文檔分塊

使用 RecursiveCharacterTextSplitter 進行智慧分塊:

  • chunk_size:1000 字元
  • chunk_overlap:200 字元重疊
  • is_separator_regex:false(使用純文字分隔)

每個區塊包含以下元數據:

chunk.metadata = {
    "source": "文件路徑",
    "file_name": "檔案名稱",
    "chunk_id": "唯一識別碼"
}

3. 向量化

使用 OpenAI Embeddings 模型將文本轉換為向量:

embeddings = OpenAIEmbeddings(
    model="azure-text-embedding-3-large",
    openai_api_key=api_key
)
# 支援 LiteLLM 相容端點

向量維度:3072

4. 向量存儲

存入 Supabase pgvector 向量資料庫:

vector_store = SupabaseVectorStore(
    client=supabase_client,
    embedding=embeddings,
    table_name="documents",
    query_name="match_documents"
)

相似性搜索

基本搜索

async def get_relevant_documents(self, query: str, k: int = 8) -> List[Document]:
    """執行相似性搜索檢索相關文檔"""
    results = await self.vector_store.asimilarity_search(query, k=k)
    return results

帶分數的搜索

async def get_relevant_documents_with_scores(
    self, 
    query: str, 
    k: int = 8, 
    score_threshold: float = 0.7
) -> List[Document]:
    """執行帶分數閾值的相似性搜索"""

分頁搜索

async def get_relevant_documents_paginated(
    self, 
    query: str,
    page: int = 1,
    page_size: int = 10,
    score_threshold: Optional[float] = None
) -> Dict[str, Any]:
    """執行分頁相似性搜索"""

搜索結果快取

系統使用文檔快取機制(TTL: 30 分鐘)優化效能:

@cache_result(document_cache, "rag_documents", ttl=1800)
async def get_relevant_documents(self, query: str, k: int = 8):
    ...

AI 對話整合

對話流程

  1. 接收用戶問題
  2. 檢索相關文檔(k=6)
  3. 獲取用戶健康檔案
  4. 格式化上下文資訊
  5. 組合系統提示詞
  6. 串流回應生成

系統提示詞

system_prompt = """你是「銀髮餐桌助手」,專為台灣銀髮族設計的AI營養飲食顧問助手。

角色定位:
- 溫暖、耐心、專業的營養飲食顧問
- 專門為台灣銀髮族(65歲以上)提供飲食建議
- 熟悉台灣在地食材、飲食文化和生活習慣

核心原則:
1. 嚴格遵循台灣衛福部(MOHW)的營養指導原則
2. 僅提供營養建議,絕不進行醫療診斷
3. 針對銀髮族的特殊營養需求
4. 考慮台灣在地飲食文化"""

上下文整合

def format_context_information(self, user_context, relevant_docs) -> str:
    """格式化用戶上下文和相關文檔"""
    # 組合用戶背景資訊
    # 組合相關營養指南文檔
    return formatted_context

API 端點

RAG 相關端點

端點 方法 說明
/api/chat POST AI 聊天諮詢(含 RAG)
/rag/load POST 載入知識庫
/rag/search GET 相似性搜索
/rag/count GET 獲取文檔數量
/rag/clear DELETE 清除知識庫
/ GET Gradio 聊天界面

聊天請求範例

curl -X POST "http://localhost:8000/api/chat" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "請問銀髮族應該如何補充蛋白質?",
    "profile_id": "uuid-string"
  }'

知識庫載入請求

curl -X POST "http://localhost:8000/rag/load" \
  -H "Authorization: Bearer <token>"

快速開始

前置要求

  • Python 3.8+
  • PostgreSQL 13+(通過 Supabase,啟用 pgvector)
  • Supabase 專案
  • OpenAI API Key 或 LiteLLM API Key

環境變數配置

複製 .env.example.env 並填入以下配置:

# Supabase Configuration
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key

# Database URL for pgvector (Supabase PostgreSQL)
DATABASE_URL=postgresql+asyncpg://postgres:[YOUR_PASSWORD]@db.[YOUR_PROJECT_ID].supabase.co:5432/postgres

# OpenAI Configuration (or LiteLLM)
OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=your_openai_base_url  # Optional, for LiteLLM/Azure

# Or use LiteLLM directly
LITELLM_API_KEY=your_litellm_api_key
LITELLM_BASE_URL=https://your-litellm-endpoint/

# Server Configuration
HOST=0.0.0.0
PORT=8000

安裝依賴

# 創建虛擬環境
python -m venv venv
source venv/bin/activate  # Linux/Mac
# 或 venv\Scripts\activate  # Windows

# 安裝依賴
pip install -r requirements.txt

資料庫設置

# 設置 pgvector 和文檔表
python setup_rag_db.py

啟動服務

# 啟動 FastAPI 服務
python app.py

# 或使用 uvicorn
uvicorn app:app --reload --host 0.0.0.0 --port 8000

載入知識庫

知識庫會在服務啟動時自動載入,或可手動觸發:

# 通過 API
curl -X POST "http://localhost:8000/rag/load"

# 或直接運行
python -m rag

測試 RAG 系統

python -m rag
python -m chat_service

訪問應用

故障排除

常見問題

  1. pgvector 擴展未啟用

    CREATE EXTENSION IF NOT EXISTS vector;
    
  2. 向量維度不匹配

    • 確保 embedding 向量維度為 3072
    • 檢查資料庫表結構:embedding vector(3072)
  3. SupabaseVectorStore 兼容性問題

    • 系統已內建手動 RPC 回退機制
    • 使用 match_documents 函數直接執行相似性搜索
  4. 知識庫載入失敗

    • 檢查 Hugging Face Dataset 網路連接
    • 確認 Dataset pcreem/dietinstruction 存在且有檔案
    • 檢查 backend/data/ 目錄存在且包含文件
    • 確認文件格式為支援的類型(.md, .pdf, .txt)

調試模式

# 啟用詳細日誌
export LOG_LEVEL=DEBUG
python app.py

# 或使用 uvicorn
uvicorn app:app --reload --log-level debug

監控與日誌

日誌配置

系統使用 Python 標準日誌庫:

LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR

健康檢查

  • GET /health - 服務健康狀態檢查
  • 返回服務狀態、版本信息和資料庫連接狀態

安全考量

  • 知識庫搜索無需認證(匿名用戶也可使用)
  • 用戶健康檔案相關操作需要 JWT 認證
  • 向量資料庫連接使用服務層級密鑰

重要提醒:本系統僅提供營養建議,無法替代專業醫療諮詢。如有健康問題,請諮詢專業醫師。