构建一个RAG系统不难,但构建一个可以持续改进的RAG系统很难。大多数团队的困境是:系统上线后,你如何知道它真的好用?修改了某个参数,是变好了还是变差了?没有评估体系,就没有持续优化的基础。本文系统介绍RAG评估的核心框架、关键指标与工程实践。
为什么RAG评估如此重要
一个真实的场景:某公司用LlamaIndex搭建了内部知识库问答系统,初期效果"感觉还不错"。三个月后,有人反馈"很多问题回答错误"。开发团队排查后发现:
- 检索召回率低,相关文档没被找到
- 部分文档在分块时被切割,关键信息丢失
- 模型有时忽略了检索结果,用自身知识回答
但最关键的问题是:他们不知道这些问题从什么时候开始出现的,也不知道哪个问题最严重。没有评估,就没有数据驱动的改进。
RAG评估的三个维度
评估一个RAG系统,需要从三个层面入手:
维度1:检索质量(Retrieval Quality)
检索模块是RAG的"眼睛",如果找不到相关文档,后面什么都是空谈。
关键指标:
- 召回率(Recall@K):对于一个查询,相关文档中有多少比例出现在Top-K结果中
- 精确率(Precision@K):Top-K结果中有多少比例是真正相关的
- MRR(Mean Reciprocal Rank):第一个相关文档出现的位置排名的倒数均值
- NDCG(Normalized Discounted Cumulative Gain):考虑了相关性层次的综合排序指标
def recall_at_k(retrieved_ids: list, relevant_ids: set, k: int) -> float:
"""计算Recall@K"""
top_k = set(retrieved_ids[:k])
if not relevant_ids:
return 0.0
return len(top_k & relevant_ids) / len(relevant_ids)
def precision_at_k(retrieved_ids: list, relevant_ids: set, k: int) -> float:
"""计算Precision@K"""
top_k = retrieved_ids[:k]
if not top_k:
return 0.0
relevant_in_top_k = sum(1 for doc_id in top_k if doc_id in relevant_ids)
return relevant_in_top_k / k
def mrr(retrieved_ids_list: list[list], relevant_ids_list: list[set]) -> float:
"""计算Mean Reciprocal Rank"""
rr_scores = []
for retrieved, relevant in zip(retrieved_ids_list, relevant_ids_list):
for rank, doc_id in enumerate(retrieved, 1):
if doc_id in relevant:
rr_scores.append(1.0 / rank)
break
else:
rr_scores.append(0.0)
return sum(rr_scores) / len(rr_scores) if rr_scores else 0.0
维度2:生成质量(Generation Quality)
即使检索完美,生成模块也可能产生问题:忽略检索结果、幻觉、答非所问。
关键指标:
忠实度(Faithfulness):答案是否基于检索到的上下文,是否有凭空捏造? 答案相关性(Answer Relevance):答案是否回答了用户的问题? 上下文利用率(Context Utilization):提供的上下文有多少被有效利用?
# 使用RAGAS框架评估生成质量
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall
from datasets import Dataset
# 准备评估数据集
eval_data = {
"question": ["什么是RAG?", "如何优化检索效果?"],
"answer": ["RAG是检索增强生成...", "可以通过调整chunk size..."],
"contexts": [
["检索增强生成(RAG)是一种...", "RAG系统由检索器和生成器组成..."],
["优化RAG检索效果的方法包括...", "chunk size是影响检索质量的关键..."],
],
"ground_truth": ["RAG即Retrieval-Augmented Generation...", "优化检索效果可以从..."],
}
dataset = Dataset.from_dict(eval_data)
results = evaluate(
dataset,
metrics=[
faithfulness, # 忠实度
answer_relevancy, # 答案相关性
context_precision, # 上下文精确率
context_recall, # 上下文召回率
]
)
print(results)
维度3:端到端质量(End-to-End Quality)
最终用户关心的是"系统能不能回答好我的问题",需要端到端的综合评估。
关键指标:
- 正确率(Accuracy):与标准答案对比
- 用户满意度(User Satisfaction):真实用户的主观评分
- 任务完成率(Task Completion Rate):需要多轮对话才能完成任务的比例
构建评估数据集
评估的质量直接依赖评估数据集的质量。有三种构建方式:
方式1:人工构建(Golden Dataset)
最可靠但最贵。由领域专家根据实际文档库,人工构建问题-答案对:
# 评估数据集格式
golden_dataset = [
{
"id": "q001",
"question": "公司的退款政策是什么?",
"ground_truth_answer": "根据退款政策,用户在购买后7天内可申请全额退款...",
"relevant_doc_ids": ["policy_doc_v3_p12", "policy_doc_v3_p13"],
"difficulty": "simple", # simple/medium/hard
"category": "policy",
},
...
]
方式2:AI辅助生成(Synthetic Dataset)
用LLM从文档库自动生成问题,人工抽样验证:
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
def generate_qa_from_chunk(chunk: str, llm: ChatOpenAI, n_questions: int = 3) -> list[dict]:
"""从文档块生成QA对"""
prompt = PromptTemplate.from_template("""
基于以下文档内容,生成{n}个有价值的问题和对应的标准答案。
要求:问题应该基于文档内容可以回答,但不要直接复制原文。
文档内容:
{content}
以JSON格式输出,格式如下:
[
{{"question": "问题1", "answer": "答案1"}},
...
]
""")
response = llm.invoke(prompt.format(content=chunk, n=n_questions))
import json
return json.loads(response.content)
# 批量生成
qa_dataset = []
for chunk in document_chunks:
qa_pairs = generate_qa_from_chunk(chunk, llm)
qa_dataset.extend(qa_pairs)
方式3:生产日志挖掘
从真实用户查询日志中挖掘高价值评估样本:
def mine_eval_cases_from_logs(user_logs: list[dict]) -> list[dict]:
"""从用户日志挖掘评估案例"""
eval_cases = []
for log in user_logs:
# 筛选有用户反馈的查询(点赞/踩)
if log.get("feedback") in ["thumbs_up", "thumbs_down"]:
eval_cases.append({
"question": log["query"],
"system_answer": log["answer"],
"user_feedback": log["feedback"],
"contexts_used": log["retrieved_contexts"],
"timestamp": log["timestamp"],
})
# 重点关注负反馈案例
negative_cases = [c for c in eval_cases if c["user_feedback"] == "thumbs_down"]
return negative_cases
自动化评估Pipeline
建立自动化评估流程,让每次改动都能快速看到数字反馈:
import json
from datetime import datetime
from typing import Callable
class RAGEvaluator:
def __init__(self, rag_system, eval_dataset: list[dict], llm_judge=None):
self.rag = rag_system
self.dataset = eval_dataset
self.llm_judge = llm_judge or ChatOpenAI(model="gpt-4o-mini")
def evaluate_faithfulness(self, question: str, answer: str, contexts: list[str]) -> float:
"""用LLM评估答案对上下文的忠实度"""
prompt = f"""
评估以下答案是否完全基于提供的上下文(忠实度评分)。
问题:{question}
上下文:{chr(10).join(contexts)}
答案:{answer}
评分标准(0-1):
1.0:答案完全基于上下文,无任何捏造
0.5:答案主要基于上下文,有轻微延伸
0.0:答案包含上下文中没有的信息或与上下文矛盾
只输出一个0到1之间的小数:
"""
score = float(self.llm_judge.invoke(prompt).content.strip())
return max(0.0, min(1.0, score))
def run_full_evaluation(self, experiment_name: str = None) -> dict:
"""运行完整评估"""
results = []
for item in self.dataset:
question = item["question"]
expected = item.get("ground_truth_answer", "")
# 运行RAG系统
rag_result = self.rag.query(question)
answer = rag_result["answer"]
contexts = rag_result["contexts"]
# 计算各项指标
faithfulness_score = self.evaluate_faithfulness(question, answer, contexts)
results.append({
"question": question,
"answer": answer,
"faithfulness": faithfulness_score,
"contexts_count": len(contexts),
})
# 汇总
avg_faithfulness = sum(r["faithfulness"] for r in results) / len(results)
summary = {
"experiment": experiment_name or datetime.now().isoformat(),
"total_questions": len(results),
"avg_faithfulness": avg_faithfulness,
"timestamp": datetime.now().isoformat(),
}
print(f"评估完成:")
print(f" 忠实度: {avg_faithfulness:.3f}")
return {"summary": summary, "details": results}
常见问题的诊断与修复
有了评估体系,你就能系统诊断问题:
问题:Recall@5低(<0.7) → 检索策略有问题 → 排查:Embedding模型是否适合领域、chunk size是否合理、是否需要混合检索(BM25+向量)
问题:Faithfulness低(<0.8) → 生成模型不忠实上下文 → 排查:系统提示是否强调"基于上下文回答"、上下文是否太长导致模型忽略、是否需要更换模型
问题:Answer Relevancy低(<0.7) → 答案没有回答用户的问题 → 排查:检索到的文档是否真正相关、生成模型是否理解了问题意图
问题:端到端准确率低但各子指标高 → 组合问题,通常是上下文拼接逻辑或最终生成的问题
建立持续评估文化
最后,技术层面的评估体系只是基础。更重要的是建立团队的评估文化:
- 每次重要修改前后都运行评估,对比数字,不凭直觉判断好坏
- 定期(每周/每月)回顾评估趋势,及时发现回退
- 收集真实用户反馈,作为评估数据集的持续补充
- 设立基准(Baseline),记录每个重要版本的评估结果
评估是RAG工程化的核心基础设施。没有评估,就像在黑暗中摸索;有了评估,才能把RAG从"感觉还行"提升到"数据证明可靠"。