RAG 專案的第一個月,你會踩的 5 個坑

🌏 Read English Version


💡 還在評估要不要做 RAG?先看這篇:不是每間公司都該做 RAG——這是判斷標準


你被指派做 RAG 了

老闆說:「我們要做一個內部知識庫搜尋,用 RAG。」

你開始研究。

看了一堆教學,覺得不難:

  • 把文件切成 chunks
  • 用 embedding model 轉成向量
  • 存進 vector database
  • 用戶問問題,找出相關 chunks,丟給 LLM 回答

三天後,你有了一個 demo。

老闆很開心:「太棒了,下個月上線。」

然後你的噩夢開始了。


為什麼 RAG 的 Demo 都很成功,Production 都很慘

根據 2024 年的調查,42% 的 RAG 專案失敗是因為資料處理問題,不是模型問題。

更殘酷的數據:超過 1200 篇 RAG 相關研究論文在 2024 年發表,代表這個領域還在快速演進,沒有「標準答案」。

Demo 成功是因為:

  • 你用了乾淨的測試資料
  • 你只測了 happy path
  • 你知道會問什麼問題,所以答案都「剛好」在 context 裡

Production 失敗是因為:

  • 真實資料又髒又亂又過時
  • 用戶會問你想不到的問題
  • 沒有人告訴用戶「這東西會錯」

以下是你第一個月會踩的 5 個坑。


坑 1:以為 Embedding 就是全部

症狀

你花了很多時間選 embedding model。

OpenAI 的 text-embedding-3-large?還是開源的 bge-large?還是 Cohere 的 embed-v3

比較了一堆 benchmark,選了一個「最好的」。

然後發現:檢索結果還是很爛。

真正的問題:Chunking 策略

Embedding model 只佔 RAG 效果的 30%。

剩下 70% 是 chunking 策略。

NVIDIA 在 2024 年做了一個大規模 benchmark,測試 7 種 chunking 策略。結論是:沒有萬用策略,每種文件類型需要不同的處理方式。

你該知道的 Chunking 選項

Fixed-size chunking(固定大小)

# 最簡單,但最容易出問題
chunk_size = 512
overlap = 50

# 問題:會把一個概念切成兩半
# "客戶可以在 30 天內" | "申請退款"
# 用戶問「退款期限」,兩個 chunk 都可能被漏掉

優點:簡單、快速、可預測 缺點:完全忽略語意邊界,重要資訊會被切斷

Semantic chunking(語意切分)

# 根據語意相似度來切分
# 當兩個句子的 embedding 相似度低於閾值,就切開

from langchain.text_splitter import SemanticChunker

splitter = SemanticChunker(
    embeddings=embedding_model,
    breakpoint_threshold_type="percentile",
    breakpoint_threshold_amount=95
)

優點:保留完整概念 缺點:。每次切分都要跑 embedding,處理大量文件時成本爆炸。

Document-aware chunking(文件感知切分)

# 根據文件結構來切分
# Markdown 按 header 切
# PDF 按頁面或章節切
# Code 按 function 切

# 這通常是最好的起點

實際建議

  1. 先問:你的文件長什麼樣?
    • 技術文件?按 header 切
    • 法律合約?按條款切
    • 對話紀錄?按對話回合切
    • 混合類型?需要分類處理
  2. Chunk size 的經驗法則
    • Factoid 類問題(「退款期限是多少天?」):256-512 tokens
    • 分析類問題(「這個產品的優缺點是什麼?」):1024+ tokens
    • 不確定?先用 512,再根據檢索結果調整
  3. Overlap 很重要
    • 業界建議:10-20% overlap
    • 500 tokens 的 chunk,用 50-100 tokens overlap
    • Overlap 太小會漏資訊,太大會浪費儲存空間
  4. 不要只用一種策略
    • 研究報告用 semantic chunking
    • 財務報表用 page-level chunking
    • 程式碼用 function-level chunking
    • 混合策略通常表現最好

坑 2:沒有處理資料品質就直接上

症狀

你把公司所有文件都丟進 vector database。

Confluence、SharePoint、Google Drive、Slack 對話、Email…

一股腦全部 index。

結果:RAG 會自信地給你過時的、錯誤的、自相矛盾的答案。

Garbage In, Confident Garbage Out

傳統系統的問題是「找不到」。

RAG 的問題是「找到錯的,還很有自信」。

這比找不到更危險。

用戶問:「我們的退款政策是什麼?」

RAG 回答:「根據 2019 年的政策文件,退款期限是 14 天。」

但其實 2023 年已經改成 30 天了。

舊文件還在 index 裡,而且因為寫得更詳細,embedding 相似度可能更高。

你該做的資料處理

1. 資料盤點

在寫任何 code 之前,先回答這些問題:

  • 資料來源有幾個?
  • 每個來源的更新頻率?
  • 有沒有 single source of truth?
  • 同一份資訊是否存在多個版本?

2. 去重

# 不只是完全相同的文件
# 還要處理「幾乎相同」的版本

# 方法 1:MinHash + LSH(快速近似去重)
from datasketch import MinHash, MinHashLSH

# 方法 2:embedding 相似度(更準確但更慢)
# 相似度 > 0.95 的文件,只保留最新版本

3. 版本控制

# 每個 chunk 都要有 metadata
{
    "content": "退款期限為 30 天...",
    "source": "refund-policy.md",
    "version": "2.3",
    "last_updated": "2024-06-15",
    "deprecated": false
}

# 檢索時可以過濾
results = vector_db.query(
    query_embedding,
    filter={"deprecated": False}
)

4. 定期清理

這不是一次性工作。

  • 設定 pipeline,定期掃描過時文件
  • 建立 owner 機制,每份文件有人負責維護
  • 如果沒有人願意維護,這份文件就不該進 index

企業級 RAG 的特殊挑戰

根據統計,企業平均使用 112 個 SaaS 應用程式來儲存內容。

這代表:

  • 資料格式五花八門(PDF、Word、Notion、Confluence、Slack…)
  • 權限管理複雜(不是所有人都該看到所有資料)
  • 沒有統一的 metadata 標準

如果你的公司連 Confluence 都沒人在用,RAG 不會讓情況變好。

RAG 是放大器,不是修復器。


坑 3:沒有定義「成功」長什麼樣

症狀

老闆問:「RAG 上線後效果怎麼樣?」

你說:「呃…用戶有在用。」

老闆:「比之前好嗎?」

你:「呃…應該有吧。」

沒有定義成功指標,就不知道有沒有進步。

Demo 成功 ≠ Production Ready

Demo 的成功標準:

  • 「看起來能動」
  • 「回答看起來合理」
  • 「老闆點頭了」

Production 的成功標準:

  • 檢索準確率是多少?
  • 回答的 faithfulness 是多少?
  • 錯誤回答的比例?
  • 用戶滿意度?
  • 比現有方案好多少?

RAG 評估的三個層次

1. Retrieval 層:找得準不準

# Precision@K:前 K 個結果中,有多少是相關的
# Recall@K:所有相關文件中,有多少出現在前 K 個
# MRR(Mean Reciprocal Rank):第一個正確答案的排名

# 範例:評估 retrieval
def evaluate_retrieval(queries, ground_truth, k=5):
    precision_scores = []
    for query, relevant_docs in zip(queries, ground_truth):
        retrieved = retriever.get_top_k(query, k)
        hits = len(set(retrieved) & set(relevant_docs))
        precision_scores.append(hits / k)
    return sum(precision_scores) / len(precision_scores)

2. Generation 層:答得對不對

# Faithfulness:回答是否基於 context,沒有瞎編
# Answer Relevancy:回答是否切題
# Hallucination Rate:幻覺比例

# 使用 RAGAS 框架評估
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy

results = evaluate(
    dataset,
    metrics=[faithfulness, answer_relevancy]
)

但要注意:根據 benchmark,RAGAS 的 Answer Relevancy 在偵測幻覺方面正確率只有 17%

為什麼?因為現代 LLM 的幻覺不是「答非所問」,而是「答得很像,但細節是錯的」。

3. End-to-End 層:整體效果

  • 用戶任務完成率
  • 用戶滿意度調查
  • 與現有方案的 A/B 測試

建立 Baseline

在上線之前,你需要知道「現狀」是什麼:

## 現狀 Baseline

### 方法:直接搜尋 Confluence

- 用戶找到答案的平均時間:15 分鐘
- 找到正確答案的比例:60%
- 用戶滿意度:3.2/5

### 目標:RAG 系統

- 用戶找到答案的平均時間:< 5 分鐘
- 找到正確答案的比例:> 80%
- 用戶滿意度:> 4.0/5

沒有 baseline,你永遠不知道 RAG 有沒有比「直接用 Google」好。


坑 4:低估了維運成本

症狀

RAG 上線了。

第一週很好。

第二週開始,用戶抱怨:「怎麼問新產品的問題都答不出來?」

你發現:新的產品文件還沒進 index。

RAG 不是「做完就不用管」的系統

RAG 需要持續維運:

1. 資料更新

# 問題:新文件怎麼進來?
# - 手動上傳?(會忘記)
# - 自動同步?(要寫 pipeline)
# - 誰負責確認資料品質?

# 問題:舊文件怎麼處理?
# - 自動標記 deprecated?
# - 手動審核刪除?
# - 保留多久的歷史版本?

2. 模型更新

# 當你換 embedding model 時...
# 所有文件都要重新 embed
# 這可能需要幾小時到幾天

# 成本估算(以 100 萬個 chunks 為例)
# OpenAI text-embedding-3-large: ~$130
# 自架 embedding server: GPU 時間 + 人力

# 更大的問題:換模型後,效果會變嗎?
# 需要重新評估所有 metrics

3. 監控

Production 的 RAG 會「安靜地變爛」。

不像傳統系統會噴 error,RAG 會:

  • 回答品質慢慢下降(但還是有回答)
  • 幻覺比例慢慢上升(但用戶不一定發現)
  • 延遲慢慢變長(但沒有 timeout)

你需要監控三層 metrics:

# 系統層

- Latency P50, P95, P99
- Throughput
- Error rate

# RAG 層

- Retrieval precision(定期抽樣評估)
- Faithfulness score(用 LLM 自動評估)
- 「我不知道」的回答比例

# 業務層

- 用戶滿意度
- 任務完成率
- 每次查詢的成本

4. 成本

上線後的成本往往比開發時高:

項目 一次性成本 每月維運成本
Vector DB(Pinecone Pro) $70+
Embedding API 依用量
LLM API 依用量
資料處理 Pipeline 開發時間 維護時間
監控系統 設定時間 告警處理時間

如果沒有預算持續維運,不要開始這個專案。


坑 5:沒有管理用戶期望

症狀

用戶以為 RAG 是「公司內部的 ChatGPT」。

問什麼都有答案,而且答案都是對的。

然後用戶拿 RAG 的錯誤回答去做決策。

出事了。

RAG 一定會錯

這不是 bug,是 feature。

根據研究,即使是最好的 RAG 系統,faithfulness 也很難超過 95%。

這代表每 20 個回答,有 1 個可能包含錯誤資訊。

而且 RAG 錯的時候,不會說「我不確定」。它會很有自信地告訴你錯誤答案。

這是 epistemic uncertainty:模型不知道自己不知道。

你該怎麼做

1. 上線前就講清楚

## 使用須知

本系統使用 AI 技術回答問題,可能出現錯誤。

- 對於重要決策,請務必查證原始文件
- 如發現錯誤回答,請回報 [連結]
- 本系統不適用於:法律諮詢、財務決策、醫療建議

2. UI 設計要誠實

// ❌ 錯誤:像 Google 一樣,只顯示答案
<Answer text={response} />

// ✅ 正確:顯示來源,讓用戶可以驗證
<Answer text={response} />
<Sources>
  {chunks.map(chunk => (
    <SourceCard
      title={chunk.source}
      link={chunk.url}
      relevance={chunk.score}
    />
  ))}
</Sources>

// ✅ 更好:顯示信心分數
<ConfidenceIndicator score={0.72} />
<Disclaimer>
  AI 生成的回答,建議查證原始文件
</Disclaimer>

3. 設計 Fallback

# 當信心分數太低時,不要硬回答
if confidence_score < 0.5:
    return "我找不到足夠的資訊來回答這個問題。你可以試試:\n" \
           "1. 換個方式問\n" \
           "2. 直接查詢 [知識庫連結]\n" \
           "3. 聯繫 [負責人]"

# 當檢索結果為空時
if len(retrieved_chunks) == 0:
    return "這個問題可能不在我的知識範圍內。"

4. 收集回饋

# 每個回答都要有 feedback 機制
# 「這個回答有幫助嗎?」
# 「這個回答正確嗎?」

# 用這些 feedback 來:
# - 找出常見的錯誤模式
# - 識別知識庫的缺口
# - 調整 retrieval 策略

「我不知道」比「亂講」重要

好的 RAG 系統要能辨識自己的極限。

測試方法:

## Hallucination 測試

1. 問一個知識庫裡沒有的問題
   - 預期:「我找不到相關資訊」
   - 失敗:編造一個答案

2. 用錯誤的前提提問(「聽說你們的退款期限是 7 天?」)
   - 預期:「根據政策,退款期限是 30 天,不是 7 天」
   - 失敗:「是的,退款期限是 7 天」

3. 問一個需要推理的問題(答案不是直接在文件裡)
   - 預期:「我沒有足夠資訊來推論」
   - 失敗:基於不完整資訊做出結論

總結:第一個月的 Checklist

Week 1:資料盤點


  • 列出所有資料來源

  • 評估每個來源的品質和更新頻率

  • 識別重複和過時的內容

  • 決定誰負責維護資料品質

Week 2:Chunking 策略


  • 根據文件類型選擇 chunking 策略

  • 設定 chunk size 和 overlap

  • 測試不同策略的檢索效果

  • 記錄選擇的原因(之後會需要調整)

Week 3:評估框架


  • 建立 baseline metrics

  • 準備測試資料集(包含 ground truth)

  • 設定 retrieval 和 generation 的評估指標

  • 定義「成功」的標準

Week 4:上線準備


  • 設定資料更新 pipeline

  • 設定監控系統

  • 撰寫使用須知

  • 設計 feedback 機制

  • 管理用戶期望

最後的話

RAG 不難。

難的是:

  • 承認你的資料沒有想像中乾淨
  • 承認你的系統會出錯
  • 承認維運需要持續投入

這些不是技術問題,是組織問題。

如果你的公司連 Confluence 都沒人在用, 如果沒有人願意維護知識庫, 如果沒有預算做持續維運,

不要做 RAG。

先把基礎打好。

RAG 是放大器。 你的知識管理本來很好,RAG 會讓它更好。 你的知識管理本來很爛,RAG 會讓它更爛——而且更有自信地爛。

選擇權在你手上。

Leave a Comment