依據 RAG_AI_完整教材.md 附錄 A 實作的生產級 PDF / Markdown 智能問答系統。

功能特色

  • 多格式文件載入:PDF、Markdown、TXT、Word
  • Hybrid Search:BM25(中文 jieba 斷詞)+ Vector Search 混合檢索
  • 可選 Re-ranker:BGE Cross-Encoder 精排(預設關閉,省記憶體)
  • Streaming 回應:CLI 與 Streamlit UI 皆支援即時串流
  • 來源引用:每個答案都附上引用的檔名與頁碼
  • 增量索引:新檔自動加入、舊檔更新、刪除孤兒資料
  • Embedding Cache:重複內容不重複呼叫 OpenAI API
  • 抗幻覺 Prompt:找不到資料時明確拒答
  • RAGAS 評估:四大指標自動評測
  • Smoke Test:上線前 regression test

專案結構

RAG_AI/
├── README.md                 # 你正在看
├── RAG_AI_完整教材.md        # 完整教材
├── requirements.txt          # 依賴
├── .env.example              # 環境變數範本
├── .gitignore
├── Makefile                  # 便利指令
├── main.py                   # CLI 進入點
├── data/                     # 放你的文件
│   ├── sample_handbook.md    # 範例:員工手冊
│   └── sample_faq.md         # 範例:FAQ
├── src/
│   ├── config.py             # 集中設定
│   ├── prompts.py            # Prompt 模板
│   ├── ingest.py             # 文件索引腳本
│   ├── rag.py                # RAG 主邏輯(Hybrid + Rerank)
│   ├── app.py                # Streamlit UI
│   └── evaluate.py           # RAGAS 評估
├── tests/
│   ├── test_smoke.py         # Smoke test
│   └── testset.json          # 評估測試集
├── chroma_db/                # (自動產生)向量資料庫
└── embedding_cache/          # (自動產生)embedding 快取

快速開始(5 分鐘)

1. 安裝

make install
source .venv/bin/activate

或手動:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

2. 設定 API Key

cp .env.example .env

編輯 .env 填入:

OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxx

沒有 OpenAI API Key?到 platform.openai.com 註冊,新帳號通常有 $5 試用額度。 跑完整個範例約花 $0.05 美元(embedding + 幾次問答)。

3. 索引範例文件

make ingest

會看到類似:

=== 階段 1:載入文件(從 data)===
  載入 sample_faq.md (1 段)
  載入 sample_handbook.md (1 段)
共載入 2 份段落

=== 階段 2:切塊 ===
切成 18 個 chunks(chunk_size=500)

=== 階段 3:建立 Vector Store ===
  使用 cleanup=incremental

=== 完成 ===
  新增:18
  更新:0
  刪除:0
  跳過:0

4. 開始問答

方式一:互動 CLI

make chat
=== RAG 智能問答 CLI ===
模型:gpt-4o-mini | Re-ranker:off
輸入 'exit' 或 Ctrl-C 離開

問題> 公司年假規定?

回答:員工每年享有 14 天年假,於到職滿一年後生效。年假需於使用日前 3 個工作日於 HR 系統申請,
並經主管核准後生效。未休完的年假可遞延至次年 6 月 30 日前使用,逾期失效。

來源:sample_handbook.md

--- 引用來源 ---
  [1] sample_handbook.md (頁 -): # 范例科技股份有限公司員工手冊...
  [2] sample_handbook.md (頁 -): ### 年假...

方式二:單次提問

make ask Q="DataPilot Pro 的訂閱方案有哪些?"

方式三:Streamlit Web UI

make ui

瀏覽器開 http://localhost:8501

進階設定

所有設定都在 .env,重要參數:

變數 預設 說明
EMBEDDING_MODEL text-embedding-3-small OpenAI embedding 模型
CHAT_MODEL gpt-4o-mini 生成模型;可改 gpt-4o 提升品質
USE_RERANKER false 設為 true 啟用 BGE 重排(首次下載 ~2GB)
TOP_K_RETRIEVE 10 Hybrid 第一階段取出多少 chunks
TOP_N_RERANK 4 Rerank 後保留多少給 LLM
CHUNK_SIZE 500 每塊 token 數
CHUNK_OVERLAP 50 相鄰塊重疊 token 數

啟用 Re-ranker(明顯提升品質)

pip install sentence-transformers torch

.env 改為:

USE_RERANKER=true

重啟 CLI / UI 即可。第一次會下載 BGE 模型(約 2GB),之後從快取讀取。

加入你自己的文件

  1. 把 PDF / Markdown / Word / TXT 放到 data/ 目錄(可建子目錄)
  2. make ingest(增量更新)
  3. 開始問答

要完全重建索引:

make reindex

評估系統品質

pip install ragas datasets
make eval

會跑 tests/testset.json 中的問題,輸出四大指標:

  • Faithfulness:答案是否忠於文件
  • Answer Relevancy:答案是否相關
  • Context Precision:取出的 chunks 相關性
  • Context Recall:是否取齊所需資訊

詳細結果會存到 evaluation_result.csv

Smoke Test

每次改完設定後跑:

make smoke

確保基本問答行為沒退化。

常見問題

Q:為什麼答案說「資料不足」?

A:這是設計如此 — Prompt 強制 LLM 找不到就拒答,避免幻覺。把相關文件放進 data/ 重新 make ingest 即可。

Q:中文檢索品質差怎麼辦?

A: 1. 啟用 Re-ranker(USE_RERANKER=true) 2. 縮小 CHUNK_SIZE 到 300 3. 提高 TOP_K_RETRIEVE 到 20

Q:可以完全離線跑(不用 OpenAI)嗎?

A:可以,但需要改 src/rag.py 的 LLM 與 embedding:

from langchain_ollama import ChatOllama, OllamaEmbeddings

並在 terminal:

ollama pull qwen2.5:7b nomic-embed-text

Q:Streamlit 卡在「載入 RAG 引擎中」?

A:第一次會下載 BGE 模型(如有啟用 Re-ranker)。可以先把 USE_RERANKER 設為 false 加速啟動。

技術棧

  • LangChain 0.3.x — RAG 框架
  • OpenAI — Embedding 與 LLM
  • Chroma — 向量資料庫
  • rank-bm25 + jieba — 中文 BM25 檢索
  • Streamlit — Web UI
  • RAGAS — 評估框架(可選)

延伸閱讀

完整原理與進階技巧請見 RAG_AI_完整教材.md,涵蓋:

  • 16 章從零到生產
  • 9 張 Mermaid 架構圖
  • 64 段 Python 範例
  • Hybrid / HyDE / Multi-Query / Self-RAG / CRAG 進階檢索
  • 生產部署的快取、監控、安全、成本優化

授權

範例專案,可自由修改使用。