引言
“我的RAG系统效果怎么样?“这是每个RAG开发者都会问的问题。但回答这个问题并不简单——RAG系统包含检索和生成两个环节,每个环节都有多个质量维度。
2026年,RAG评估已经形成了一套比较完整的指标体系。从检索的准确率和召回率,到生成的忠实度和相关性,再到端到端的用户满意度。本文将系统介绍这些指标。
一、RAG评估框架
1.1 评估维度
RAG系统
├── 检索质量
│ ├── 准确率(Precision)
│ ├── 召回率(Recall)
│ ├── 排序质量(NDCG/MRR)
│ └── 多样性(Diversity)
├── 生成质量
│ ├── 忠实度(Faithfulness)
│ ├── 答案相关性(Answer Relevance)
│ ├── 完整性(Completeness)
│ └── 正确性(Correctness)
└── 端到端质量
├── 用户满意度
├── 响应延迟
└── 成本效率
1.2 评估方法
- 人工评估:最准确但成本高
- 自动评估:使用LLM或规则自动评估
- 基准测试:在标准数据集上测试
- A/B测试:线上对比不同版本
二、检索质量指标
2.1 准确率与召回率
class RetrievalMetrics:
def precision_at_k(self, retrieved, relevant, k):
"""Top-K准确率"""
retrieved_k = retrieved[:k]
relevant_set = set(relevant)
retrieved_set = set(retrieved_k)
return len(relevant_set & relevant_set) / k
def recall_at_k(self, retrieved, relevant, k):
"""Top-K召回率"""
retrieved_k = retrieved[:k]
relevant_set = set(relevant)
retrieved_set = set(retrieved_k)
return len(retrieved_set & relevant_set) / len(relevant_set)
def average_precision(self, retrieved, relevant):
"""平均准确率"""
relevant_set = set(relevant)
precisions = []
num_relevant = 0
for i, doc in enumerate(retrieved):
if doc in relevant_set:
num_relevant += 1
precisions.append(num_relevant / (i + 1))
if not precisions:
return 0.0
return np.mean(precisions)
def mean_average_precision(self, queries_results):
"""MAP"""
return np.mean([self.average_precision(r["retrieved"], r["relevant"])
for r in queries_results])
2.2 排序质量
def ndcg_at_k(self, retrieved, relevance_scores, k):
"""NDCG@K"""
# DCG
dcg = sum(
(2 ** relevance_scores.get(doc, 0) - 1) / np.log2(i + 2)
for i, doc in enumerate(retrieved[:k])
)
# IDCG(理想排序的DCG)
ideal_order = sorted(relevance_scores.values(), reverse=True)[:k]
idcg = sum(
(2 ** score - 1) / np.log2(i + 2)
for i, score in enumerate(ideal_order)
)
return dcg / idcg if idcg > 0 else 0
def mrr(self, queries_results):
"""平均倒数排名"""
reciprocal_ranks = []
for result in queries_results:
for i, doc in enumerate(result["retrieved"]):
if doc in result["relevant"]:
reciprocal_ranks.append(1 / (i + 1))
break
else:
reciprocal_ranks.append(0)
return np.mean(reciprocal_ranks)
2.3 上下文相关性
class ContextRelevanceMetric:
async def measure(self, question, retrieved_context):
"""评估检索到的上下文与问题的相关性"""
prompt = f"""
问题: {question}
检索到的上下文:
{self.format_context(retrieved_context)}
请评估上下文与问题的相关性:
1. 有多少段落直接相关?
2. 有多少段落间接相关?
3. 有多少段落完全不相关?
4. 相关性评分(0-1)
"""
result = await self.llm.call(prompt)
return result["relevance_score"]
三、生成质量指标
3.1 忠实度(Faithfulness)
答案是否忠实于检索到的上下文,不产生幻觉:
class FaithfulnessMetric:
async def measure(self, answer, context):
"""评估答案对上下文的忠实度"""
# 1. 将答案分解为陈述
statements = await self.extract_statements(answer)
# 2. 逐一验证每个陈述是否被上下文支持
supported = 0
unsupported = []
for stmt in statements:
is_supported = await self.check_support(stmt, context)
if is_supported:
supported += 1
else:
unsupported.append(stmt)
faithfulness = supported / len(statements) if statements else 0
return {
"faithfulness": faithfulness,
"supported_statements": supported,
"unsupported_statements": unsupported
}
async def check_support(self, statement, context):
"""检查陈述是否被上下文支持"""
prompt = f"""
陈述: {statement}
上下文: {context}
这个陈述是否可以从上下文中推导出来?(是/否)
"""
result = await self.llm.call(prompt)
return "是" in result
3.2 答案相关性
答案是否直接回答了用户的问题:
class AnswerRelevanceMetric:
async def measure(self, question, answer):
"""评估答案与问题的相关性"""
# 方法1: 从答案反向生成问题,比较与原始问题的相似度
prompt = f"""
基于以下答案,生成3个可能的问题:
答案: {answer}
"""
generated_questions = await self.llm.call(prompt)
# 计算生成的问题与原始问题的相似度
similarities = []
for gen_q in generated_questions:
sim = await self.compute_similarity(question, gen_q)
similarities.append(sim)
return np.mean(similarities)
3.3 完整性
答案是否覆盖了问题的所有方面:
class CompletenessMetric:
async def measure(self, question, answer, context):
"""评估答案的完整性"""
# 1. 从问题中提取需要回答的要点
points = await self.extract_key_points(question)
# 2. 检查每个要点是否在答案中被覆盖
covered = 0
uncovered = []
for point in points:
is_covered = await self.check_coverage(point, answer)
if is_covered:
covered += 1
else:
uncovered.append(point)
return {
"completeness": covered / len(points) if points else 1.0,
"covered_points": covered,
"uncovered_points": uncovered
}
四、RAGAS框架
RAGAS(RAG Assessment)是2026年最流行的RAG评估框架:
class RAGAS:
"""RAGAS评估框架"""
async def evaluate(self, question, answer, context, ground_truth=None):
"""RAGAS综合评估"""
results = {}
# 1. 上下文精确率(Context Precision)
results["context_precision"] = await self.context_precision(question, context)
# 2. 上下文召回率(Context Recall)
if ground_truth:
results["context_recall"] = await self.context_recall(ground_truth, context)
# 3. 忠实度(Faithfulness)
results["faithfulness"] = await self.faithfulness(answer, context)
# 4. 答案相关性(Answer Relevancy)
results["answer_relevancy"] = await self.answer_relevancy(question, answer)
# 5. 综合得分
results["ragas_score"] = np.mean([
results["context_precision"],
results.get("context_recall", 1.0),
results["faithfulness"],
results["answer_relevancy"]
])
return results
五、端到端评估
5.1 人工评估
class HumanEvaluation:
async def evaluate(self, test_cases, evaluators):
"""人工评估"""
results = []
for case in test_cases:
# 生成RAG回答
rag_answer = await self.rag_system.query(case.question)
# 多个评估员评分
scores = []
for evaluator in evaluators:
score = await evaluator.evaluate(
question=case.question,
answer=rag_answer,
reference=case.expected_answer,
criteria=["accuracy", "completeness", "relevance", "fluency"]
)
scores.append(score)
# 计算平均分和一致性
avg_scores = self.average_scores(scores)
agreement = self.compute_inter_annotator_agreement(scores)
results.append({
"question": case.question,
"answer": rag_answer,
"scores": avg_scores,
"agreement": agreement
})
return results
5.2 LLM-as-Judge
class LLMJudge:
async def judge(self, question, answer, reference=None):
"""使用LLM作为评判"""
prompt = f"""
问题: {question}
答案: {answer}
{"参考答案: " + reference if reference else ""}
请从以下维度评分(1-5分):
1. 准确性: 答案是否事实正确
2. 完整性: 答案是否覆盖所有要点
3. 相关性: 答案是否直接回答问题
4. 流畅性: 答案是否表达清晰
5. 有用性: 答案对用户是否有用
输出JSON格式,包含每个维度的分数和总评。
"""
result = await self.llm.call(prompt)
return result
5.3 在线评估
class OnlineEvaluation:
async def collect_feedback(self, query_id, user_feedback):
"""收集用户反馈"""
# 用户可以点赞/点踩/评分
await self.feedback_store.save({
"query_id": query_id,
"feedback": user_feedback,
"timestamp": time.time()
})
async def analyze_metrics(self, time_window=7*24*3600):
"""分析在线指标"""
feedback = await self.feedback_store.get_recent(time_window)
return {
"satisfaction_rate": self.compute_satisfaction(feedback),
"thumbs_up_rate": self.compute_thumbs_up_rate(feedback),
"follow_up_rate": self.compute_follow_up_rate(feedback), # 用户追问比例
"copy_rate": self.compute_copy_rate(feedback), # 用户复制答案的比例
"regeneration_rate": self.compute_regeneration_rate(feedback) # 用户重新生成的比例
}
六、基准数据集
6.1 常用基准
| 数据集 | 类型 | 特点 |
|---|---|---|
| Natural Questions | 开放域问答 | 真实用户问题 |
| MS MARCO | 段落检索 | 大规模检索基准 |
| HotpotQA | 多跳推理 | 需要多步推理 |
| TriviaQA | 问答 | 事实型问答 |
| KILT | 多任务 | 多种知识密集型任务 |
6.2 自定义评估集
class CustomEvalSetBuilder:
async def build_from_production(self, production_logs, num_samples=100):
"""从生产日志构建评估集"""
# 1. 采样真实用户问题
samples = self.sample_queries(production_logs, num_samples)
# 2. 为每个问题标注标准答案
for sample in samples:
sample.ground_truth = await self.generate_ground_truth(sample)
sample.relevant_docs = await self.identify_relevant_docs(sample)
# 3. 质量审核
reviewed = await self.human_review(samples)
return reviewed
七、持续评估
class ContinuousEvaluation:
async def run_continuous_eval(self):
"""持续评估循环"""
while True:
# 1. 在评估集上运行
results = await self.eval_suite.run(self.rag_system)
# 2. 与基线比较
comparison = self.compare_with_baseline(results)
# 3. 检测退化
if self.has_degradation(comparison):
await self.alert_degradation(comparison)
# 4. 更新仪表盘
await self.update_dashboard(results)
await asyncio.sleep(self.eval_interval)
结语
评估是RAG系统持续改进的基础。没有度量就没有优化。2026年的RAG评估已经形成了多维度、多方法的评估体系——从检索到生成、从自动到人工、从离线到在线。
选择评估指标时,记住:没有单一指标能全面衡量RAG质量。需要根据应用场景选择合适的指标组合。事实型问答关注准确性和忠实度,研究型问答关注完整性和相关性,对话型问答关注连贯性和有用性。
最终,最好的评估指标是用户满意度。所有技术指标都是用户满意度的代理。定期收集用户反馈,让用户告诉你系统是否真的在变好,这才是评估的终极目的。
加入讨论
这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。