链载Ai

标题: 全网最全RAG评估指南:全面解析RAG评估指标并提供代码示例 [打印本页]

作者: 链载Ai    时间: 4 小时前
标题: 全网最全RAG评估指南:全面解析RAG评估指标并提供代码示例

一、RAG痛点介绍

最近我一直在关注和优化RAG(Retrieval-Augmented Generation)相关的内容,总结了一下RAG的痛点和最佳实践,然后重点会介绍如何评估RAG。

二、RAG痛点优化

认识了RAG的痛点,就知道如何进行优化了,下面是RAG最佳实践的总结。

首先,总结一下日常对RAG(Retrieval-Augmented Generation)的最佳实践中,通常会涉及以下关键问题和优化策略:

1. 数据如何处理的?

2. chunk-size如何设置的?

3. Embedding模型使用的什么?

4. Prompt如何设计?

5. 检索的topN如何设置?

6. LLM模型选择的什么?

7. RAG检索生成效果优化策略



通过不断地实验和优化,可以找到最适合特定应用场景的RAG配置,从而实现更好的检索和生成效果。

经过各种优化之后,对RAG来说,最重要的就是如何评估其效果。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.034em;">三、为什么需要对RAG系统评估?

评估是AI开发流程中的一个非常关键步骤,它被用于检查当前策略相对于其他策略的有效性,或在当你对流程进行更改时进行评估。因此在进行LLM项目的开发和改进时,必须要有衡量其表现的方法。


LlamaIndex中RAG处理过程(图片来源:https://docs.llamaindex.ai/en/stable/getting_started/concepts/):

为了评估RAG系统,我们通常使用两种类型的评估:

与传统的机器学习技术不同,传统技术有明确定量的度量指标(如Gini系数、R平方、AIC、BIC、混淆矩阵等),评估RAG系统更加复杂。这种复杂性的原因在于RAG系统生成的响应是非结构化文本,需要结合定性和定量指标来准确评估其性能。

为了有效评估RAG系统,我们通常遵循TRIAD框架。该框架由三个主要组成部分组成:

检索评估适用于RAG系统的检索器组件,该组件通常使用向量数据库。这些评估衡量检索器在响应用户查询时识别和排名相关文档的效果。检索评估的主要目标是评估上下文相关性,即检索到的文档与用户查询的匹配程度。它确保提供给生成组件的上下文是相关和准确的。

精确度

精确度衡量了检索到的文档的准确性。它是检索到的相关文档数量与检索到的文档总数之比。定义如下:

这意味着精确度评估了系统检索到的文档中有多少实际与用户查询相关。例如,如果检索器检索到了10个文档,其中7个是相关的,那么精确度将是0.7或70%。

def calculate_precision(retrieved_docs, relevant_docs):"""计算精确度
参数:retrieved_docs (list): 检索到的文档列表relevant_docs (list): 相关文档列表
返回:float: 精确度"""# 计算检索到的相关文档数量relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
# 计算精确度precision = len(relevant_retrieved_docs) / len(retrieved_docs) if retrieved_docs else 0return precision
# 示例数据retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']relevant_docs = ['doc2', 'doc4', 'doc6']
# 计算精确度precision = calculate_precision(retrieved_docs, relevant_docs)print(f"精确度: {precision:.2f}")

精确度评估的是“系统检索到的所有文档中,有多少实际上是相关的?”

在可能导致负面后果的情况下,精确度尤为重要。例如,在医学信息检索系统中,高精确度至关重要,因为提供不相关的医学文档可能导致错误信息和潜在的有害结果。

召回率

召回率衡量了检索到的文档的全面性。它是检索到的相关文档数量与数据库中相关文档的总数之比。定义如下:

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"/>

这意味着召回率评估了数据库中存在的相关文档有多少被系统成功检索到。

def calculate_recall(retrieved_docs, relevant_docs):"""计算召回率
参数:retrieved_docs (list): 检索到的文档列表relevant_docs (list): 相关文档列表
返回:float: 召回率"""# 计算检索到的相关文档数量relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
# 计算召回率recall = len(relevant_retrieved_docs) / len(relevant_docs) if relevant_docs else 0return recall
# 示例数据retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']relevant_docs = ['doc2', 'doc4', 'doc6', 'doc7']
# 计算召回率recall = calculate_recall(retrieved_docs, relevant_docs)print(f"召回率: {recall:.2f}")

召回率评估的是“数据库中存在的所有相关文档中,系统成功检索到了多少个?”

在可能错过相关信息会产生成本的情况下,召回率至关重要。例如,在法律信息检索系统中,高召回率至关重要,因为未能检索到相关的法律文件可能导致不完整的案例研究,并可能影响法律诉讼的结果。

精确度和召回率的平衡

通常需要平衡精确度和召回率,因为改善其中一个指标有时会降低另一个指标。目标是找到适合特定应用需求的最佳平衡。这种平衡有时可以用F1分数来量化,F1分数是精确度和召回率的调和平均值:

#

平均倒数排名(MRR)

平均倒数排名(MRR)是一种评估检索系统效果的度量指标,它考虑了第一个相关文档的排名位置。当只有第一个相关文档是主要关注的情况下,MRR特别有用。倒数排名是第一个相关文档被找到的排名的倒数。MRR是多个查询的这些倒数排名的平均值。MRR的公式如下:

其中Q是查询的数量,是第q个查询的第一个相关文档的排名。

MRR评估的是“平均来说,系统多快能够在响应用户查询时检索到第一个相关文档?”

例如,在基于RAG的问答系统中,MRR至关重要,因为它反映了系统能够多快地向用户呈现正确答案。如果正确答案更频繁地出现在列表的顶部,MRR值将更高,表示检索系统更有效。

平均准确率(MAP)

平均准确率(MAP)是一种评估多个查询的检索精确度的度量指标。它同时考虑了检索的精确度和检索文档的顺序。MAP定义为一组查询的平均准确率得分的平均值。为了计算单个查询的平均准确率,需要在检索到的文档的排序列表中的每个位置计算精确度,只考虑前K个检索到的文档,其中每个精确度都根据文档是否相关进行加权。多个查询的MAP公式如下:

其中Q是查询的数量,是查询q的平均准确率。

MAP评估的是“平均来说,系统在多个查询中排名靠前的文档的精确度如何?”

例如,在基于RAG的搜索引擎中,MAP至关重要,因为它考虑了检索的精确度和不同排名的检索结果,确保相关文档在搜索结果中更高地显示,从而通过首先呈现最相关的信息来提高用户体验。

响应评估

响应评估适用于系统的生成组件。这些评估衡量系统根据检索到的文档提供的上下文有效地生成响应的能力。我们将响应评估分为两种类型:

忠实度(基于检索)

忠实度评估生成的响应是否准确,并且基于检索到的文档。它确保响应不包含幻觉或错误信息。这个度量指标至关重要,因为它将生成的响应追溯到其来源,确保信息基于可验证的真实情况。忠实度有助于防止幻觉,即系统生成听起来合理但事实上不正确的响应。

为了衡量忠实度,通常使用以下方法:

答案相关性

答案相关性衡量生成的响应对用户的查询有多好,并提供有用的信息。

四、使用LangSmith进行评估

了解了这些评估指标,该如何进行评估,可以先通过使用LangSmith进行评估,LangSmith 是一个开发者平台,允许您调试、测试、评估和监控大语言模型 (LLM) 应用程序,并且能够与 LangChain 无缝集成, 助您从开发原型顺利过渡到实际生产应用。

在LLM任务中,测量准确性的一个挑战来自非结构化文本的影响。问答系统可能生成冗长的响应,使得传统的指标如 BLEU 或 ROUGE 变得不可靠。在这种情况下,使用标注良好的数据集和大语言模型 (LLM) 辅助评估器可以帮助您评估系统的响应质量。

针对一个RAG系统进行评估,主要步骤如下:

1. 在LangChain代码中加入使用LangSmith

第一步:获取一个LangChain的API Key,登录LangSmith:https://smith.langchain.com/,参考下图创建API key:

第二步:设置以下参数后,LangSmith会自动进行跟踪管理。

importosos.environ['LANGCHAIN_TRACING_V2']='true'os.environ['LANGCHAIN_ENDPOINT']='https://api.smith.langchain.com'os.environ['LANGCHAIN_API_KEY']=<your-api-key>os.environ['LANGCHAIN_PROJECT']="myprojectname"

2.准备测试数据

这里整理了三种准备测试数据的方式:数据导入,代码创建和使用LangSmith辅助创建。

第一种方法:CSV文件导入

第二种方法:代码创建

下面的代码执行后,也可以在LangSmith中新建一个 Retrieval QA Questions xxxxx 的测试集。

# 问题与答案examples = [("What is LangChain?","LangChain is an open-source framework for building applications using large language models. It is also the name of the company building LangSmith.",),("Can I trace my Llama V2 llm?","So long as you are using one of LangChain's LLM implementations, all your calls can be traced",),]
# 数据库创建部分from langsmith import Clientclient = Client()
import uuiddataset_name = f"Retrieval QA Questions {str(uuid.uuid4())}"dataset = client.create_dataset(dataset_name=dataset_name)for q, a in examples:client.create_example(inputs={"question": q}, outputs={"answer": a}, dataset_id=dataset.id)

第三种方法:使用LangSmith辅助创建

创建的步骤如下:

3.使用LangSmith进行评估

测试数据准备好之后,就可以开始对系统进行评估了。LangSmith的后台可以生成评估的代码。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"/>

RAG QA问答的正确性评估器(Evaluator)包含三个版本:“qa”、“context_qa”、“cot_qa”。

“qa”评估器,指示大语言模型 (LLM) 根据参考答案直接将响应评为“正确”或“错误”。

“context_qa”评估器指示 LLM 使用参考“上下文”来确定响应的正确性。用于只有上下文和解答,没有答案的情况。

“cot_qa”评估器与“context_qa”评估器类似,但它指示 LLMChain 在得出最终结论前使用思维链“推理”。

这通常会导致响应更好地与人工标签匹配,但会稍微增加 Token 和运行成本。

更多评估器,可以参考下面的文档:
https://docs.smith.langchain.com/old/evaluation/faq/evaluator-implementations

4. 完整代码

import langsmithfrom langchain import chat_models, prompts, smithfrom langchain.schema import output_parserfrom langchain_community.llms import Ollamafrom langchain_community.embeddings import OllamaEmbeddingsimport bs4from langchain import hubfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain_community.document_loaders import WebBaseLoaderfrom langchain_community.vectorstores import Chromafrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnablePassthrough
from langchain_community.document_loaders import UnstructuredHTMLLoaderloader = UnstructuredHTMLLoader("./240327-ollama-20question.html")docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)splits = text_splitter.split_documents(docs)vectorstore = Chroma.from_documents(documents=splits, embedding=OllamaEmbeddings(model="mofanke/acge_text_embedding"))retriever = vectorstore.as_retriever()
from langchain.prompts import ChatPromptTemplatetemplate = """你是一个回答问题的助手。请使用以下检索到的背景信息来回答问题。如果你不知道答案,直接说你不知道。请用最多三句话来保持回答的简洁性。问题:{question}
背景:{context}
答案:"""
prompt = ChatPromptTemplate.from_template(template)
#llm = chat_models.ChatOpenAI(model="gpt-3.5-turbo", temperature=0)llm = Ollama(model="qwen:72b", temperature=0)
# Post-processingdef format_docs(docs):return "\n\n".join(doc.page_content for doc in docs)
# Chainrag_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}| prompt| llm| StrOutputParser())
# 执行查询rag_chain.invoke("Ollama支持哪些模型?")
# 定义评估设置(评估器,评估用的LLM等)eval_config = smith.RunEvalConfig(evaluators=["cot_qa"],custom_evaluators=[],eval_llm=Ollama(model="qwen:72b", temperature=0))
client = langsmith.Client()chain_results = client.run_on_dataset(dataset_name="Self-RAG-Ollama-20QA",llm_or_chain_factory=rag_chain,evaluation=eval_config,project_name="test-crazy-rag-qw72b-qw72b",concurrency_level=5,verbose=True,)

开发RAG系统本身并不困难,但评估RAG系统对于性能、实现持续改进、与业务目标保持一致、平衡成本、确保可靠性和适应新方法至关重要。这个全面的评估过程有助于构建强大、高效和以用户为中心的RAG系统。






欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5