RAGAs评估工具:用指标与LLM优化你的RAG管道性能

文摘   2024-12-01 16:06   美国  
截至目前,我们知道构建一个检索增强生成(RAG)应用的证明概念很简单,但要使其投入生产却非常困难。由于 RAG 管道中不同组件的存在,使 RAG 管道的性能达到令人满意的状态尤其困难。
在评估 RAG 管道时,你必须单独和一起评估其组件,以了解 RAG 管道是否以及在哪里还需要改进。此外,为了了解您的 RAG 应用程序的性能是否在提高,您必须对其进行定量评估。
为此,您需要两个要素:一个评估指标和一个评估数据集。
目前,确定合适的评估指标和收集良好的验证数据是一个活跃的研究领域。由于这是一个快速发展的主题,我们目前正见证各种 RAG 评估框架的出现,例如 RAG 三联指标、ROUGE、ARES、BLEU 和 RAGas [1]。本文将重点介绍如何使用 RAGas 评估 RAG 管道。
RAGAs(检索增强生成评估)是一个框架,为您提供评估您 RAG 管道组件级别的必要成分。
RAGAs 的有趣之处在于它最初是一个用于“无参考”评估的框架。这意味着,在评估数据集中,RAGAs 不需要依赖人工标注的基准标签,而是利用LLMs在幕后进行评估。

RAGAs为您提供了一系列指标,用于分别评估RAG管道的各个组件和整体性能。

在组件级别,RAGAs提供了评估检索组件(上下文相关性和上下文召回率)和生成组件(忠诚度和答案相关性)的指标:

1. 上下文精度:衡量检索到的上下文的信噪比,使用问题和上下文计算。

2. 上下文召回:衡量是否检索到了回答问题所需的所有相关信息,基于ground_truth和上下文进行计算。

3. 忠诚度:衡量生成答案的事实准确性,通过计算正确陈述占生成答案总陈述的比例,使用问题、上下文和答案进行计算。

4. 答案相关性:衡量生成的答案与问题的相关性,通过问题和答案进行计算。例如,如果问题是“法国在哪里,它的首都是什么?”而答案是“法国位于西欧”,则相关性较低,因为答案只涵盖了一部分内容。

所有指标都被缩放到[0, 1]范围内,值越高表示性能越好。

此外,RAGAs还提供了评估RAG管道端到端性能的指标,如答案语义相似度和答案正确性。本文主要关注组件级指标。

本节使用 RAGAs 评估最小化 vanilla RAG 管道,以向您展示如何使用 RAGAs,并为您提供对其评估指标的感觉。
安装依赖包。
#!pip install langchain openai weaviate-client ragas
此外,请在根目录下的 .env 文件中定义您相关的环境变量。要获取 OpenAI API 密钥,您需要一个 OpenAI 账户,然后在 API 密钥下“创建新的密钥”。
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
首先,您必须通过加载和分块文档来准备数据。
import requestsfrom langchain.document_loadersimport TextLoaderfrom langchain.text_splitterimport CharacterTextSplitterurl ="https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt"res = requests.get(url)withopen("state_of_the_union.txt","w")as f: f.write(res.text)# Load the dataloader = TextLoader('./state_of_the_union.txt')documents = loader.load()# Chunk the datatext_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)chunks = text_splitter.split_documents(documents)
接下来,使用 OpenAI 嵌入模型为每个块生成向量嵌入,并将它们存储在向量数据库中。
from langchain.embeddingsimport OpenAIEmbeddings
from langchain.vectorstoresimport Weaviate
import weaviate
from weaviate.embeddedimport EmbeddedOptions
from dotenvimport load_dotenv,find_dotenv

# Load OpenAI API key from .env file
load_dotenv(find_dotenv())

# Setup vector database
client = weaviate.Client(
embedded_options = EmbeddedOptions()
)

# Populate vector database
vectorstore = Weaviate.from_documents(
client = client,
documents = chunks,
embedding = OpenAIEmbeddings(),
by_text =False
)

# Define vectorstore as retriever to enable semantic search
retriever = vectorstore.as_retriever()
最后,设置一个提示模板,并将 OpenAI LLM 与检索组件结合到一个 RAG 流程中。
from langchain.chat_modelsimport ChatOpenAI
from langchain.promptsimport ChatPromptTemplate
from langchain.schema.runnableimport RunnablePassthrough
from langchain.schema.output_parserimport StrOutputParser

# Define LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# Define prompt template
template ="""You are an assistant for question-answering tasks.
Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know.
Use two sentences maximum and keep the answer concise.
Question: {question}
Context: {context}
Answer:
"""


prompt = ChatPromptTemplate.from_template(template)

# Setup RAG pipeline
rag_chain = (
{"context": retriever,"question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
RAGAs 旨在成为一个无参考评估框架,因此评估数据集的准备工作非常少。您需要准备 questionground_truths 对,然后可以通过以下推理方法准备剩余信息:
from datasetsimport Dataset

questions = ["What did the president say about Justice Breyer?",
"What did the president say about Intel's CEO?",
"What did the president say about gun violence?",
]
ground_truths = [["The president said that Justice Breyer has dedicated his life to serve the country and thanked him for his service."],
["The president said that Pat Gelsinger is ready to increase Intel's investment to $100 billion."],
["The president asked Congress to pass proven measures to reduce gun violence."]]
answers = []
contexts = []

# Inference
for queryin questions:
answers.append(rag_chain.invoke(query))
contexts.append([docs.page_contentfor docsin retriever.get_relevant_documents(query)])

# To dict
data = {
"question": questions,
"answer": answers,
"contexts": contexts,
"ground_truths": ground_truths
}

# Convert dict to dataset
dataset = Dataset.from_dict(data)
如果您对context_recall 指标不感兴趣,您不需要提供 ground_truths 信息。在这种情况下,您只需要准备 question

首先,从 ragas.metrics 导入您想要使用的所有指标。然后,您可以使用 evaluate() 函数,只需传入相关指标和准备好的数据集即可。

from ragasimport evaluate
from ragas.metricsimport (
faithfulness,
answer_relevancy,
context_recall,
context_precision,
)

result = evaluate(
dataset = dataset,
metrics=[
context_precision,
context_recall,
faithfulness,
answer_relevancy,
],
)

df = result.to_pandas()

以下可以看到示例的 RAGAs 分数结果:

我们可以得出以下观察:

上下文相关性(检索到的上下文的信噪比):虽然LLM认为最后一个问题的所有上下文都是相关的,但它也认为对于第二个问题,大部分检索到的上下文是不相关的。根据此指标,您可以尝试调整检索到的上下文数量,以减少噪声。

上下文召回(是否检索到回答问题所需的所有相关信息):LLM评估认为检索到的上下文包含回答问题所需的全部相关信息。

忠诚度(生成答案的事实准确性):虽然LLM认为第一个和最后一个问题的答案正确,但第二个问题的答案错误地指出总统没有提到英特尔CEO,因此其忠诚度评分为0.5。

答案相关性(生成的答案与问题的相关性):所有生成的答案都被评判为与问题相关。

可见,构建一个概念验证的RAG应用相对简单,但要使其性能达到生产级别却非常困难。与机器学习项目类似,您应通过验证数据集和评估指标来评估RAG管道的性能。

然而,由于RAG管道包含多个组件,这些组件需要单独以及组合地进行评估,因此需要一套全面的评估指标。此外,生成一个高质量的验证数据集需要依赖人工标注,这不仅困难且耗时,而且成本高昂。

本文介绍了RAGAs评估框架,该框架提出了四个评估指标——上下文相关性上下文召回忠诚度答案相关性,这些指标共同构成RAGAs得分。此外,RAGAs在底层通过LLMs进行无参考评估,从而节省了成本。

参考:https://towardsdatascience.com/evaluating-rag-applications-with-ragas-81d67b0ee31a

AI技术研习社
专注分享人工智能、大模型、算法、大数据开发、数据分析领域的技术干货和落地实践!
 最新文章