免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


做好 RAG 落地最后环节 —— 评估 RAG 应用

发布日期:2025-09-11 08:17:56 浏览次数: 1569
作者:AI悠悠

微信搜一搜,关注“AI悠悠”

推荐语

RAG应用落地难在评估?这份指南帮你建立科学的评估体系,确保应用稳定可控。

核心内容:
1. RAG应用评估的必要性与四大挑战
2. 评估依据与关键指标解析
3. 评估流程设计与实施方法

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

一、为什么RAG应用需要评估

随着大模型技术的发展,我们已经具备了开发完整 RAG(Retrieval-Augmented Generation,检索增强生成)应用的技术能力。借助 LlamaIndex、LangChain 等成熟框架,可以在较短时间内实现从原型到应用的快速构建。然而,真正将 RAG 应用推向生产环境,远不只是“搭建起来”那么简单,仍有许多问题值得提前思考与应对。

  • 1. 大模型输出的不确定性
    大模型的回答往往带有不确定性,这种特性会造成结果的不可预知性。如果缺乏充分测试,上线后可能引发严重的应用风险。因此,在部署之前,必须通过科学的方法对系统进行全面评估,尽可能量化和控制这种不确定性。


  • 2. 持续评估与改进机制
    应用上线只是起点。在后续的迭代中,需要建立科学、快速且可复用的评估机制,用于衡量改进是否真正带来价值。例如,某次优化后,回答的置信度是上升了 10%,还是下降了 5%?只有通过系统化的度量,才能避免“盲目调优”。


  • 3. 知识库的动态变化
    RAG 应用依赖的知识库并非一成不变。在持续更新与维护过程中,可能会引入新的噪声甚至错误信息。为了确保应用长期稳定运行,定期检测与重新评估知识库的质量就显得尤为重要。


  • 4. 底层模型的选择与升级
    RAG 应用高度依赖底层大模型。面对市面上众多商业与开源模型,企业需要明确如何选择最适合自身需求的版本。同时,模型升级是否会带来性能提升,还是引入新的不确定性,也是必须提前纳入评估体系的关键问题。


RAG 应用的快速开发并非难事,真正的挑战在于如何在生产环境中保持其稳定性、可控性和持续改进的能力。唯有建立起科学的评估与运维体系,才能让 RAG 应用真正发挥价值。

二、RAG应用的评估依据与指标

基于大模型的 RAG 应用与传统应用存在显著差异:传统应用的输出多具备确定性与可量化性,例如直接输出明确数值,评估标准清晰且易于衡量;而 RAG 应用以自然语言作为输入与输出载体,其结果通常表现为一段文本内容 —— 这类输出的相关性、准确性等核心指标,难以通过简单的定量方式直接判断,往往需要依托更智能的评估工具与专业模型完成综合评估。

RAG 应用的评估依据,即评估模块的输入一般包括以下要素。

  1. 输入问题(question):用户在使用 RAG 应用时的输入问题。

  2. 生成的答案(answer):需要评估的 RAG 应用的输出,即问题的答案。

  3. 上下文(context):用于增强 RAG 应用输出的参考上下文,通常在检索阶段生成。

  4. 参考答案(reference_answer):输入问题的真实的正确答案,通常需要人类标注。

基于这些评估依据,对 RAG 应用进行评估的常见指标见表1 。

三、RAG应用的评估流程与方法

  1. 确定评估的目的、维度与指标。

  2. 准备评估数据集,可以自行准备与标注,也可以使用大模型生成。根

  3. 据 评 估 指 标 , 你 可 能 需 要 准 备 不 同 的 输 入 问 题 ( question ) 与 参 考 答 案(reference_answer)。

  4. 将评估数据集输入 RAG 应用,获得检索结果(即上下文,context)与生成的答案(answer)。

  5. 将评估依据输入评估器,计算各类评估指标,分析 RAG 应用的整体性能。

  6. 对 RAG 应用的组件级评估通常侧重于检索与生成两个最关键的阶段。通过对这两个阶段单独评估,可以更细致地观察与分析问题,从而有针对性地优化与增强 RAG 应用。


四、评估检索质量

利用检索评估组件 RetrieverEvaluator 可以对任何检索模块进行质量评估。

该评估的主要指标如下。

  • 命中率(hit_rate):表示检索出的上下文对期望的上下文的命中率。

  • 平均倒数排名(mrr):衡量检索出的上下文的排名质量。

  • cohere 重排相关性(cohere-rerank-relevancy):用 Cohere Rerank 模型的排名结果衡量检索的排名质量。

评估检索质量的主要依据为输入问题与期望的上下文(检索出的 Node)。

1、生成检索评估数据集

评估检索过程有两种方式:用 evaluate 方法评估单次查询,或用 evaluate_dataset 方法批量评估构造好的检索评估数据集。由于评估的是检索上下文与问题的相关性,需要问题与参考上下文的数据对,因此首先需用 generate_question_context_pairs 方法借助大模型从已有数据生成检索评估数据集(也可自行构造)。
# 读取文档,构造 Node,用于生成检索评估数据集from pathlib import Pathfrom llama_index.core import SimpleDirectoryReader, VectorStoreIndexfrom llama_index.core.node_parser import SentenceSplitterfrom llama_index.core.evaluation import (    generate_question_context_pairs,    EmbeddingQAFinetuneDataset,)
# 加载大模型的代码,请勿删除 startfrom common.llm_model_helper import llm_settings# 加载大模型的代码,请勿删除 end
documents = SimpleDirectoryReader( input_files=[r"D:\muxue\common_docs\jianlai.txt"]).load_data()
node_parser = SentenceSplitter(chunk_size=1024)nodes = node_parser.get_nodes_from_documents(documents)

for idx, node in enumerate(nodes):    node.id_ = f"node_{idx}"
# 准备一个检索器,后面使用# vector_index = VectorStoreIndex(nodes)# retriever = vector_index.as_retriever(similarity_top_k=2)QA_GENERATE_PROMPT_TMPL = """ 以下是上下文: --------------------- {context_str} --------------------- 你是一位专业教授。你的任务是基于以上的上下文,为即将到来的考试设置{num_questions_per_chunk} 个问题。这些问题必须基于提供的上下文生成,并确保上下文能够回答这些问题。确保每一行都只有一个独立的问题。不要有多余解释。不要给问题编号。"""print("Generating question-context pairs...")qa_dataset = generate_question_context_pairs(    nodes,    # llm=llm_Ollama,    num_questions_per_chunk=1,    qa_generate_prompt_tmpl=QA_GENERATE_PROMPT_TMPL)print("Saving dataset...")qa_dataset.save_json("retriever_eval_dataset.json")

在这段代码中,手工设置了中文的 Prompt,一方面有助于了解生成原理与调试生成结果,另一方面用于生成中文问题。最后,把生成的检索评估数据集保存到本地的 JSON 文档中,以减少不必要的重复生成,后面只需要从本地文档中加载即可。

2、运行评估检索过程的程序

我们已经构造了一个检索器,并且借助大模型生成了检索评估数据集。下面构造与运行检索评估器。基本的流程如下。

  • 加载检索评估数据集。

  • 构造检索评估器( RetrieverEvaluator 对象),设置评估指标。

  • 调用 evaluate 方法,查看评估结果。

# 读取文档,构造 Node,用于生成检索评估数据集

# 读取文档,构造 Node,用于生成检索评估数据集from pathlib import Pathfrom llama_index.core import SimpleDirectoryReader, VectorStoreIndexfrom llama_index.core.node_parser import SentenceSplitterfrom llama_index.core.evaluation import (    generate_question_context_pairs,    EmbeddingQAFinetuneDataset,)from llama_index.core.evaluation import RetrieverEvaluatorfrom evaluation_comm import get_retriever

print("Loading dataset...")# 从保存的 JSON 文档中加载检索评估数据集qa_dataset = EmbeddingQAFinetuneDataset.from_json("retriever_eval_dataset.json")eval_querys = list(qa_dataset.queries.items())

# 构造一个检索评估器,设定两个评估指标metrics = ["mrr""hit_rate"]retriever_evaluator = RetrieverEvaluator.from_metric_names(metrics, retriever=get_retriever())# 简单评估前 10 个评估用例for eval_id, eval_query in eval_querys[:10]:    expect_docs = qa_dataset.relevant_docs[eval_id]    print(f"Query: {eval_query}, Expected docs: {expect_docs}")    # 评估,输入评估问题与预期检索出的 Node    eval_result = retriever_evaluator.evaluate(query=eval_query, expected_ids=expect_docs)    print(eval_result)
# 对整个评估数据集进行评估# eval_results = retriever_evaluator.evaluate_dataset(qa_dataset)

从打印的结果中可以看到评估指标,你可以对这些评估指标进行汇总计算,得出检索评估器的质量评估结果。如果需要对整个检索评估数据集直接进行评估,那么可以使用更简单的方式:

eval_results = retriever_evaluator.evaluate_dataset(qa_dataset)

直接在检索评估数据集上调用 evaluate_dataset 方法,其效果与逐个循环调用 evaluate 方法的效果是一致的。

五、评估响应质量

响应质量是 RAG 应用评估的重点,关乎端到端客户体验。可评估单个指标、单次响应,也可基于批量数据集自动运行多个响应评估器以获取整体结果。

1、 生成响应评估数据集

和评估检索过程类似,仍可借助大模型生成响应评估数据集(也可按格式自行标注)。它与检索评估数据集不同,因评估响应质量除需问题和检索上下文外,还需大模型生成的答案甚至参考答案。用 generate_dataset_from_nodes 方法能让大模型批量生成响应评估数据集。
from pathlib import Pathfrom llama_index.core import SimpleDirectoryReader, VectorStoreIndexfrom llama_index.core.llama_dataset.generator import RagDatasetGeneratorfrom llama_index.core.llama_dataset import LabelledRagDataset
# 加载大模型的代码from common.llm_model_helper import llm_settings

# build documentsdocs = SimpleDirectoryReader(input_files=[r'D:\muxue\common_docs\jianlai.txt']).load_data()

# define generator, generate questionsdataset_generator = RagDatasetGenerator.from_documents(    documents=docs,    #llm=llm_ollama,    num_questions_per_chunk=1,  # 设置每个 Node 都生成的问题数量    show_progress=True,    question_gen_query="您是一位老师。您的任务是为即将到来的考试设置{num_questions_per_chunk}个问题。这些问题必须基于提供的上下文生成,并确保上下文能够回答这些问题。确保每一行都只有一个独立的问题。不要有多余解释。不要给问题编号。")
# 以下代码只需要运行一次save_json_name='rag_eval_dataset_jianlai.json'print('Generating questions from nodes...\n')rag_dataset = dataset_generator.generate_dataset_from_nodes()rag_dataset.save_json(save_json_name)# 从本地文档中加载并查看print('Loading dataset...\n')rag_dataset = LabelledRagDataset.from_json(save_json_name)for example in rag_dataset.examples:    print(f'query: {example.query}')    print(f'answer: {example.reference_answer}')

在运行代码后,你可以在当前目录中看到一个 rag_eval_dataset_jianlai.json 数据集文档,打开该文档,可以看到生成的每个评估用例的数据格式。其中:

  • query:生成的问题。

  • reference_contexts:检索出的参考上下文。

  • reference_answers:参考答案。

这些内容都可能被输入到后面的响应评估器中,作为评估响应质量的输入依据,如下所示。

2、单次响应评估

要想对 RAG 应用的某一次查询的响应过程进行不同维度的评估,那么只需要构造对应的评估器组件(Evaluator),然后输入必需的数据,即可获得评估结果。单次响应评估的输入参数有以下几个。

  • query:输入问题。

  • response:RAG 应用的响应结果。如果使用 evaluate_response 方法评估,那么可以直接输入 response;如果使用 evaluate 方法评估,那么需要从response 中提取上下文与文本内容,将其分别作为参数输入。

  • reference:参考答案。它在正确性与相似度评估中会用到,对应响应评估数据集中的 reference_answer 字段。

 

from llama_index.core import (    VectorStoreIndex,    SimpleDirectoryReader,    Response,)from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.evaluation import (FaithfulnessEvaluator,RelevancyEvaluator,ContextRelevancyEvaluator,AnswerRelevancyEvaluator,CorrectnessEvaluator,SemanticSimilarityEvaluator)
# 加载大模型的代码,请勿删除 startfrom common.llm_model_helper import llm_settings# 加载大模型的代码,请勿删除 end
# ......这里省略构造查询引擎的过程......documents = SimpleDirectoryReader(input_files=[r"D:\muxue\common_docs\jianlai.txt"]).load_data()# create vector indexsplitter = SentenceSplitter(chunk_size=512)vector_index = VectorStoreIndex.from_documents(    documents, transformations=[splitter])query_engine = vector_index.as_query_engine()
# 两个重要的输入参数query = "陈平安对中年光棍的尖酸刻薄言语有何反应?"response = query_engine.query(query)# 评估忠实度的评估器evaluator = FaithfulnessEvaluator()eval_result = evaluator.evaluate_response(query=query,                                          response=response)print(f'faithfulness score: {eval_result.score}\n')# 评估相关性的评估器(综合了上下文相关性与答案相关性)evaluator = RelevancyEvaluator()eval_result =evaluator.evaluate_response(query=query, response=response)print(f'relevancy score: {eval_result.score}\n')# 评估上下文相关性的评估器evaluator = ContextRelevancyEvaluator()eval_result =evaluator.evaluate_response(query=query, response=response)
print(f'context relevancy score: {eval_result.score}\n')# 评估答案相关性的评估器evaluator = AnswerRelevancyEvaluator()eval_result =evaluator.evaluate_response(query=query, response=response)print(f'answer relevancy score: {eval_result.score}\n')# 评估正确性的评估器,注意输入了 referenceevaluator = CorrectnessEvaluator()eval_result =evaluator.evaluate_response(query=query, response=response,                            reference='根据提供的上下文信息,陈平安对中年光棍的尖酸刻薄言语反应如下:他翻了个白眼,但并不以为意。原因有二:一是他生活在这座乡野地方,早已习惯此类言语,认为若因此恼火反而显得可笑;二是这中年光棍本身也是小镇百姓经常取笑的对象,陈平安对此人并无太多计较。')print(f'correctness score: {eval_result.score}\n')# 评估答案与标准答案的语义相似度(基于 embedding)的评估器,注意输入了 referenceevaluator = SemanticSimilarityEvaluator()eval_result =evaluator.evaluate_response(query=query, response=response,                            reference='陈平安翻了个白眼,但并不以为意,对此人并无太多计较。')print(f'semantic similarity score: {eval_result.score}\n')

评估过程非常简单,各个评估指标可参考表 1中的说明。必须再次强调,有的评估器需要输入参考答案(正确性与语义相似度),否则会出现异常。在正常运行评估代码后,可以看到输出的评估结果,如下图所示。

3、批量响应评估

你可以借助批量评估器,在评估数据集的基础上并行运行多个响应评估器,并通过计算与统计获得综合的性能评估结果。以 (五-1)节生成的响应评估数据集为基础,对构造的查询引擎进行综合评估:

from llama_index.core import (    VectorStoreIndex,    SimpleDirectoryReader,    Response,)from llama_index.core.node_parser import SentenceSplitterfrom llama_index.core.llama_dataset import LabelledRagDatasetfrom llama_index.core.evaluation import (FaithfulnessEvaluator, RelevancyEvaluator, ContextRelevancyEvaluator, AnswerRelevancyEvaluator, CorrectnessEvaluator, SemanticSimilarityEvaluator)from llama_index.core.evaluation import BatchEvalRunnerimport asyncio# 打印评估结果import pandas as pd# 加载大模型的代码,请勿删除 startfrom common.llm_model_helper import llm_settings# 加载大模型的代码,请勿删除 end
# ......这里造查询引擎......documents = SimpleDirectoryReader(input_files=[r"D:\muxue\common_docs\jianlai.txt"]).load_data()# create vector indexsplitter = SentenceSplitter(chunk_size=512)vector_index = VectorStoreIndex.from_documents(    documents, transformations=[splitter])query_engine = vector_index.as_query_engine()
# 构造多个响应评估器faithfulness_evaluator = FaithfulnessEvaluator()relevancy_evaluator = RelevancyEvaluator()correctness_evaluator = CorrectnessEvaluator()similartiy_evaluator = SemanticSimilarityEvaluator()
# 加载数据集rag_dataset = LabelledRagDataset.from_json('rag_eval_dataset_jianlai.json')
# 构造一个批量评估器runner = BatchEvalRunner(    {"faithfulness": faithfulness_evaluator,     "relevancy": relevancy_evaluator,     "correctness": correctness_evaluator,     "similarity": similartiy_evaluator},    workers=4)

async def evaluate_queries():    """    为了提高性能,采用异步并行的评估方法,调用批量评估器    输入:查询引擎、批量的 query,批量的 reference    这里对响应评估数据集中的前十个评估用例进行评估    """    eval_results = await runner.aevaluate_queries(        query_engine,        queries=[example.query for example in rag_dataset.examples][:10],        reference=[example.reference_answer for example in rag_dataset.examples][:10],    )    return eval_results

eval_results = asyncio.run(evaluate_queries())
def display_results(eval_results):    data = {}
    for key, results in eval_results.items():        scores = [result.score for result in results]        scores.append(sum(scores) / len(scores))        data[key] = scores
    data["query"] = [result.query for result in eval_results["faithfulness"]]    data["query"].append("【Average】")    df = pd.DataFrame(data)    print(df)
display_results(eval_results)

借助 BatchEvalRunner 组件,在调用 aevaluate_queries 方法进行批量评估时可以设置 workers 参数并行运行,从而缩短评估的时间。最后,我们把评估结果用表格的形式展示,以便更直观地观察(也可以输出 Excel 文档),输出结果如图所示。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询