LangChain – RAG:檢索增強生成(Retrieval‑Augmented Generation)
主題:Evaluation(檢測品質)
簡介
在 RAG(Retrieval‑Augmented Generation) 工作流程中,我們把外部文件或知識庫的內容取回來,交給大型語言模型(LLM)產生答案。雖然取回的文字往往能提升答案的正確性與完整度,但 「答案品質」 卻仍然是最終使用者關心的核心指標。
如果沒有系統性的 評估(Evaluation) 機制,我們無法判斷:
- 檢索階段 是否成功找到相關文件。
- 生成階段 是否正確、忠實、且符合使用者需求。
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 產生的批改結果。流程大致如下:
- 準備 question‑answer (QA) 對,每筆問題皆有一或多個 參考答案。
- 透過 LangChain 的
RetrievalQAChain取得檢索結果與生成答案。 - 用
langchain.evaluation套件的evaluate方法,計算上述指標。
為什麼先做離線評估?
- 可快速迭代檢索向量或 Prompt 調校。
- 不會產生額外的 API 成本(只呼叫一次檢索與 LLM)。
3️⃣ 線上評估(Online Evaluation)
線上評估則是在 真實使用者互動 中即時收集品質回饋,常見做法包括:
- 人類評審(Human-in‑the‑Loop):讓評審者根據「正確性」與「適切性」給分。
- 自動批改(LLM Judge):利用另一個 LLM(如 GPT‑4)作為評分模型,稱為 LLM Judge。
- A/B 測試:同時跑兩套不同的 RAG 配置,觀察點擊率、滿意度等指標。
LangChain 已內建 LLMChain 與 PromptTemplate,可以輕鬆組合出 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)
重點:
retriever的k參數決定返回多少段文件,過少可能 召回率 低,過多則可能降低 精確度(因為 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=5的 Latency 明顯較高且答案長度沒有明顯提升,則可考慮保留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 Rate 或 Factual Consistency。 |
| 檢索結果過多(k 太大) | LLM 產生的答案冗長、延遲上升。 | 先做 召回率 評估,找出「最小 k」能滿足資訊需求。 |
| 使用同一個 LLM 作為 Judge | 可能產生 同質偏見(judge 與生成模型相似),評分不客觀。 | 盡量選擇 不同模型或不同 temperature 的 LLM 作為 Judge。 |
| 測試資料集與實務情境不匹配 | 離線評估結果無法映射到線上使用者滿意度。 | 建立 領域特定的測試集,或在測試階段加入 人工審核。 |
| 忽視 Latency | 高精確度的系統在即時客服上會被拋棄。 | 在評估報表中加入 平均延遲、95th percentile latency。 |
進階最佳實踐
- 分層評估:先做離線指標(精確度、召回率),再在小流量線上環境加上 LLM Judge,最後全量 A/B 測試。
- 自動化管線:將
evaluate步驟寫成 CI/CD 作業,確保每次模型或向量更新都會產出 品質報告。 - 回饋迴路:將線上使用者的評分(如 thumbs‑up/down)回寫到訓練資料,持續微調檢索或 Prompt。
- 多模型 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 | 結合 QAEvalChain 與 LLM Judge,確保摘要不遺漏關鍵條款且不加入虛構內容。 |
總結
- RAG 的品質不僅取決於檢索的相關性,也深受生成模型的忠實度影響。
- LangChain 提供了 離線與線上兩條評估路徑,配合多樣化指標(Exact Match、BLEU、Hallucination Rate、Latency 等),讓開發者能在 效能、成本與正確性 之間取得最佳平衡。
- 實務上,建議先以小規模測試資料集完成離線評估,接著在預備環境加入 LLM Judge 進行線上驗證,最後以 A/B 測試驗證全量佈署的影響。
- 記得 持續收集使用者回饋,將真實的滿意度指標回寫到模型或檢索的微調流程,形成閉環的品質提升機制。
透過本文的概念說明與 5 個完整程式碼範例,你已具備構建、評估、優化 RAG 系統的全套工具與最佳實踐。立即在自己的專案中加入評估管線,讓 LangChain 的 RAG 解決方案更可靠、更具商業價值!