如何利用框架,使用大模型评估RAG效果(附文档代码)
导读

众所周知,没有评估就没有优化。眼下RAG(检索增强生成)是很多AI落地场景的主流方案,但光有方案还不够,怎么量化它的效果,才是真正考验人的地方。这篇文章会聊几种主流的RAG评估框架,读完你会对以下几点有个清晰的认知:
- 如何让大模型来“考核”大模型
- 这些框架具体怎么用
- 配套的文档和代码长什么样
LlamaIndex是LLM(大语言模型)应用开发中的常客,开发人员用它来搭建RAG应用的频率非常高。而在开发RAG应用的过程中,评估数据的好坏直接关系到后续的调优方向。好在随着RAG技术本身的演进,评估工具也变得更加高效和精准了。这篇文章会介绍几个能与LlamaIndex配合使用的RAG评估工具,并拿它们来做个横向对比。
RAG 评估工具是什么?
简单说,RAG评估工具就是一套用来给检索增强生成(RAG)这类文本生成系统打分的方法论。它们评估的维度包括准确性、内容质量和相关性等。对于开发人员来说,这些工具能帮他们摸清应用的底细,并找到优化的方向。和人工评估比起来,机器评估更客观、更准确、更高效——自动化了就能批量化。有些激进的做法甚至把这些工具直接嵌入了CI/CD流程,实现评估和优化的全自动化。
实体术语
聊RAG评估,有些术语是绕不开的。不同工具的叫法可能有点出入,但核心逻辑一致。下面是几个常见的实体定义:
- 指用户的查询,有些工具里也叫“输入”或“查询”。
问题:
- 指检索回来的文档片段,有时也被称为“检索上下文”。
上下文:
- 指系统生成的回复,也可能被称作“实际输出”或“响应”。
答案:
- 指人工标注的正确结果,用来衡量生成答案的准确性。
标准答案:
为了行文一致,下文会统一使用这组术语。
准备工作
测试文档
这次我们拿漫威的《复仇者联盟》系列电影来当测试素材。数据主要来自维基百科上关于该系列的词条,包含了四部电影的情节信息。
数据集
基于上述文档,我们准备了一个包含了“问题”和“标准答案”的数据集。具体如下:
questions = [
"洛基在征服地球的尝试中使用了什么神秘的物体?",
"复仇者联盟的哪两名成员创造了奥创?",
"灭霸如何实现了他在宇宙中消灭一半生命的计划?",
"复仇者联盟用什么方法扭转了灭霸的行动?",
"复仇者联盟的哪位成员牺牲了自己来打败灭霸?",
]
ground_truth = [
"六角宝",
"托尼·斯塔克(钢铁侠)和布鲁斯·班纳(绿巨人浩克)。",
"通过使用六颗无限宝石",
"通过时间旅行收集宝石。",
"托尼·斯塔克(钢铁侠)",
]
检索引擎
接下来,我们用LlamaIndex搭建一个标准的RAG检索引擎。评估工具会基于这个引擎来生成“答案”和“上下文”数据:
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()
vector_index = VectorStoreIndex.from_documents(documents)
query_engine = vector_index.as_query_engine(similarity_top_k=2)
- 从
data目录加载文档。 - 用
VectorStoreIndex创建文档向量索引。 - 将索引转为查询引擎,相似度阈值设为
2。
TruLens
TruLens 是一个专门用来评估和改进LLM应用的软件工具。
评估指标
TruLens 主要通过以下几个维度来考核RAG应用:
- 看答案有没有好好回应问题,是不是有用且相关。
答案相关性:
- 看检索到的上下文跟问题是否相关,有没有给答案提供足够的依据。
上下文相关性:
- 检查答案是不是严格基于上下文里的事实来生成的。
基于事实:
- 把答案跟人工标记的正确答案做对比,检验准确性。
基准真相:
使用示例
下面这段代码展示了如何用 TruLens 来做RAG评估:
import numpy as np
from trulens_eval import Tru, Feedback, TruLlama
from trulens_eval.feedback.provider.openai import OpenAI
from trulens_eval.feedback import Groundedness, GroundTruthAgreement
openai = OpenAI()
golden_set = [{"query": q, "response": r} for q, r in zip(questions, ground_truth)]
ground_truth = Feedback(
GroundTruthAgreement(golden_set).agreement_measure, name="Ground Truth"
).on_input_output()
grounded = Groundedness(groundedness_provider=openai)
groundedness = (
Feedback(grounded.groundedness_measure_with_cot_reasons, name="Groundedness")
.on(TruLlama.select_source_nodes().node.text)
.on_output()
.aggregate(grounded.grounded_statements_aggregator)
)
qa_relevance = Feedback(
openai.relevance_with_cot_reasons, name="Answer Relevance"
).on_input_output()
qs_relevance = (
Feedback(openai.qs_relevance_with_cot_reasons, name="Context Relevance")
.on_input()
.on(TruLlama.select_source_nodes().node.text)
.aggregate(np.mean)
)
tru_query_engine_recorder = TruLlama(
query_engine,
app_id="A vengers_App",
feedbacks=[
ground_truth,
groundedness,
qa_relevance,
qs_relevance,
],
)
with tru_query_engine_recorder as recording:
for question in questions:
query_engine.query(question)
tru = Tru()
tru.run_dashboard()
这段代码里定义了“基准真相”、“基于事实”、“答案相关性”和“上下文相关性”这几个反馈指标,然后用 TruLlama 记录查询引擎的运行结果,最后通过 Tru 启动评估并展示结果。
评估结果
TruLens 的评估结果可以通过浏览器访问本地服务来查看。除了总得分,还能看到每个指标的详细得分以及背后的推理。下面是 TruLens 评估结果的示例截图:

Ragas
Ragas 是另一个用来评估RAG应用的框架。跟 TruLens 相比,Ragas 的指标粒度更细。
评估指标
Ragas 考核的维度包括:
- 评估“问题”和“上下文”之间是否一致。
忠实度:
- 评估“答案”和“问题”之间是否相关。
答案相关性:
- 检查“标准答案”在“上下文”中的排名是否靠前。
上下文精度:
- 评估“标准答案”和“上下文”的一致性。
上下文召回:
- 看“标准答案”里的实体在“上下文”中是否被覆盖。
上下文实体召回:
- 评估“问题”和“上下文”之间的匹配度。
上下文相关性:
- 看“答案”和“标准答案”在语义上有多接近。
答案语义相似性:
- 直接评估“答案”相对“标准答案”是否正确。
答案正确性:
- 包括对其他方面的额外评估,比如有害性、正确性等。
方面评论:
使用示例
Ragas 官方文档里虽然有跟 LlamaIndex 集成的示例,但代码已经过时了。下面是一个更新后的版本:
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_relevancy,
answer_correctness,
)
from ragas import evaluate
from datasets import Dataset
metrics = [
faithfulness,
answer_relevancy,
context_relevancy,
answer_correctness,
]
answers = []
contexts = []
for q in questions:
response = query_engine.query(q)
answers.append(response.response)
contexts.append([sn.get_content() for sn in response.source_nodes])
data = {
"question": questions,
"contexts": contexts,
"answer": answers,
"ground_truth": ground_truth,
}
dataset = Dataset.from_dict(data)
result = evaluate(dataset, metrics)
result.to_pandas().to_csv("output/ragas-evaluate.csv", sep=",")
这个例子中:
- 输入数据是
questions和ground_truth。 - 用到的指标和 TruLens 类似。
- 手动构建了数据集,把问题、答案和上下文都填了进去。
- 评估结果保存到了本地文件中。
评估结果
Ragas 的结果可以在本地文件里查看,每个评估指标都有对应的分数。下面是示例:

Ragas 和 TruLens 的评估结果差异挺大,特别是在“上下文相关性”这个指标上,Ragas 的分数明显偏低。事实上,评估上下文时,Ragas 更推荐把“上下文精度”和“上下文召回”作为主要指标。为了方便比较,我们这里才用了“上下文相关性”。另一个值得注意的点是:Ragas 的结果只给分数,不给任何得分理由。
DeepEval
DeepEval 是一个开源的LLM评估框架,最大的特点是能把评估任务当成单元测试来跑。
评估指标
DeepEval 的指标覆盖面很广,有些是为RAG应用量身定做的,有些则适用于其他LLM场景:
- 看问题和上下文的一致性。
忠实度:
- 看答案和问题的一致性。
答案相关性:
- 检查标准答案在上下文中的排名。
上下文精确性:
- 评估标准答案和上下文的一致性。
上下文召回:
- 评估问题和上下文的一致性。
上下文相关性:
- 衡量胡说八道的程度。
幻觉:
- 评估是否存在偏见。
偏见:
- 检测是否包含人身攻击、讽刺或威胁等内容。
毒性:
- 允许借用 Ragas 的指标进行评估并生成解释。
Ragas:
- 评估信息被记住的持久性。
知识保留:
- 评估摘要是否有效。
摘要:
- 一个通过大模型和思维链(CoT)执行评估任务的框架。可以根据任何自定义标准评估LLM输出。
G-Eval:
使用示例
DeepEval 的一大特色就是把评估当单元测试跑。下面是一个简单的例子:
import pytest
from deepeval.metrics import (
AnswerRelevancyMetric,
FaithfulnessMetric,
ContextualRelevancyMetric,
)
from deepeval.test_case import LLMTestCase
from deepeval import assert_test
from deepeval.dataset import EvaluationDataset
def generate_dataset():
test_cases = []
for i in range(len(questions)):
response = query_engine.query(questions[i])
test_case = LLMTestCase(
input=questions[i],
actual_output=response.response,
retrieval_context=[node.get_content() for node in response.source_nodes],
expected_output=ground_truth[i],
)
test_cases.append(test_case)
return EvaluationDataset(test_cases=test_cases)
dataset = generate_dataset()
@pytest.mark.parametrize(
"test_case",
dataset,
)
def test_rag(test_case: LLMTestCase):
answer_relevancy_metric = AnswerRelevancyMetric(model="gpt-3.5-turbo")
faithfulness_metric = FaithfulnessMetric(model="gpt-3.5-turbo")
context_relevancy_metric = ContextualRelevancyMetric(model="gpt-3.5-turbo")
assert_test(
test_case,
[answer_relevancy_metric, faithfulness_metric, context_relevancy_metric],
)
这段代码构建了一个包含问题、生成答案、上下文和标准答案的测试集,然后用“忠实度”、“答案相关性”和“上下文相关性”这些指标来考核。DeepEval 默认使用 gpt-4,但为了省钱,也可以指定其他模型,比如 gpt-3.5-turbo。每个指标的阈值默认设为 0.5,也就是说分数低于 0.5 就算测试失败。
执行测试只需要运行 deepeval test run test_deepeval.py,DeepEval 会在终端输出结果:通过会显示 PASSED,不通过则显示 FAILED。
评估结果
终端结果看着不太方便,但 DeepEval 提供了另一个途径:设置环境变量 export DEEPEVAL_RESULTS_FOLDER="./output",结果就会被保存到本地的 JSON 文件中。
如果想更直观地查看,还可以用 Confident 平台。先通过 deepeval login --confident-api-key your_api_key 登录,然后运行测试。结果会自动上传到 Confident,展示更友好。下面是 Confident 上的评估结果截图:

Confident 还支持把结果导出为 CSV 文件,方便本地查看。
UpTrain
UpTrain 也是一个开源的LLM评估和改进平台,在我们讨论的这几个工具中,它的评估指标范围最广。
评估指标
UpTrain 的指标不仅针对RAG应用,也覆盖其他LLM场景。部分指标如下:
- 看答案和标准答案的一致性。
响应匹配:
- 衡量答案是否覆盖了问题的所有方面。
响应完整性:
- 检查答案有没有多余的废话。
响应简洁性:
- 评估答案和问题之间的关联度。
响应相关性:
- 看答案是否有效,有没有给出类似“我不知道”的无用回复。
响应有效性:
- 评估答案、问题和上下文三者之间是否一致。
响应一致性:
- 衡量上下文和问题之间的相关性。
上下文相关性:
- 看答案有没有充分利用上下文来覆盖所有要点。
上下文利用:
- 检查答案是否基于上下文、事实准确。
事实准确性:
- 衡量上下文是否精炼,有没有无关信息。
上下文简洁性:
- 评估排序后上下文的有效性。
上下文重新排序:
- 判断问题是否包含越狱提示。
越狱检测:
- 看问题是否试图泄露系统提示。
提示注入:
- 评估答案是否简洁、连贯、没有语法错误。
语言特征:
- 检查答案是否符合特定的语气要求。
语调:
- 看子问题是否覆盖了问题的全部方面。
子查询完整性:
- 看问题的不同变体是否与原始问题保持一致。
多查询准确性:
- 评估答案中的代码是否跟上下文相关。
代码幻觉:
- 评估对话中用户的满意程度。
用户满意度:
使用示例
UpTrain 和 LlamaIndex 的集成很方便,通过 EvalLlamaIndex 就能创建评估对象。拿个例子来说:
import os
import json
from uptrain import EvalLlamaIndex, Evals, ResponseMatching, Settings
settings = Settings(
openai_api_key=os.getenv("OPENAI_API_KEY"),
)
data = []
for i in range(len(questions)):
data.append(
{
"question": questions[i],
"ground_truth": ground_truth[i],
}
)
llamaindex_object = EvalLlamaIndex(settings=settings, query_engine=query_engine)
results = llamaindex_object.evaluate(
data=data,
checks=[
ResponseMatching(),
Evals.CONTEXT_RELEVANCE,
Evals.FACTUAL_ACCURACY,
Evals.RESPONSE_RELEVANCE,
],
)
with open("output/uptrain-evaluate.json", "w") as json_file:
json.dump(results, json_file, indent=2)
这里注意几个点:
- UpTrain 需要 OpenAI 的 API 密钥。
- 初始数据集只要“问题”和“标准答案”即可,答案和上下文由
EvalLlamaIndex自动生成。 - 用到了几个常见的评估指标。
- 结果保存到了 JSON 文件中。
评估结果
评估结果存储在 JSON 文件里。为了方便比较,可以转成 CSV 格式。下面是 UpTrain 的结果示例:

有个现象值得注意:运行“响应匹配”后,可能会得到 score_response_match、score_response_match_recall 和 score_response_match_precision 三个分数。即便答案和标准答案看起来差不多,这些分数也可能为 0。目前原因还不清楚,如果你知道,欢迎探讨。
比较分析
| 维度 | TruLens | Ragas | DeepEval | UpTrain |
|---|---|---|---|---|
| 评估指标数量 | 较少 | 适中 | 广泛 | 最广泛 |
| 自定义评估 | 不支持 | 不支持 | 支持 | 支持 |
| 自定义LLMs | 支持 | 通过LangChain | 支持 | 支持 |
| 框架集成 | LlamaIndex, LangChain | LlamaIndex, LangChain | LlamaIndex | LlamaIndex |
| WebUI | 支持 | 不支持 | 支持(Confident) | 支持 |
| 分数解释 | 提供 | 不提供 | 提供(可辅助Ragas) | 提供 |
| 单元测试 | 不支持 | 不支持 | 支持 | 不支持 |
从表格能看出,
TruLens 和 Ragas 属于先行者
DeepEval 和 UpTrain 属于后来者
结论
这篇文章聊了几个能与 LlamaIndex 集成的RAG评估工具,并做了横向对比。它们能帮开发人员看清自己 RAG 应用的底牌,从而找到优化的方向。当然,文中没提到的工具还有不少,比如 LlamaIndex 自带的评估和 Tonic Validate。如果你还在纠结选哪个,建议先挑一个项目直接上手试。不顺手?换一个就是了。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名