本文 AI 產出,尚未審核

LangChain – RAG:檢索增強生成(Retrieval‑Augmented Generation)

主題:Evaluation(檢測品質)


簡介

RAG(Retrieval‑Augmented Generation) 工作流程中,我們把外部文件或知識庫的內容取回來,交給大型語言模型(LLM)產生答案。雖然取回的文字往往能提升答案的正確性與完整度,但 「答案品質」 卻仍然是最終使用者關心的核心指標。

如果沒有系統性的 評估(Evaluation) 機制,我們無法判斷:

  1. 檢索階段 是否成功找到相關文件。
  2. 生成階段 是否正確、忠實、且符合使用者需求。

LangChain 為 RAG 提供了一套完整的評估工具,讓開發者可以在 離線(offline)線上(online) 兩種情境下,快速量化與比較不同的 RAG 配置。本文將從概念說明、實作範例、常見陷阱與最佳實踐,帶你一步步建立可靠的品質檢測流程。


核心概念

1️⃣ 評估指標(Metrics)

指標 定義 何時使用
精確度(Precision) 產生的答案中正確資訊的比例。 需要高可信度的事實性問答(如醫療、法律)。
召回率(Recall) 正確資訊被模型覆蓋的程度。 資料庫龐大且答案可能散落多處時。
F1 Score 精確度與召回率的調和平均。 想要兼顧兩者時的綜合指標。
BLEU / ROUGE 與參考答案的 n‑gram 相似度。 生成式回答的流暢度與資訊覆蓋度。
Hallucination Rate 模型產生虛假資訊的比例。 需要嚴格控制「幻覺」的情境。
Latency 從輸入問題到得到答案的總時間。 交互式系統或即時客服。

小技巧:在 RAG 評估時,Hallucination Rate 常是最值得關注的指標,因為即使 BLEU 很高,若答案中混入錯誤事實,仍會嚴重損害使用者體驗。


2️⃣ 離線評估(Offline Evaluation)

離線評估指的是 使用已標註好的測試資料,不依賴即時 LLM 產生的批改結果。流程大致如下:

  1. 準備 question‑answer (QA) 對,每筆問題皆有一或多個 參考答案
  2. 透過 LangChain 的 RetrievalQAChain 取得檢索結果與生成答案。
  3. langchain.evaluation 套件的 evaluate 方法,計算上述指標。

為什麼先做離線評估?

  • 可快速迭代檢索向量或 Prompt 調校。
  • 不會產生額外的 API 成本(只呼叫一次檢索與 LLM)。

3️⃣ 線上評估(Online Evaluation)

線上評估則是在 真實使用者互動 中即時收集品質回饋,常見做法包括:

  • 人類評審(Human-in‑the‑Loop):讓評審者根據「正確性」與「適切性」給分。
  • 自動批改(LLM Judge):利用另一個 LLM(如 GPT‑4)作為評分模型,稱為 LLM Judge
  • A/B 測試:同時跑兩套不同的 RAG 配置,觀察點擊率、滿意度等指標。

LangChain 已內建 LLMChainPromptTemplate,可以輕鬆組合出 LLM Judge 的 Prompt,示範見下方程式碼。


4️⃣ LangChain 評估工具概覽

模組 功能說明
langchain.evaluation.qa 提供 QAEvalChain,自動比對生成答案與參考答案。
langchain.evaluation.llm_judge 使用 LLM 作為評分者,支援自訂評分標準。
langchain.chains.RetrievalQAChain RAG 核心鏈,整合檢索與生成。
langchain.evaluation.metrics 內建 BLEU、ROUGE、ExactMatch 等指標函式。

程式碼範例

以下示範 Python(LangChain 主要語言),每段程式碼皆附上說明,方便直接貼到自己的環境測試。

範例 1️⃣ 建立基本的 RetrievalQAChain

from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.chains import RetrievalQAChain

# 1. 建立向量資料庫(此處以簡易的文字列表示範)
docs = [
    "Python 是一種廣泛使用的高階程式語言。",
    "LangChain 提供 RAG 工作流的高階抽象。",
    "向量搜尋可以使用 FAISS、Pinecone 等服務。"
]

# 2. 產生向量並建立 FAISS 索引
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_texts(docs, embeddings)

# 3. 建立檢索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

# 4. 組合 LLM 與檢索器成為 RetrievalQAChain
qa_chain = RetrievalQAChain.from_chain_type(
    llm=OpenAI(model_name="gpt-3.5-turbo"),
    chain_type="stuff",          # 把所有檢索結果一次性送入 LLM
    retriever=retriever
)

# 5. 測試一次查詢
question = "什麼是 LangChain?"
answer = qa_chain.run(question)
print("Answer:", answer)

重點retrieverk 參數決定返回多少段文件,過少可能 召回率 低,過多則可能降低 精確度(因為 LLM 必須處理太多資訊)。


範例 2️⃣ 離線評估:使用 QAEvalChain 計算 Exact Match 與 BLEU

from langchain.evaluation.qa import QAEvalChain
from langchain.evaluation.metrics import exact_match, bleu_score

# 假設已有 QA 測試集合
test_cases = [
    {"question": "LangChain 的核心功能是什麼?",
     "answer": "提供檢索增強生成(RAG)工作流的高階抽象。"},
    {"question": "FAISS 是什麼?",
     "answer": "FAISS 是 Facebook AI 所開發的向量相似度搜尋庫。"}
]

# 建立評估鏈(使用同一個 LLM 作為評分者)
eval_chain = QAEvalChain.from_llm(
    llm=OpenAI(model_name="gpt-4"),
    metric_functions=[exact_match, bleu_score]
)

# 逐筆執行評估
results = []
for case in test_cases:
    pred = qa_chain.run(case["question"])
    score = eval_chain.evaluate(
        {"question": case["question"], "answer": case["answer"], "prediction": pred}
    )
    results.append(score)

# 顯示統計
import pandas as pd
df = pd.DataFrame(results)
print(df.mean())

說明exact_match 會檢查生成答案是否與參考答案完全相同,bleu_score 則衡量文字相似度。離線評估的結果可直接作為 模型調校 的依據。


範例 3️⃣ 線上評估:使用 LLM Judge 判斷「幻覺」率

from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

# 1. 定義 Judge Prompt
judge_prompt = PromptTemplate.from_template(
    """以下是一個使用者問題、RAG 系統產生的答案,以及參考答案。請根據以下準則給予 0~1 的分數,\
    1 代表答案完全忠實且沒有幻覺,0 代表答案完全錯誤或包含幻覺。  
    準則:
    - 內容是否與參考答案一致?
    - 是否有新增、捏造的資訊?
    - 語氣與風格是否合適?

    問題: {question}
    參考答案: {reference}
    系統答案: {prediction}
    評分:"""
)

# 2. 建立 Judge Chain(使用較高階的 LLM)
judge_chain = LLMChain(
    llm=OpenAI(model_name="gpt-4"),
    prompt=judge_prompt
)

# 3. 針對單筆測試執行
case = {
    "question": "什麼是向量搜尋?",
    "reference": "向量搜尋是利用高維向量的相似度,從資料庫中快速找出相近的項目。",
    "prediction": qa_chain.run("什麼是向量搜尋?")
}

score_text = judge_chain.run(case)
print("LLM Judge Score:", score_text.strip())

技巧:將 LLM Judge 的分數視為 Hallucination Rate 的 proxy,分數低於 0.6 時建議 回退(fallback)到只返回檢索結果或請使用者重新提問。


範例 4️⃣ A/B 測試兩套檢索策略的線上指標

import time
import random

def run_qa(chain, question):
    start = time.time()
    answer = chain.run(question)
    latency = time.time() - start
    return answer, latency

# 兩套不同的檢索器(k=2 vs k=5)
retriever_a = vectorstore.as_retriever(search_kwargs={"k": 2})
retriever_b = vectorstore.as_retriever(search_kwargs={"k": 5})

qa_a = RetrievalQAChain.from_chain_type(OpenAI(model_name="gpt-3.5-turbo"), retriever=retriever_a)
qa_b = RetrievalQAChain.from_chain_type(OpenAI(model_name="gpt-3.5-turbo"), retriever=retriever_b)

questions = ["LangChain 的主要功能是什麼?", "FAISS 能做什麼?", "向量搜尋的核心概念是什麼?"]
results = {"A": [], "B": []}

for q in questions:
    ans_a, lat_a = run_qa(qa_a, q)
    ans_b, lat_b = run_qa(qa_b, q)

    # 以簡易的字數差距作為 proxy 評分(實務上會放入 LLM Judge)
    score_a = len(ans_a.split())
    score_b = len(ans_b.split())

    results["A"].append({"question": q, "latency": lat_a, "length": score_a})
    results["B"].append({"question": q, "latency": lat_b, "length": score_b})

# 統計比較
import pandas as pd
df_a = pd.DataFrame(results["A"])
df_b = pd.DataFrame(results["B"])

print("Latency 平均 (A):", df_a["latency"].mean())
print("Latency 平均 (B):", df_b["latency"].mean())
print("答案長度平均 (A):", df_a["length"].mean())
print("答案長度平均 (B):", df_b["length"].mean())

觀察點:若 k=5Latency 明顯較高且答案長度沒有明顯提升,則可考慮保留 k=2 的配置。這樣的 A/B 測試 能幫助團隊在 效能 vs. 資訊完整度 之間取得平衡。


範例 5️⃣ 結合自訂指標:計算「事實一致性」

from langchain.evaluation.metrics import factual_consistency

def evaluate_factual_consistency(question, reference, prediction):
    # factual_consistency 會回傳 0~1 的分數
    return factual_consistency(
        question=question,
        reference=reference,
        prediction=prediction,
        llm=OpenAI(model_name="gpt-4")
    )

case = {
    "question": "什麼是向量搜尋?",
    "reference": "向量搜尋是利用高維向量的相似度,從資料庫中快速找出相近的項目。",
    "prediction": qa_chain.run("什麼是向量搜尋?")
}

consistency_score = evaluate_factual_consistency(**case)
print("事實一致性分數:", consistency_score)

實務建議:將 事實一致性Hallucination Rate 結合,可得到更完整的品質圖像;若分數低於 0.7,建議加入 後處理(post‑processing)重新檢索


常見陷阱與最佳實踐

陷阱 可能的後果 最佳實踐
只看 BLEU/ROUGE 文字相似度高,但事實錯誤仍可能發生。 同時追蹤 Hallucination RateFactual Consistency
檢索結果過多(k 太大) LLM 產生的答案冗長、延遲上升。 先做 召回率 評估,找出「最小 k」能滿足資訊需求。
使用同一個 LLM 作為 Judge 可能產生 同質偏見(judge 與生成模型相似),評分不客觀。 盡量選擇 不同模型或不同 temperature 的 LLM 作為 Judge。
測試資料集與實務情境不匹配 離線評估結果無法映射到線上使用者滿意度。 建立 領域特定的測試集,或在測試階段加入 人工審核
忽視 Latency 高精確度的系統在即時客服上會被拋棄。 在評估報表中加入 平均延遲95th percentile latency

進階最佳實踐

  1. 分層評估:先做離線指標(精確度、召回率),再在小流量線上環境加上 LLM Judge,最後全量 A/B 測試。
  2. 自動化管線:將 evaluate 步驟寫成 CI/CD 作業,確保每次模型或向量更新都會產出 品質報告
  3. 回饋迴路:將線上使用者的評分(如 thumbs‑up/down)回寫到訓練資料,持續微調檢索或 Prompt。
  4. 多模型 Ensemble:若單一 LLM 的幻覺率過高,可使用 雙模型投票(如 GPT‑4 + Claude),再以 LLM Judge 統一裁決。

實際應用場景

場景 需要的評估指標 評估流程範例
企業內部文件搜尋 精確度、召回率、Latency 離線使用標註好的 FAQ 建立 QA 對,跑 QAEvalChain;線上加入 LLM Judge 檢測 hallucination。
醫療輔助問答 Hallucination Rate、事實一致性、Exact Match 使用 factual_consistency 與醫學知識圖譜做雙重驗證;若分數低於門檻則回傳「請諮詢醫師」訊息。
電商客服聊天機器人 Latency、F1、使用者滿意度(thumbs‑up) A/B 測試不同檢索向量(商品描述 vs. 評價),同時收集使用者回饋作為線上指標。
教育平台自動批改 BLEU、ROUGE、事實一致性 離線使用教師批改的答案作為參考,計算 BLEU/ROUGE;線上使用 LLM Judge 針對新提交的答案即時打分。
法律文件摘要 Exact Match、Factual Consistency、Hallucination Rate 結合 QAEvalChainLLM Judge,確保摘要不遺漏關鍵條款且不加入虛構內容。

總結

  • RAG 的品質不僅取決於檢索的相關性,也深受生成模型的忠實度影響。
  • LangChain 提供了 離線與線上兩條評估路徑,配合多樣化指標(Exact Match、BLEU、Hallucination Rate、Latency 等),讓開發者能在 效能、成本與正確性 之間取得最佳平衡。
  • 實務上,建議先以小規模測試資料集完成離線評估,接著在預備環境加入 LLM Judge 進行線上驗證,最後以 A/B 測試驗證全量佈署的影響。
  • 記得 持續收集使用者回饋,將真實的滿意度指標回寫到模型或檢索的微調流程,形成閉環的品質提升機制。

透過本文的概念說明與 5 個完整程式碼範例,你已具備構建、評估、優化 RAG 系統的全套工具與最佳實踐。立即在自己的專案中加入評估管線,讓 LangChain 的 RAG 解決方案更可靠、更具商業價值!