RAG 评估指南:怎么知道你的 RAG 好不好
你搭了一个 RAG 系统,回答问题,Demo 看起来很好。然后有用户提了一个问题,系统自信地给出了一个错误答案——引用的是一个完全不相关的文档。问题出在哪?你不知道,因为你没有任何量化评估。在 RAG 上线之前,你需要一套评估体系,不然问题只会在生产环境里被用户发现。
RAG 评估的三个核心指标
RAG 系统的质量由三个正交的维度决定:
Faithfulness(忠实度)
问题:模型的回答,是否真的来自检索到的上下文?还是在凭空捏造?
忠实度低 = 幻觉。即使检索到了正确文档,模型也可能「不按文档回答」,编造内容。
评分示意:
- 高忠实度(> 0.85):回答中每个声明都能在检索文档中找到依据
- 低忠实度(< 0.6):回答中存在文档中没有的信息
Answer Relevance(回答相关性)
问题:模型的回答,有没有真正回应用户的问题?
可能出现的失败模式:检索到正确文档,但模型回答了文档里的其他内容,没有正面回答用户的问题。
Context Precision(上下文精度)
问题:检索到的文档,有多少是真正有用的?
| 情况 | 说明 |
|---|---|
| 高 Precision + 低 Recall | 检索到的都是对的,但漏了重要文档 |
| 低 Precision + 高 Recall | 检索了很多,但大多数不相关 |
| 高 Precision + 高 Recall | 理想状态 |
工具选型
RAGAS
最成熟的 RAG 评估指标库。直接实现了 Faithfulness、Answer Relevancy、Context Precision 等指标,原生支持 LangChain 和 LlamaIndex。评分基于 LLM-as-Judge,不需要人工标注。
TruLens
评估 + Tracing 二合一框架。可以对 LangChain、LlamaIndex 应用进行端到端追踪,同时实时计算质量指标。适合需要把评估嵌入应用监控的场景。
LLM-as-Judge(自建)
用另一个 LLM 调用评估输出质量,成本可控,灵活度高,但需要精心设计评估 prompt。
实战:用 RAGAS 评估你的 RAG Pipeline
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_precision,
context_recall,
)
# 每条数据需要:问题、生成的答案、检索到的上下文、(可选)标准答案
eval_data = {
"question": [
"What is the return policy?",
"How do I reset my password?",
"What payment methods are accepted?",
],
"answer": [
"You can return items within 30 days of purchase.",
"Click 'Forgot Password' on the login page and follow the email instructions.",
"We accept Visa, Mastercard, and PayPal.",
],
"contexts": [
["Our return policy allows returns within 30 days. Items must be unused."],
["To reset your password, click 'Forgot Password' and check your email."],
["Accepted payment methods: Visa, Mastercard, American Express, PayPal."],
],
"ground_truth": [
"Items can be returned within 30 days if unused.",
"Use the 'Forgot Password' link and follow email instructions.",
"Visa, Mastercard, American Express, and PayPal are accepted.",
],
}
dataset = Dataset.from_dict(eval_data)
result = evaluate(
dataset,
metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
)
print(result)
# 输出示例:
# {'faithfulness': 0.92, 'answer_relevancy': 0.88,
# 'context_precision': 0.85, 'context_recall': 0.79}参考分数线(不同场景会有差异):
| 指标 | 合格 | 良好 | 优秀 |
|---|---|---|---|
| Faithfulness | > 0.75 | > 0.85 | > 0.92 |
| Answer Relevancy | > 0.70 | > 0.80 | > 0.90 |
| Context Precision | > 0.65 | > 0.80 | > 0.90 |
构建评估数据集
评估的质量取决于数据集的质量。三种构建方式:
合成数据集(最快,适合起步)
用 LLM 从你的语料库自动生成问答对:
from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple, reasoning, multi_context
generator = TestsetGenerator.with_openai()
testset = generator.generate_with_langchain_docs(
documents, # 你的知识库文档
test_size=50, # 生成 50 个问答对
distributions={
simple: 0.5, # 50% 简单问题
reasoning: 0.3, # 30% 推理问题
multi_context: 0.2, # 20% 多文档问题
},
)人工标注数据集(最准确,适合关键场景)
- 由领域专家手工编写问题和标准答案
- 成本高,但质量最可靠
- 建议至少准备 20 条「黄金问答」覆盖核心场景
生产数据采样(最接近真实,需要隐私处理)
从生产流量中随机采样真实用户问题,人工标注:
sampled_queries = (
db.query(ProductionTrace)
.filter(ProductionTrace.date >= "2024-01-01")
.order_by(func.random())
.limit(100)
.all()
)
for q in sampled_queries:
print(f"Q: {q.user_query}")
print(f"A: {q.model_response}")
print("---")最小可行数据集:50 个问答对足以起步。其中至少包含:
- 10 个核心场景的「应该能回答好」的问题
- 10 个「答案不在语料库里」的问题(测试模型是否知道说不知道)
- 10 个需要跨多个文档综合的问题
持续评估:CI 里跑 RAG 评分
每次改动检索参数(embedding 模型、chunk size、top-k)都应该跑一次评估:
# evaluate_rag.py — 在 CI 中运行
import sys
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
THRESHOLDS = {
"faithfulness": 0.80,
"answer_relevancy": 0.75,
}
def run_evaluation(dataset):
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
failed = []
for metric, threshold in THRESHOLDS.items():
score = result[metric]
status = "✅" if score >= threshold else "❌"
print(f"{status} {metric}: {score:.3f} (threshold: {threshold})")
if score < threshold:
failed.append(metric)
if failed:
print(f"\nFailed metrics: {failed}")
sys.exit(1) # CI 失败
if __name__ == "__main__":
dataset = load_eval_dataset("eval_dataset.json")
run_evaluation(dataset)# .github/workflows/rag-eval.yml
name: RAG Evaluation
on:
push:
paths:
- "rag/**"
- "embeddings/**"
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run RAG evaluation
run: python evaluate_rag.py
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}常见失败模式
理解常见失败模式能帮你更快定位问题:
检索失败(Retrieval Failure)
症状:Context Precision 低,但语料库里有正确答案。
原因:
- Chunk size 太大或太小,把关键信息切断了
- Embedding 模型对领域词汇不理解(通用模型 vs 领域模型)
- Top-k 太小,正确文档没被召回
排查方法:用已知答案的问题,检查检索到的 top-5 文档,看正确文档排在第几位。
生成失败(Generation Failure)
症状:Context Precision 高,但 Faithfulness 低——正确文档检索到了,但模型没有按文档回答。
原因:
- 上下文太长,模型「忘记」了关键部分(Long Context Forgetting)
- Prompt 指令不够明确,没有要求模型严格基于上下文
- 模型本身的幻觉倾向(小模型问题更严重)
修复:在 System Prompt 中明确加入「只基于提供的上下文回答,如果上下文中没有答案,请说不知道」。
覆盖失败(Coverage Failure)
症状:用户问了一个答案确实不在语料库里的问题,但模型没有说「不知道」,而是编造了答案。
防护:在评估集中加入「超出范围的问题」,测试模型是否能正确拒绝回答。
延伸阅读
- RAGAS 文档 — 最全面的 RAG 评估指标文档
- TruLens — 评估 + Tracing 一体化框架
- LlamaIndex 评估指南 — LlamaIndex 官方评估最佳实践