RAG05-RAG系统评估
RAG系统评估
1 RAG系统评估工具
1.1 学习目标 ¶
了解RAG系统评估的指标
掌握RAGAS框架的原理和使用方式
1.2 概述 ¶
RAG系统正式上线前,需要评估 RAG 的表现到底是怎样的。如果 效果不够理想,则需要改进。
1.3 RAGAS评估框架 ¶
RAGAS(Retrieval Augmented Generation Assessment)是用于评估 RAG 效果的框架,可帮助分析检索与生成两个环节的表现。项目地址:https://github.com/explodinggradients/ragas
1 数据说明 ¶
RAGAS评估 通常需要一个评估数据集。常见做法是构建包含问题query、检索上下文context、模型答案answer以及真实答案groud_truths 字段的评估数据集。例如:

统一字段说明-全文统一:
| 字段名/术语 | 统一术语 | 记号 | 专业英文 | 说明 |
|---|---|---|---|---|
| question/query | 问题 | $q$ | question/query | 输入 RAG系统的用户查询 |
| answer | 模型答案 | $a$ | model answer | RAG系统生成的答案 |
| contexts | 检索上下文 | $C$ | retrieved contexts | 从知识源检索、用于生成模型答案的上下文 |
| ground_truths | 真实答案 | $gt$ | ground truth | 问题对应的人工标注答案 |
| claim(来自真实答案) | 声明 | $c$ | claim | 从真实答案拆分出的最小事实单元,用于 Context Recall |
| statement(来自模型答案) | 陈述 | $s$ | statement | 从模型答案拆分出的最小事实单元,用于 Faithfulness |
注意:要区分 “声明(claim)”与“陈述(statement)”。
2 评估指标 ¶

评估检索的指标:上下文精确率(Context Precision)、上下文召回率(Context Recall)。
评估生成的指标:忠实度(faithfulness)、模型答案相关性(Answer Relevance)。
上下文精确率 (Context Precision) ¶
作用:衡量检索上下文中“真正与问题相关的信息占比”,越高表示噪声越少。
公式:
$$
\text{Context Precision} = AP平均精确率
$$
Average Precision(AP,平均精确率)
衡量检索结果中相关内容是否排在前面。
相比普通 Precision,AP 不仅关注检索到多少相关内容,还关注相关内容的排序质量。
$n$:检索结果总数(TopK)
$rel(i)$:第 $i$ 个检索结果是否相关
- 相关:$rel(i)=1$
- 不相关:$rel(i)=0$
$P(i)$:前 $i$ 个检索结果的 Precision
则:
$$
AP
==
\frac{\sum_{i=1}^{n}P(i)\times rel(i)}
{\sum_{i=1}^{n}rel(i)}
$$
其中:
$$
P(i)
=\frac{\text{前 }i\text{ 个结果中的相关数量}}
{i}
$$
计算示例
假设 Retriever 返回 Top5:
| 排名 | Context | 是否相关 |
|---|---|---|
| Top1 | Context A | ✓ |
| Top2 | Context B | ✓ |
| Top3 | Context C | ✗ |
| Top4 | Context D | ✓ |
| Top5 | Context E | ✗ |
对应相关性序列:
[1, 1, 0, 1, 0]
计算每个相关 Context 所在位置的 Precision:
| 排名 | 是否相关 | 前 i 个相关数量 | Precision $P(i)$ |
|---|---|---|---|
| Top1 | ✓ | 1 | $1/1=1.00$ |
| Top2 | ✓ | 2 | $2/2=1.00$ |
| Top3 | ✗ | - | 不参与计算 |
| Top4 | ✓ | 3 | $3/4=0.75$ |
| Top5 | ✗ | - | 不参与计算 |
因此:
$$
AP=\frac{1.00+1.00+0.75}{3}=0.92
$$
其中:
- 分子:所有相关 Context所在位置的 Precision 之和
- 分母:相关 Context 的总数量(3)
最终:
Average Precision = 0.92
示例(Context Precision,统一示例)
问题(query):
2026 年世界杯冠军是谁?检索上下文(context):
西班牙获得 2026 年世界杯冠军。
决赛中西班牙击败荷兰。
巴西有丰富的足球文化。
模型答案:
2026 年世界杯冠军是西班牙,比赛在加时赛决出胜负。真实答案:
2026年世界杯的冠军是西班牙。西班牙在决赛中以 1-0 击败了荷兰。
其中与问题直接相关的是前 2 句,因此:
$$
\text{上下文精确率} = \frac{2}{3} \approx 0.67
$$
上下文召回率 (Context Recall) ¶
作用:衡量检索上下文 $C$ 对真实答案 $gt$ 的覆盖程度。
分数范围:$[0,1]$,越高表示“真实答案中的关键信息”被检索到的比例越高。
计算思路:先将 $gt$ 拆成声明集合 $\text{Claim}(gt)$,再判断每条声明是否被 $C$ 支持。
公式:
$$
\text{Context Recall} = \frac{\text{被上下文支持的真实答案声明数}}{\text{真实答案总声明数}}
$$
示例(Context Recall,统一示例)
问题(query):
2026 年世界杯冠军是谁?检索上下文(context):
西班牙获得 2026 年世界杯冠军。
决赛中西班牙击败荷兰。
巴西有丰富的足球文化。
模型答案:
2026 年世界杯冠军是西班牙,比赛在加时赛决出胜负。真实答案:
2026年世界杯的冠军是西班牙。西班牙在决赛中以 1-0 击败了荷兰。
将真实答案拆成 2 条声明:
| 声明Claim | 上下文是否支持 | 结论 |
|---|---|---|
| 声明1:2026年世界杯的冠军是西班牙。 | 明确包含该信息 | 召回 |
| 声明2:西班牙在决赛中以 1-0 击败了荷兰。 | 仅提到“击败荷兰”,未提到“1-0” | 未召回 |
因此:
$$
\text{Context Recall} = \frac{1}{2} = 0.5
$$
忠实度(faithfulness) ¶
作用:指模型答案确实是根据给定的检索上下文得到的。这对于避免幻觉,并确保检索到的上下文可以作为生成依据非常重要。
如果分数低,说明 LLM 的模型答案没有很好遵循检索到的知识,产生幻觉的可能性更高。
公式:
$$
\text{Faithfulness} = \frac{\text{被上下文支持的模型答案陈述数}}{\text{模型答案总陈述数}}
$$
实现方式:
第一步:先让 LLM 从模型答案中提取一组陈述。使用的提示词如下:
给定一个问题和模型答案,从给定模型答案的每个句子中创建一个或多个陈述。
问题:[问题]
模型答案:[模型答案]
- 第二步:生成这组陈述后,LLM 判断每条陈述是否可以从检索上下文中推断出来。这个验证步骤可使用如下提示词:
考虑给定的上下文和以下陈述,然后确定它们是否由上下文中的信息支持。在得出结论(是/否)之前,为每个陈述提供简要解释。在最后以给定格式为每个陈述提供最终结论。不要偏离指定的格式。
陈述:[陈述 1]
...
陈述:[陈述 n]
示例(Faithfulness,统一示例)
问题(query):
2026 年世界杯冠军是谁?检索上下文(context):
西班牙获得 2026 年世界杯冠军。
决赛中西班牙击败荷兰。
巴西有丰富的足球文化。
模型答案:
2026 年世界杯冠军是西班牙,比赛在加时赛决出胜负。真实答案:
2026年世界杯的冠军是西班牙。西班牙在决赛中以 1-0 击败了荷兰。
将模型答案拆成 2 条陈述:
2026 年世界杯冠军是西班牙。
比赛在加时赛决出胜负。
其中第 1 条能被上下文支持,第 2 条无法从给定上下文中推出,因此:
$$
\text{忠实度} = \frac{1}{2} = 0.5
$$
- 直观理解:模型答案里的陈述,能被上下文支持的越多,忠实度就越高。
答案相关性(Answer Relevance) ¶
作用:衡量“模型答案是否围绕原问题作答”,而不是答非所问。
公式:
$$
\text{Answer Relevance} = \frac{1}{n}{\sum \text{COSINE}(\text{模型答案反推问题}, \text{原问题})}
$$
- 由模型答案反推问题的提示词:
为给定答案生成N个问题。
答案:[答案]
N需要自定义,比如3
示例(Answer Relevance,统一示例)
原问题(query):
2026 年世界杯冠军是谁?检索上下文(context):
西班牙获得 2026 年世界杯冠军。
决赛中西班牙击败荷兰。
巴西有丰富的足球文化。
模型答案:
2026 年世界杯冠军是西班牙,比赛在加时赛决出胜负。真实答案:
2026年世界杯的冠军是西班牙。西班牙在决赛中以 1-0 击败了荷兰。
用模型答案反推得到 3 个问题,与原问题余弦相似度分别为:0.92、0.81、0.77。
则:
$$
\text{模型答案相关性} = \frac{0.92 + 0.81 + 0.77}{3} = 0.83
$$
计算步骤:
从模型答案反推 $n$ 个问题 $\hat{q}_i$
计算每个 $\hat{q}_i$ 与原问题 $q$ 的余弦相似度
对相似度取平均,得到最终分数
解释:分数越高,说明模型答案越聚焦原问题。
1.4 本章小结 ¶
本节介绍了 RAG 系统评估的基本方法,重点说明了 RAGAS 的四个核心指标(以下示例均基于统一示例:query=“2026 年世界杯冠军是谁?”)。
| 指标 | 说明 | 公式 | 范围 | 示例 |
|---|---|---|---|---|
| 上下文精确率(Context Precision) | 检索内容与问题的相关程度,越高噪声越少。 | 与问题相关的上下文句子数 / 上下文总句子数 | 0~1 | 相关句 2 条、总句 3 条,得分 2/3≈0.67 |
| 上下文召回率(Context Recall) | 真实答案中的关键信息被检索覆盖的程度。 | 被上下文支持的真实答案声明数 / 真实答案总声明数 | 0~1 | 支持 1 条、总陈述 2 条,得分 1/2=0.5 |
| 忠实度(Faithfulness) | 模型答案是否真正依据检索上下文生成。 | 被上下文支持的模型答案陈述数 / 模型答案总陈述数 | 0~1 | 支持 1 条、总陈述 2 条,得分 1/2=0.5 |
| 答案相关性(Answer Relevance) | 模型答案是否围绕原问题作答。 | 模型答案反推问题与原问题的相似度之和 / 反推问题数量 | 0~1 | 相似度 0.92、0.81、0.77,均值约 0.83 |
2 实现EduRAG系统的评估
2.1 学习目标 ¶
理解 RAGAS 在 RAG 系统评估中的作用。
掌握使用 RAGAS 评估核心指标的方法。
2.2 功能描述 ¶
generate_eval_data.py 用于生成RAG系统的评估数据集,核心功能包括:
读取原始评估数据
对每个 question,调用真实 RAG 系统获取 contexts, answer
将 question + contexts + answer + ground_truth 写入 最终评估数据集 rag_evaluate_data_real.json
ragas_evaluate.py 用于评估 RAG 系统,核心功能包括:
加载评估数据集 rag_evaluate_data_real.json
转换为 RAGAS 所需的 Dataset 格式。
初始化 LLM 和 embedding 模型。
计算 Faithfulness、Answer Relevance、Context Precision 和 Context Recall 四项指标。
输出结果并保存为 CSV。
2.3 完整代码 ¶
"""
调用 RAG 系统生成评估数据集 rag_evaluate_data_real.json
流程说明:
1. 读取原始评估数据 rag_evaluate_data.json(仅使用 question 和 ground_truth)
2. 对每个 question,调用真实 RAG 系统获取:
- contexts:向量检索命中的文档(来自 Milvus 混合检索 + 重排)
- answer:LLM 基于上下文生成的答案(来自 DashScope API)
3. 将 question + contexts + answer + ground_truth 写入 rag_evaluate_data_real.json
4. 该文件可供 ragas_evaluate.py 做 RAGAS 评估,反映 RAG 系统的真实表现
注意:
- 不修改原始 rag_evaluate_data.json
- contexts 和 answer 完全来自 RAG 系统的实际输出
- 如果检索为空,contexts 为 [],answer 可能为 LLM 自由生成或兜底回复
"""
import json
import os
import sys
import time
# 添加项目根目录到 sys.path,确保模块导入正常
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..'))
sys.path.insert(0, PROJECT_ROOT)
from base.config import config
from base.logger import logger
from rag_qa.core.vector_store import VectorStore
from rag_qa.core.rag_system import RAGSystem
from rag_qa.core.prompts import RAGPrompts
from openai import OpenAI
# 1. 初始化 RAG 系统
def init_rag_system():
"""初始化向量库和 RAG 系统"""
logger.info("=" * 50)
logger.info("正在初始化 RAG 系统...")
logger.info("=" * 50)
client = OpenAI(
api_key=config.DASHSCOPE_API_KEY,
base_url=config.DASHSCOPE_BASE_URL
)
def call_dashscope_api(prompt, system_prompt=None):
"""DashScope API 调用,支持传入 system_prompt"""
try:
if system_prompt is None:
system_prompt = RAGPrompts.rag_system_prompt()
completion = client.chat.completions.create(
model=config.LLM_MODEL,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}
],
temperature=0.1
)
return completion.choices[0].message.content if completion.choices else ""
except Exception as e:
logger.error(f"调用 DashScope API 异常: {e}")
return f"出问题了,请联系客服: {config.CUSTOMER_SERVICE_PHONE}!"
vector_store = VectorStore()
rag_system = RAGSystem(
vector_store=vector_store,
llm=call_dashscope_api,
)
logger.info("RAG 系统初始化完成")
return rag_system
# 2. 对单个问题执行 RAG 流程
def process_question(rag_system, question):
"""
对单个问题执行完整的 RAG 流程,返回真实的 contexts 和 answer。
评估时始终执行检索(不依赖 BERT 分类),因为评估数据集的问题
全部来自知识库覆盖范围,目的是测试 RAG 管道的检索+生成能力。
:param rag_system: RAGSystem 实例
:param question: 用户问题
:return: (contexts, answer)
"""
# 2.1 始终执行检索(评估目的:测试完整 RAG 管道)
# 如果按 BERT 分类跳过检索,"通用知识"类问题会得到空 contexts,
# 导致 Faithfulness/ContextRecall/ContextPrecision 全部失真
strategy = rag_system.strategy_selector.select_strategy(question)
logger.info(f"问题: '{question}' → 检索策略: {strategy}")
context_docs = rag_system.retrieve_and_merge(question, strategy=strategy)
contexts = []
if context_docs:
for doc in context_docs:
if hasattr(doc, "page_content"):
contexts.append(doc.page_content)
elif isinstance(doc, dict):
contexts.append(doc.get("page_content", ""))
else:
contexts.append(str(doc))
logger.info(f"检索到 {len(contexts)} 个上下文文档")
else:
logger.info("未检索到相关文档")
# 2.2 基于检索到的上下文生成答案
if contexts:
context_text = "\n\n".join(contexts)
prompt_input = rag_system.rag_prompt.format(
context=context_text,
history="",
question=question,
phone=config.CUSTOMER_SERVICE_PHONE
)
# 消耗生成器,收集完整回答
llm_result = rag_system.llm(prompt_input)
if isinstance(llm_result, str):
answer = llm_result
else:
answer = ''.join(llm_result)
logger.info(f"基于上下文生成答案,长度: {len(answer)} 字符")
else:
# 检索为空时,让 RAG 系统自然处理:
# - 通用知识类query → general_prompt + general_system_prompt → LLM 直接回答
# - 专业咨询类query → rag_prompt(空context) + rag_system_prompt → "信息不足"
answer = ''.join(rag_system.generate_answer(question))
logger.info(f"无上下文,由 RAG 系统自然处理,长度: {len(answer)} 字符")
return contexts, answer
# 3. 生成 RAG 评估数据集
def generate_rag_eval_data():
"""
生成 RAG 评估数据集:读取原始问题,调用 RAG 系统获取 contexts 和 answer,
输出 rag_evaluate_data_real.json 供 RAGAS 评估使用。
:return: 输出文件路径(str)
"""
# 3.1 读取原始评估数据(仅使用 question 和 ground_truth)
input_file = os.path.join(SCRIPT_DIR, "rag_evaluate_data.json")
output_file = os.path.join(SCRIPT_DIR, "rag_evaluate_data_real.json")
with open(input_file, "r", encoding="utf-8") as f:
original_data = json.load(f)
logger.info(f"读取 {len(original_data)} 个评估问题,来自: {input_file}")
# 3.2 初始化 RAG 系统
rag_system = init_rag_system()
# 3.3 逐个问题调用 RAG 系统
eval_data = []
success_count = 0
fail_count = 0
for i, item in enumerate(original_data):
question = item["question"]
ground_truth = item["ground_truth"]
logger.info(f"\n{'='*50}")
logger.info(f"[{i+1}/{len(original_data)}] 处理问题: {question}")
logger.info(f"{'='*50}")
start_time = time.time()
try:
contexts, answer = process_question(rag_system, question)
duration = time.time() - start_time
logger.info(f"处理完成, 耗时: {duration:.2f}s")
success_count += 1
except Exception as e:
duration = time.time() - start_time
logger.error(f"处理失败, 耗时: {duration:.2f}s, 错误: {e}")
contexts = []
answer = ""
fail_count += 1
eval_data.append({
"question": question,
"contexts": contexts,
"answer": answer,
"ground_truth": ground_truth
})
# 每个问题处理完后保存一次(防止中断丢失数据)
with open(output_file, "w", encoding="utf-8") as f:
json.dump(eval_data, f, ensure_ascii=False, indent=2)
# 3.4 输出统计 + 诊断信息
has_context = sum(1 for item in eval_data if item["contexts"])
no_context = sum(1 for item in eval_data if not item["contexts"])
logger.info(f"\n{'='*50}")
logger.info(f"评估数据生成完成!")
logger.info(f"总计: {len(original_data)} 个问题")
logger.info(f"成功: {success_count}, 失败: {fail_count}")
logger.info(f"有上下文: {has_context}, 无上下文: {no_context}")
if no_context > 0:
logger.warning(f"以下问题未检索到上下文(可能影响评估指标):")
for item in eval_data:
if not item["contexts"]:
logger.warning(f" - {item['question']}")
logger.info(f"数据已保存到: {output_file}")
logger.info(f"{'='*50}")
return output_file
def main():
generate_rag_eval_data()
if __name__ == "__main__":
main()
"""
用 RAGAS 对 RAG 系统做自动化评估。
流程说明(6步):
1. 读取评估数据(JSON 文件)
2. 转成 RAGAS 要求的数据格式(Dataset)
3. 初始化评估所需模型(LLM + Embedding)
4. 计算评估指标
5. 打印并保存评估结果
"""
import json
import os
import sys
import pandas as pd
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
Faithfulness, # 忠实度
AnswerRelevancy, # 答案相关度
ContextPrecision, # 上下文相关度
ContextRecall # 上下文召回
)
from langchain_openai import ChatOpenAI
from langchain_community.embeddings import DashScopeEmbeddings
# 添加项目根目录到 sys.path,确保模块导入正常
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..'))
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
from base.config import config
from rag_qa.rag_assesment.generate_eval_data import generate_rag_eval_data
# 0) 自动生成 RAG 评估数据集(调用真实 RAG 系统)
print("开始生成 RAG 评估数据集...")
data_file = os.path.join(SCRIPT_DIR, "rag_evaluate_data_real.json")
# 如果data_file不存在,则生成
if not os.path.exists(data_file):
data_file = generate_rag_eval_data()
print(f"RAG 评估数据集已生成: {data_file}")
else:
print("RAG 评估数据集已存在")
# 1) 读取评估数据(RAG 系统真实输出的 question、contexts、answer、ground_truth)
with open(data_file, "r", encoding="utf-8") as f:
data = json.load(f)
# 3) 转成 RAGAS 需要的字段结构
# 注意:字段名要与评估指标要求一致
eval_data = {
"question": [item["question"] for item in data], # 问题列表
"answer": [item["answer"] for item in data], # 模型回答列表
"contexts": [item["contexts"] for item in data], # 上下文列表(list[str])
"ground_truth": [item["ground_truth"] for item in data] # 真实答案列表
}
dataset = Dataset.from_dict(eval_data)
# 4) 初始化 LLM(用于部分指标的判分推理)
# qwen-plus
llm = ChatOpenAI(
model_name=config.LLM_MODEL,
openai_api_base=config.DASHSCOPE_BASE_URL,
openai_api_key=config.DASHSCOPE_API_KEY,
temperature=0 # 固定输出,减少随机性
)
# 5) 初始化 Embedding(用于语义相似度类指标)
embeddings = DashScopeEmbeddings(
model="text-embedding-v4",
dashscope_api_key=config.DASHSCOPE_API_KEY
)
# 6) 执行评估
# 指标含义:
# - Faithfulness:回答是否忠于给定上下文
# - AnswerRelevancy:回答与问题是否相关
# - ContextPrecision:上下文中无关内容是否少
# - ContextRecall:上下文是否覆盖真实答案所需信息
result = evaluate(
dataset=dataset,
metrics=[
Faithfulness(),
AnswerRelevancy(),
ContextPrecision(),
ContextRecall()
],
llm=llm,
embeddings=embeddings
)
# 6) 输出并保存结果
print("RAGAS 评估结果:")
print(result)
# 保存为 CSV,便于后续查看和汇报(使用绝对路径)
result_csv = os.path.join(SCRIPT_DIR, "ragas_evaluation_results.csv")
result_df = pd.DataFrame([result])
result_df.to_csv(result_csv, index=False)
print(f"评估结果已保存到: {result_csv}")
2.4 说明 ¶
数据集字段:通常包括
question、answer、contexts和ground_truth。answer对应模型答案,ground_truth对应真实答案。contexts必须是列表,即使只有一段上下文,也应写成["context text"]。指标说明:Faithfulness 表示模型答案是否忠于上下文;Answer Relevance 表示模型答案与问题是否匹配;Context Precision 表示上下文是否与问题相关;Context Recall 表示上下文是否覆盖真实答案所需信息。
环境配置:
ChatOpenAI用于评估推理,OpenAIEmbeddings用于语义相似度计算,也可替换为其他兼容 LangChain 的模型。结果形式:输出为 0 到 1 的分数字典,分数越高越好,例如:
{
'faithfulness':0.95,
'answer_relevance':0.92,
'context_relevance':0.90,
'context_recall':0.93
}
结果可保存为 CSV 文件(
ragas_evaluation_results.csv),便于多次运行对比。这套代码结构通用,只需替换数据集和模型配置即可迁移到其他 RAG 系统。
如有需要,还可以扩展更多指标或添加自定义数据处理逻辑。
2.5 章节总结 ¶
详细介绍了使用RAGAS评估RAG系统的完整流程。
3 RAG评估数据集的构造(扩展)
3.1 学习目标 ¶
掌握 RAG 性能评估的指标。
实现 RAG 评估数据集的构造。
3.2 引言 ¶
优化 RAG 不能只靠“试错”。仅凭少量问答的主观判断,很难确认某次改动是否真正有效。
要稳定优化 RAG,需要建立量化指标并准备高质量评估数据集。只有通过结构化评估,才能客观比较不同方案的效果。
3.3 结构化评估 RAG 的性能 ¶
RAG 系统评估通常分为两部分:
检索评估(Retrieval Evaluation):检索内容是否相关。
生成评估(Generation Evaluation):模型答案是否正确、完整。
端到端评估可重点关注以下四类指标:
Groundedness(可靠性):检索内容能否为模型答案提供可靠支撑。
Completeness(完整性):模型答案是否覆盖问题的关键信息。
Utilization(利用率):检索到的信息是否被模型有效使用。
Relevance(相关性):检索内容与用户问题是否匹配。
这些指标都依赖高质量测试样本和清晰的评估流程。
3.4 使用 Agents 完成 RAG 性能基准测试 ¶
在基准测试流程中,三个常见代理的分工如下:
测试样本代理(Test Sample Agent):生成评估所需的 QA 样本。
样本质量评价代理(Critique Agent):筛选并校验样本质量。
评估代理(Evaluation Agent):依据指标对系统表现打分。
三者配合后,可以形成一套完整的 RAG 性能评估流程。
1 生成测试样本 ¶
评估 RAG 性能时,首先要生成测试样本。测试样本代理(Test Sample Agent)可以自动构造一批 QA 样本,既可用于快速验证,也可用于大规模评估。
如果面向特定知识库,通常建议先生成至少 200 个样本,因为经过质量筛选后,可保留的有效样本往往会明显减少。
以下是生成 QA 样本的提示词:
QA_generation_prompt
=
"""
你的任务是:根据给定的上下文,编写一个事实型问题及其真实答案。
你提出的事实型问题应能通过上下文中的具体、简明的事实信息来回答。
你的问题风格应与用户在搜索引擎中提出的问题类似。
这意味着你提出的问题**不能**包含“根据段落”或“根据上下文”等措辞。
请按以下格式给出你的输出:
输出
:
::
事实型问题:(你的问题)
真实答案:(你对该问题的回答)
以下是上下文内容:
上下文:{context}
\n
输出
:
::"""
2 检查样本质量 ¶
自动生成的样本可能存在质量问题,因此需要使用样本质量评价代理(Critique Agent)进行审核,例如:
问题是否清晰、无歧义。
问题是否适合目标知识领域。
当任一评价维度得分过低时,可直接剔除该样本。
提示:让代理先输出评分依据,再给出最终分数,通常能提升评分稳定性。以下是评估样本质量的提示词:
question_groundedness_critique_prompt = """
你将获得一个上下文和一个问题。
你的任务是给出一个总评分,评估该问题是否能够通过给定上下文明确无歧义地回答。
请在 1 到 5 分之间评分:
1 表示完全无法根据上下文回答,5 表示可以清晰无歧义回答。
请输出:
Feedback: <详细反馈>
[RESULT] <1-5整数>
"""
print("question_groundedness_critique_prompt loaded")
3 设置评估代理 ¶
最后,我们需要在测试数据集上评估 RAG 系统的表现,核心包括三部分:
选择评估指标:优先关注 faithfulness(可靠性),它能较全面地反映端到端效果。
选择评估模型:可使用 GPT-4,也可尝试
kaist-ai/prometheus-13b-v1.0或BAAI/JudgeLM-33B-v1.0。设计评估提示词:明确评分标准(如 1 到 5 分),并要求模型先给出评分依据,再输出最终分数。
提示:评分标准越清晰,评估结果越稳定、一致。以下是 RAG 评估模型的提示词:
EVALUATION_PROMPT = """
### 任务描述
提供了一条指令(可能包含输入)、待评估模型答案、真实答案与评分细则。
1. 根据评分细则严格评估模型答案质量并给出详细反馈。
2. 在反馈后给出 1 到 5 的整数分数。
3. 输出格式:
Feedback: <详细反馈>
[RESULT] <1-5整数>
"""
print("EVALUATION_PROMPT loaded")
3.5 本章小结 ¶
准备高质量的评估数据集是优化 RAG 性能的基础。通过引入生成代理和评价代理,我们可以建立一个系统化的评估流程,确保每个调整都有量化依据。这种基于数据驱动的方法不仅能帮助开发者快速迭代 RAG 系统,还能避免无效尝试导致的时间浪费。
版权声明
本文为 程序员青阳 原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文链接及本声明。