Skip to content

kkchengaf/Local_RAG_Chat

Repository files navigation

本地 RAG 文檔問答系統

這是 AI Engineer 學習路上的實戰專案。我們實現了一個基於本地 LLM 的文檔問答系統,支持混合檢索、智能查詢處理等功能。

專案概述

目標:上傳 PDF 文檔,基於內容進行智能問答

默認數據:道路使用者守則 (Road Users Code 2020)

技術棧

  • 前端:Streamlit (互動式 Web 介面)
  • API 伺服器:FastAPI
  • LLM:Ollama (本地運行)
  • RAG Pipeline:LangChain
  • 向量資料庫:ChromaDB
  • 檢索方式:混合檢索 (BM25 + Vector Search)

專案結構

local-rag-chat/
├── app.py                  # Streamlit 主程式
├── api_server.py          # FastAPI 伺服器
├── main.py                 # 測試腳本
├── config.py               # 配置常量
├── document_processor.py   # 文檔處理與向量存儲
├── rag_chain.py           # RAG 鏈與檢索
├── prompts.py              # Prompt 模板
├── hybrid_retriever.py    # 混合檢索 (BM25 + Vector)
├── query_processor.py     # 查詢處理 (擴展 + 子問題)
├── token_tracker.py       # Token 使用追蹤
├── requirements.txt       # Python 依賴清單
├── README.md              # 說明文檔
├── screenshot/            # 截圖
└── data/                  # 存放 PDF 文檔
    ├── basiclaw_full_text.pdf      # 基本法
    └── road_users_code_2020_chi.pdf  # 道路使用者守則

截圖展示

1. 主介面

主介面

2. 問答示範

例題1 例題2

前置要求

1. 安裝 Ollama

Ollama 讓你可以在本地運行大型語言模型。

macOS / Linux:

# 安裝 Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 啟動服務
ollama serve

Windows:

2. 下載 LLM 模型

# 默認模型 (12B)
ollama pull gemma3:12b

# 或使用其他模型
ollama pull qwen3.5:9b

3. 下載 Embedding 模型

# 默認 Embedding 模型
ollama pull bge-m3

# 或使用較小的模型
ollama pull qwen3-embedding:0.6b

4. 確認模型已安裝

ollama list

應該能看到類似輸出:

NAME                ID          SIZE      MODIFIED
gemma3:12b         xxx...      7.2GB     ...
bge-m3              xxx...      1.2GB     ...

快速開始

步驟 1:進入專案目錄

cd local-rag-chat

步驟 2:建立虛擬環境

# 建立 venv
python -m venv venv

# 啟動虛擬環境
# macOS / Linux
source venv/bin/activate

# Windows (PowerShell)
venv\Scripts\Activate.ps1

# Windows (命令提示字元)
venv\Scripts\activate.bat

步驟 3:安裝依賴

pip install -r requirements.txt

步驟 4:啟動 Ollama 服務

確保在另一個終端機視窗執行:

ollama serve

步驟 5:啟動應用程式

streamlit run app.py

瀏覽器會自動打開 http://localhost:8501

功能特色

1. 混合檢索 (Hybrid Search)

  • BM25:關鍵字匹配,適合精確檢索
  • Vector Search:語意相似度檢索
  • Reciprocal Rank Fusion (RRF):結合兩種檢索結果

2. 智能查詢處理

  • 查詢擴展:將模糊查詢擴展為完整問題
    • 例如:「它」→ 「基本法中關於...的規定」
  • 子問題生成:將複雜問題分解為多個簡單問題

3. 文檔管理

  • 新增文檔到現有索引
  • 重建索引
  • 移除特定文檔

FastAPI 伺服器

除了 Streamlit 介面,本專案還提供了 FastAPI 伺服器,可供其他應用程式调用。

啟動 API 伺服器

# 安裝額外依賴(如尚未安裝)
pip install fastapi uvicorn python-multipart

# 啟動伺服器
python api_server.py

伺服器將在 http://localhost:8000 運行

API 端點

端點 方法 說明
/ GET 根路徑
/health GET 健康檢查
/documents GET 列出已索引的文檔
/upload POST 上傳 PDF 文檔
/reindex POST 重新建立索引
/documents/{doc_id} DELETE 刪除指定文檔
/chat POST 聊天問答(Streaming)
/chat/non-stream POST 聊天問答(非Streaming)
/conversation/{id} DELETE 清除對話歷史
/usage GET 取得總體使用統計
/usage/daily GET 取得每日使用統計
/usage/models GET 取得模型使用統計
/usage/conversation/{id} GET 取得對話使用統計
/usage/recent GET 取得最近使用記錄
/usage DELETE 清除使用統計

API 使用範例

健康檢查

curl http://localhost:8000/health

上傳文檔

curl -X POST http://localhost:8000/upload \
  -F "files=@document.pdf" \
  -F "chunk_size=1000" \
  -F "embedding_model=bge-m3"

聊天問答(非Streaming)

curl -X POST http://localhost:8000/chat/non-stream \
  -H "Content-Type: application/json" \
  -d '{
    "message": "什麼是道路使用者守則?",
    "use_hybrid": true,
    "model": "gemma3:12b",
    "temperature": 0.7
  }'

聊天問答(Streaming)

curl -X POST http://localhost:8000/chat \
  -H "Content-Type: application/json" \
  -d '{
    "message": "什麼是道路使用者守則?",
    "use_hybrid": true,
    "model": "gemma3:12b",
    "temperature": 0.7
  }'

重新建立索引

curl -X POST http://localhost:8000/reindex \
  -H "Content-Type: application/json" \
  -d '{
    "chunk_size": 1000,
    "chunk_overlap": 200,
    "embedding_model": "bge-m3"
  }'

API 文檔

啟動伺服器後,可訪問 http://localhost:8000/docs 查看互動式 API 文檔(Swagger UI)

使用教學

1. 首次使用流程

  1. 打開應用:訪問 http://localhost:8501
  2. 選擇模型:在左側側邊欄選擇 LLM 模型
  3. 讀取索引:點擊「讀取現有索引」載入已建立的向量數據
  4. 開始問答:在底部輸入框提問

2. 問答範例

假設已載入道路使用者守則:

  • 「什麼是道路使用者?」
  • 「駕駛者在道路上有哪些義務?」
  • 「行人應該遵守什麼規則?」

3. 參數調整

在側邊欄可以調整以下參數:

參數 說明 默認值
LLM 模型 選擇問答使用的語言模型 gemma3:12b
Embedding 模型 選擇向量化模型 bge-m3
混合檢索 啟用 BM25 + Vector 混合檢索 開啟
查詢擴展 啟用模糊查詢擴展 開啟
子問題生成 啟用複雜問題分解 開啟
Chunk Size 每個文本塊的大小 1000
Chunk Overlap 文本塊之間的重疊 200
檢索文檔數 每次問答檢索的文檔數 2
Temperature 生成創造性 (0-1) 0.0

RAG 流程說明

什麼是 RAG?

RAG (Retrieval-Augmented Generation) 是一種讓 AI 能夠回答特定文檔內容的技術。

本專案的 RAG 流程

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   PDF 文件   │ ──→ │  文本切分   │ ──→ │   向量化    │
└─────────────┘     └─────────────┘     └─────────────┘
                                            │
                                            ▼
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   生成回答   │ ←── │  Prompt 組裝 │ ←── │  混合檢索   │
└─────────────┘     └─────────────┘     └─────────────┘
  1. 文檔攝取 (Ingestion):使用 PyPDFLoader 讀取 PDF
  2. 文本切分 (Splitting):使用 RecursiveCharacterTextSplitter 將長文本切分成小塊
  3. 向量化 (Embedding):使用 Ollama 將文本轉為向量
  4. 混合檢索 (Hybrid Retrieval)
    • BM25 檢索
    • Vector 相似度檢索
    • RRF 結果融合
  5. 查詢處理 (Query Processing)
    • 查詢擴展
    • 子問題生成
  6. 生成回答 (Generation):將檢索到的內容注入 Prompt,讓 LLM 生成答案

模組說明

config.py

所有配置常量,包括:

  • 路徑配置
  • 模型配置
  • 檢索參數

document_processor.py

文檔處理功能:

  • PDF 載入與處理
  • 向量數據庫管理
  • 文檔增刪

rag_chain.py

RAG 鏈構建:

  • 創建 RAG 問答鏈
  • 文檔檢索
  • 上下文格式化

prompts.py

Prompt 模板:

  • QA Prompt
  • 查詢擴展 Prompt
  • 子問題生成 Prompt
  • 摘要 Prompt

hybrid_retriever.py

混合檢索實現:

  • BM25 檢索器
  • Vector 檢索器
  • RRF 結果融合

query_processor.py

查詢處理實現:

  • 查詢擴展
  • 子問題生成
  • 多查詢檢索與融合

api_server.py

FastAPI 伺服器實現:

  • REST API 端點
  • 文件上傳與索引
  • 聊天問答(Streaming)
  • 對話歷史管理
  • Token 使用追蹤

token_tracker.py

Token 使用追蹤模組:

  • 追蹤每個請求的 Token 使用量
  • 每日、每週、每月統計
  • 按模型分類統計
  • 按對話分類統計

常見問題

Q1: 連接 Ollama 失敗

錯誤ConnectionRefusedError

解決

  1. 確認 Ollama 服務正在運行:ollama serve
  2. 確認端口正確(預設 11434)

Q2: 上傳大文件很慢

解決

  1. 將 PDF 頁數控制在 200 頁以內
  2. 減小 Chunk Size

Q3: 回答品質不佳

解決

  1. 嘗試不同的模型
  2. 調整 Temperature 參數
  3. 增加檢索文檔數
  4. 啟用混合檢索和查詢處理

學習要點

完成這個專案後,請確保你理解以下概念:

1. RAG 的核心原理

  • 為什麼需要向量檢索?
  • 如何將文本轉為向量?
  • 為什麼要切分文本?

2. 混合檢索

  • BM25 的原理
  • Vector Search 的原理
  • RRF 融合方法

3. LangChain 的組件

  • Document Loaders
  • Text Splitters
  • Embeddings
  • Vector Stores
  • Chains
  • Retrievers

4. Prompt Engineering

  • 如何設計有效的問答 Prompt?
  • 上下文注入的原理?

參考資源

授權

本專案僅供學習使用。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages