4.5RAG应用的评估


文档摘要

4.5 RAG应用的评估 4.5.1 如何评估一个RAG应用 RAG(检索增强生成)是一种结合了信息检索和自然语言生成的技术,广泛应用于知识问答、客户服务等领域。要实现高质量的RAG应用,必须对其进行全面的评估和优化。本文将从以下几个方面展开介绍:如何评估RAG应用,如何评估及优化检索模块,以及如何评估及优化生成模块。 评估RAG应用需要综合考虑: 检索性能:检索的准确率和召回率 检索模块决定了从知识库中找到的文档质量,是RAG应用的基础。主要评估指标包括: 准确率(Precision):检索结果中相关文档的比例。 召回率(Recall):所有相关文档中被检索出的比例。 F1值:准确率和召回率的调和平均值。 生成质量:回答的准确性、流畅度和相关性 准确性:回答是否正确。

4.5 RAG应用的评估

4.5.1 如何评估一个RAG应用

RAG(检索增强生成)是一种结合了信息检索和自然语言生成的技术,广泛应用于知识问答、客户服务等领域。要实现高质量的RAG应用,必须对其进行全面的评估和优化。本文将从以下几个方面展开介绍:如何评估RAG应用,如何评估及优化检索模块,以及如何评估及优化生成模块。

评估RAG应用需要综合考虑:

  • 检索性能:检索的准确率和召回率

检索模块决定了从知识库中找到的文档质量,是RAG应用的基础。主要评估指标包括:

  • 准确率(Precision):检索结果中相关文档的比例。

  • 召回率(Recall):所有相关文档中被检索出的比例。

  • F1值:准确率和召回率的调和平均值。

  • 生成质量:回答的准确性、流畅度和相关性

  • 准确性:回答是否正确。

  • 流畅性:语言是否自然。

  • 相关性:回答是否与问题紧密相关。

  • 用户体验:响应速度、交互友好性

用户体验评估主要关注应用的交互友好性,包括:

  • 响应速度:回答的生成时间。

  • 交互性:系统界面和交互设计是否直观。

  • 稳定性:系统是否可靠,无明显错误。

4.5.2 评估及优化检索模块

评估检索模块的方法

  • 指标评估:使用准确率、召回率、F1值等指标

评估检索模块时,常用以下指标:

  • 准确率:衡量检索结果的相关性。

  • 召回率:衡量检索结果的覆盖范围。

  • F1值:综合考虑准确率和召回率。

评估检索模块

from camel.embeddings import SentenceTransformerEncoder from camel.retrievers import VectorRetriever from camel.storages.vectordb_storages import QdrantStorage from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity from nltk.tokenize import word_tokenize import numpy as np # 初始化嵌入模型 embedding_model = SentenceTransformerEncoder(model_name='intfloat/e5-large-v2') # 初始化向量存储 vector_storage = QdrantStorage( vector_dim=embedding_model.get_output_dim(), collection="test_collection", path="test_storage", collection_name="CAMEL AI 文档" ) # 初始化检索器 vr = VectorRetriever(embedding_model=embedding_model, storage=vector_storage) # 处理文档并构建向量数据库 vr.process( content="example_document.md", )

这里可以使用我们用LLM生成的一个示例md文档作为我们要检索的文档,使用本地的embedding模型和向量检索器。

example_document.md

在这里我们设置一些问题和我们预期的标准答案。

test_queries = [ { "query": "什么是CAMEL AI?", "expected_answers": ["CAMEL AI 是一个开源的、社区驱动的AI框架。"] }, { "query": "如何开始使用CAMEL AI?", "expected_answers": ["首先安装框架:`pip install camel-ai`,然后引入必要的模块。"] }, { "query": "CAMEL AI 的主要特点是什么?", "expected_answers": ["模块化设计、易用性和扩展性。"] } ]

之后,我们定义我们的评估指标,我们计算检索出的结果和我们预期结果之间的余弦相似度,并且认为超过一定范围时检索的结果是符合预期的。

# 定义评估指标 def calculate_precision(retrieved, relevant, threshold=0.5): """计算精确率(Precision),当相似度超过阈值时认为是正确的""" correct = 0 for r in retrieved: for rel in relevant: similarity = compute_similarity(rel, r) if similarity >= threshold: correct += 1 break return correct / len(retrieved) if retrieved else 0 def calculate_recall(retrieved, relevant, threshold=0.5): """计算召回率(Recall),当相似度超过阈值时认为是正确的""" correct = 0 for rel in relevant: for r in retrieved: similarity = compute_similarity(rel, r) if similarity >= threshold: correct += 1 break return correct / len(relevant) if relevant else 0 def calculate_f1(precision, recall): """计算F1值""" return 2 * (precision * recall) / (precision + recall) if (precision + recall) else 0 def compute_similarity(expected, retrieved): """计算预期答案与检索结果的相似度""" vectorizer = TfidfVectorizer() tfidf = vectorizer.fit_transform([expected, retrieved]) similarity_matrix = cosine_similarity(tfidf, tfidf) return similarity_matrix[0, 1] def evaluate_retrieval(query, expected_answers, threshold=0.5, top_k=1): """评估单个查询的检索质量""" results = vr.query(query=query, top_k=top_k) retrieved_texts = [result["text"] for result in results] # 计算精确率、召回率和F1值 precision = calculate_precision(retrieved_texts, expected_answers, threshold) recall = calculate_recall(retrieved_texts, expected_answers, threshold) f1 = calculate_f1(precision, recall) # 计算平均相似度 similarities = [] for expected, retrieved in zip(expected_answers, retrieved_texts): similarities.append(compute_similarity(expected, retrieved)) avg_similarity = np.mean(similarities) if similarities else 0 return { "precision": precision, "recall": recall, "f1": f1, "avg_similarity": avg_similarity, "retrieved_texts": retrieved_texts }

下面我们执行评估:

# 执行评估 evaluation_results = [] for test_case in test_queries: query = test_case["query"] expected_answers = test_case["expected_answers"] evaluation = evaluate_retrieval(query, expected_answers) evaluation_results.append({ "query": query, "expected_answers": expected_answers, "evaluation": evaluation }) # 打印详细结果 print(f"Query: {query}") print(f"Expected Answers: {expected_answers}") print(f"Retrieved Results: {evaluation['retrieved_texts']}") print(f"Precision: {evaluation['precision']:.4f}") print(f"Recall: {evaluation['recall']:.4f}") print(f"F1 Score: {evaluation['f1']:.4f}") print(f"Average Similarity: {evaluation['avg_similarity']:.4f}") print("-" * 100) # 计算整体评估结果 total_precision = sum(result["evaluation"]["precision"] for result in evaluation_results) / len(evaluation_results) total_recall = sum(result["evaluation"]["recall"] for result in evaluation_results) / len(evaluation_results) total_f1 = sum(result["evaluation"]["f1"] for result in evaluation_results) / len(evaluation_results) total_similarity = sum(result["evaluation"]["avg_similarity"] for result in evaluation_results) / len(evaluation_results) print("\n整体评估结果:") print(f"Average Precision: {total_precision:.4f}") print(f"Average Recall: {total_recall:.4f}") print(f"Average F1 Score: {total_f1:.4f}") print(f"Average Similarity: {total_similarity:.4f}") >>> Query: 什么是CAMEL AI? Expected Answers: ['CAMEL AI 是一个开源的、社区驱动的AI框架。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.5722 ---------------------------------------------------------------------------------------------------- Query: 如何开始使用CAMEL AI? Expected Answers: ['首先安装框架:`pip install camel-ai`,然后引入必要的模块。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 0.0000 Recall: 0.0000 F1 Score: 0.0000 Average Similarity: 0.4752 ---------------------------------------------------------------------------------------------------- Query: CAMEL AI 的主要特点是什么? Expected Answers: ['模块化设计、易用性和扩展性。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 0.0000 Recall: 0.0000 F1 Score: 0.0000 Average Similarity: 0.0502 ---------------------------------------------------------------------------------------------------- ... Average Precision: 0.3333 Average Recall: 0.3333 Average F1 Score: 0.3333 Average Similarity: 0.3659

通过以上的步骤,我们可以完成一个简单检索模块的评估。下面我们来看一下如何优化我们的检索模块。

首先我们会发现在上面第三条检索的结果其实是涵盖了我们的预期结果的,但是由于我们使用的是基于TF-IDF的余弦相似度。导致了其得分较低。

首先,我们简单介绍一下TF-IDF的基本原理和它在相似度计算中的应用。TF-IDF(词频-逆向文件频率)是一种用于信息检索和文本挖掘的常用加权技术,用于评估一个词在文档中的重要程度。其核心思想是:如果某个词在一篇文档中出现的频率高,并且在其他文档中很少出现,则认为该词具有很好的类别区分能力。

这种方法在我们第三条结果出现的问题是:

忽略语义信息:TF-IDF基于词频统计,无法捕捉词语之间的语义关系。例如,“汽车”和“车辆”在语义上是相近的,但TF-IDF会将其视为完全不同的词。

而且预期的结果和检索到的结果字数差距较大,导致两条结果的在基于TF-IDF的余弦相似度下相差较大。这里我们可以尝试使用Embedding模型来将结果转成向量之后再计算余弦相似度。它的特点如下:

优点:精准捕捉语义和语境。
缺点:计算资源消耗大。

#我们将原有的compute_similarity函数替换一下 # def compute_similarity(expected, retrieved): # """计算预期答案与检索结果的相似度""" # vectorizer = TfidfVectorizer() # tfidf = vectorizer.fit_transform([expected, retrieved]) # similarity_matrix = cosine_similarity(tfidf, tfidf) # return similarity_matrix[0, 1] def compute_similarity(expected, retrieved): """计算预期答案与检索结果的相似度""" embeddings = embedding_model.embed_list([expected, retrieved]) return cosine_similarity([embeddings[0]], [embeddings[1]])[0][0]

然后再重新运行一下评估函数:

# 执行评估 evaluation_results = [] for test_case in test_queries: query = test_case["query"] expected_answers = test_case["expected_answers"] evaluation = evaluate_retrieval(query, expected_answers) evaluation_results.append({ "query": query, "expected_answers": expected_answers, "evaluation": evaluation }) # 打印详细结果 print(f"Query: {query}") print(f"Expected Answers: {expected_answers}") print(f"Retrieved Results: {evaluation['retrieved_texts']}") print(f"Precision: {evaluation['precision']:.4f}") print(f"Recall: {evaluation['recall']:.4f}") print(f"F1 Score: {evaluation['f1']:.4f}") print(f"Average Similarity: {evaluation['avg_similarity']:.4f}") print("-" * 100) # 计算整体评估结果 total_precision = sum(result["evaluation"]["precision"] for result in evaluation_results) / len(evaluation_results) total_recall = sum(result["evaluation"]["recall"] for result in evaluation_results) / len(evaluation_results) total_f1 = sum(result["evaluation"]["f1"] for result in evaluation_results) / len(evaluation_results) total_similarity = sum(result["evaluation"]["avg_similarity"] for result in evaluation_results) / len(evaluation_results) print("\n整体评估结果:") print(f"Average Precision: {total_precision:.4f}") print(f"Average Recall: {total_recall:.4f}") print(f"Average F1 Score: {total_f1:.4f}") print(f"Average Similarity: {total_similarity:.4f}") >>> Query: 什么是CAMEL AI? Expected Answers: ['CAMEL AI 是一个开源的、社区驱动的AI框架。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.9024 ---------------------------------------------------------------------------------------------------- Query: 如何开始使用CAMEL AI? Expected Answers: ['首先安装框架:`pip install camel-ai`,然后引入必要的模块。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.9148 ---------------------------------------------------------------------------------------------------- Query: CAMEL AI 的主要特点是什么? Expected Answers: ['模块化设计、易用性和扩展性。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。\n\n主要特点\n\n模块化设计:用户可以根据需求选择性地加载不同的功能模块。\n\n易用性:提供了简单易用的API接口,降低了开发门槛。\n\n拓展性:支持多种模型和后端服务,方便用户根据需求进行扩展。\n\n常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.8000 ---------------------------------------------------------------------------------------------------- ... Average Precision: 1.0000 Average Recall: 1.0000 Average F1 Score: 1.0000 Average Similarity: 0.8724

可以发现,这次评估的结果更加符合我们人类的标准。

另外我们可以发现,我们每次检索到的内容其实完全一样,这是因为VectorRetriever会默认将文档按照500字为间隔来划分,我们将这里我们可以调整一下chunk的大小,之后重新划分文档:

# 初始化向量存储 vector_storage = QdrantStorage( vector_dim=embedding_model.get_output_dim(), collection="test_collection", path="test_storage", collection_name="CAMEL AI 文档" ) # 初始化检索器 vr = VectorRetriever(embedding_model=embedding_model, storage=vector_storage) vr.process( content="example_document.md", max_characters=100, should_chunk=True, )

然后再次检索:

# 执行评估 evaluation_results = [] for test_case in test_queries: query = test_case["query"] expected_answers = test_case["expected_answers"] evaluation = evaluate_retrieval(query, expected_answers) evaluation_results.append({ "query": query, "expected_answers": expected_answers, "evaluation": evaluation }) # 打印详细结果 print(f"Query: {query}") print(f"Expected Answers: {expected_answers}") print(f"Retrieved Results: {evaluation['retrieved_texts']}") print(f"Precision: {evaluation['precision']:.4f}") print(f"Recall: {evaluation['recall']:.4f}") print(f"F1 Score: {evaluation['f1']:.4f}") print(f"Average Similarity: {evaluation['avg_similarity']:.4f}") print("-" * 100) # 计算整体评估结果 total_precision = sum(result["evaluation"]["precision"] for result in evaluation_results) / len(evaluation_results) total_recall = sum(result["evaluation"]["recall"] for result in evaluation_results) / len(evaluation_results) total_f1 = sum(result["evaluation"]["f1"] for result in evaluation_results) / len(evaluation_results) total_similarity = sum(result["evaluation"]["avg_similarity"] for result in evaluation_results) / len(evaluation_results) print("\n整体评估结果:") print(f"Average Precision: {total_precision:.4f}") print(f"Average Recall: {total_recall:.4f}") print(f"Average F1 Score: {total_f1:.4f}") print(f"Average Similarity: {total_similarity:.4f}") >>> Query: 什么是CAMEL AI? Expected Answers: ['CAMEL AI 是一个开源的、社区驱动的AI框架。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.9584 ---------------------------------------------------------------------------------------------------- Query: 如何开始使用CAMEL AI? Expected Answers: ['首先安装框架:`pip install camel-ai`,然后引入必要的模块。'] Retrieved Results: ['常见问题\n\n如何开始使用CAMEL AI?\n\n首先安装框架:pip install camel-ai\n\n引入必要的模块:from camel import *\n\n参考官方文档:CAMEL AI官方文档'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.9604 ---------------------------------------------------------------------------------------------------- Query: CAMEL AI 的主要特点是什么? Expected Answers: ['模块化设计、易用性和扩展性。'] Retrieved Results: ['CAMEL AI 介绍\n\nCAMEL AI 是一个开源的、社区驱动的AI框架,旨在简化AI应用的开发和部署。该框架提供了多种功能模块,包括数据加载、特征工程、模型训练和部署等。'] Precision: 1.0000 Recall: 1.0000 F1 Score: 1.0000 Average Similarity: 0.8103 ---------------------------------------------------------------------------------------------------- ... Average Precision: 1.0000 Average Recall: 1.0000 Average F1 Score: 1.0000 Average Similarity: 0.9097

可以发现效果又更近了一步。

更多的调整方向可以参考以下几点:

  • 参数调整:优化嵌入模型和检索算法的参数

优化嵌入模型和检索算法的参数,例如:

  • 调整嵌入向量的维度。

  • 优化检索的相似度计算方法(如欧几里得距离、余弦相似度)。

  • 在自身场景下微调嵌入模型通过效果是明显的

  • 数据增强:扩充知识库,提高覆盖面

通过扩充知识库提高覆盖面,例如:

  • 添加更多高质量的知识数据。

  • 利用数据增强技术生成多样化的知识表达。

  • 检索策略优化

  • 分阶段检索

  • 混合检索(如TF-IDF + 语义模型)

  • 实时反优化

4.5.3 评估及优化生成模块

优化生成模块的方法:

  • 质量评估:使用BLEU、ROUGE等自动指标和人工评估

生成模块的评估可以分为自动评估和人工评估:

  • 自动评估:使用BLEU、ROUGE等指标衡量生成文本的质量。

  • 人工评估:通过专家或用户打分,评估文本的准确性、流畅性和相关性。

  • 上下文增强:提供更丰富的上下文信息

  • 为生成模型提供更丰富的上下文信息,例如问题背景或用户历史记录。

代码示例:以下展示了如何评估生成模块的回答质量。

from rouge_score import rouge_scorer from nltk.translate.bleu_score import sentence_bleu from nltk.tokenize import word_tokenize # 示例数据 reference = "RAG combines retrieval and generation for QA." generated = "RAG integrates retrieval and generation for question answering." # 使用ROUGE评估 scorer = rouge_scorer.RougeScorer(['rouge1', 'rougeL'], use_stemmer=True) scores = scorer.score(reference, generated) # 使用BLEU评估 reference_tokens = word_tokenize(reference) generated_tokens = word_tokenize(generated) bleu_score = sentence_bleu([reference_tokens], generated_tokens) print(f"ROUGE-1: {scores['rouge1'].fmeasure:.2f}") print(f"ROUGE-L: {scores['rougeL'].fmeasure:.2f}") print(f"BLEU Score: {bleu_score:.2f}")

发布者: 作者: 转发
评论区 (0)
U