用 RAGAs(检索增强生成评估)评估 RAG(检索增强型生成)应用 [译]

评估 RAG 应用和 RAGA 的方法

这是一个包含度量标准和大语言模型(LLM)生成的数据的框架,用于评估您的检索增强型生成流程的性能。

检索增强生成的风格化性能仪表板
检索增强生成的风格化性能仪表板

我们已经知道,建立一个 检索增强生成 (Retrieval-Augmented Generation, RAG) 应用 的概念验证相对简单,但要将其实际应用到生产环境中则非常具有挑战性。特别是,由于 RAG 流程中涉及多个不同的组件,要使其性能达到满意的状态尤其困难:

  • 检索器组件: 为大语言模型从外部数据库中检索额外的上下文,以便回答查询。
  • 生成器组件: 基于结合了检索信息的提示来生成答案。

在评估 RAG 流程时,需要单独对这两个组件进行评估,然后再综合考虑,以判断 RAG 流程在哪些方面仍需改进。此外,要了解你的 RAG 应用性能是否有所提升,必须进行量化的评估。为此,你需要两个关键元素:一个评估指标一个评估数据集。

目前,在确定合适的评估指标和收集高质量验证数据方面,科研界正忙于探索和研究。这是一个发展迅速的领域,我们可以看到各种各样的 RAG 评估框架方法逐渐出现,比如 RAG 三元组指标ROUGEARESBLEURAGAs [1]。这篇文章将主要介绍如何利用 RAGAs [1] 来评估 RAG 流程。

RAGAs 是什么

RAGAs(检索增强生成评估)是一个提供必要工具的框架(GitHub文档),这些工具可以帮助你在组件层面上对你的 RAG 流程进行评估。

评估数据

RAGAs 最初是作为一种无需参照标准的评估框架而设计的,这一点颇具特色 [1]。这意味着,在评估数据集时,不必依赖人工标注的标准答案,而是通过底层的大语言模型 (LLM) 来进行评估。

为了对 RAG 流程进行评估,RAGAs 需要以下几种信息:

  • question:RAG 流程的输入,即用户的查询问题。
  • answer:由 RAG 流程生成的答案,也就是输出结果。
  • contexts:为解答 question 而从外部知识源检索到的相关上下文。
  • ground_truthsquestion 的标准答案,这是唯一需要人工标注的信息。这个信息仅在评估 context_recall 这一指标时才必须(详见 评估指标)。

利用大语言模型 (LLM) 进行无参考评估是当前研究的热点话题。这种依赖最少人工数据的评估方法虽然成本低、效率高,但其可能存在的偏差问题也引发了一些讨论 [3]。尽管如此,已有研究表明这种方法的结果是有前景的 [4]。更多相关信息,可以参考 RAGAs 论文中的“相关工作”部分 [1]。

值得注意的是,这一框架已经扩展,提供了一些需要依赖真实标签的评估指标和范式,比如 context_recallanswer_correctness(详见 评估指标)。

此外,该框架还提供了 自动测试数据生成的工具,方便用户使用。

评价指标

RAGAs 为您提供了一些 指标,可用于从组件层面和整体流程两个方面评估 RAG 流程的性能。

组件层次 上,RAGAs 提供了评价检索组件(包括 context_relevancycontext_recall)和生成组件(涉及 faithfulnessanswer_relevancy)的专门指标 [2]:

  • 上下文精准度 衡量检索出的上下文中有用信息与无用信息的比率。该指标通过分析 questioncontexts 来计算。
  • 上下文召回率 用来评估是否检索到了解答问题所需的全部相关信息。这一指标依据 ground_truth(此为框架中唯一基于人工标注的真实数据的指标)和 contexts 进行计算。
  • 真实性 用于衡量生成答案的事实准确度。它通过对比给定上下文中正确的陈述与生成答案中总陈述的数量来计算。这一指标结合了 questioncontextsanswer
  • 答案相关度 评估生成答案与问题的关联程度。例如,对于问题“法国在哪里及其首都是什么?”,答案“法国位于西欧。”的答案相关度较低,因为它只回答了问题的一部分。

所有指标的评分范围在 [0, 1] 之间,分数越高表示性能越出色。

RAGAs 同样为评估 RAG 流程的 整体流程 提供了指标,例如 答案的语义相似度答案的正确性。本文主要讨论的是组件层面的评价指标。

使用 RAGAs 评估 RAG 应用

本节将通过 RAGAs 工具来评估一个基本的 RAG(检索增强生成)流程。目的是向你展示如何运用 RAGAs 工具,以及它的评估指标是如何提供直观理解的。

准备工作

请确保你已经安装了以下 Python 包:

  • langchainopenaiweaviate-client,用于搭建 RAG 流程
  • ragas,用于评估 RAG 流程
!pip install langchain openai weaviate-client ragas

此外,你需要在根目录下的 .env 文件中设置相关环境变量。要获取 OpenAI 的 API 密钥,你需要注册 OpenAI 账号,并在 API keys 页面创建新的密钥。

OPENAI_API_KEY="\<YOUR_OPENAI_API_KEY>"

搭建 RAG 应用

在评估 RAG 应用之前,首先需要进行设置。我们这里使用一个基础版的 RAG 流程。关于详细的设置过程,可以参考以下链接中的文章。

检索增强生成 (RAG): 从理论到 LangChain 实现

首先,准备数据,包括加载文档和进行数据分块。

import requests
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
url = "https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt"
res = requests.get(url)
with open("state_of_the_union.txt", "w") as f:
f.write(res.text)
# Load the data
loader = TextLoader('./state_of_the_union.txt')
documents = loader.load()
# Chunk the data
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)

然后,使用 OpenAI 的嵌入模型为每个数据块生成向量嵌入,并存储在向量数据库中。

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Weaviate
import weaviate
from weaviate.embedded import EmbeddedOptions
from dotenv import 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_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import 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 datasets import 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 query in questions:
answers.append(rag_chain.invoke(query))
contexts.append([docs.page_content for docs in 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)

将字典转换为数据集

dataset = Dataset.from_dict(data)

如果你不关注 context_recall 指标,就不必提供 ground_truths 数据。在这种情况下,你只需准备 question 即可。

评估 RAG 应用

首先,从 ragas.metrics 导入你计划使用的所有度量标准。然后,使用 evaluate() 函数,简单地传入所需的度量标准和已准备好的数据集即可。

from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_recall,
context_precision,
)
result = evaluate(
dataset = dataset,
metrics=[
context_precision,
context_recall,
faithfulness,
answer_relevancy,
],
)
df = result.to_pandas()

下方展示了示例中的 RAGAs 分数:

RAGAs 分数涵盖了上下文精确度、上下文回忆率、答案的忠实度和相关性。
RAGAs 分数涵盖了上下文精确度、上下文回忆率、答案的忠实度和相关性。

我们可以做出以下几点观察:

  • context_relevancy(检索上下文的相关性与噪声比):尽管大语言模型 (LLM) 认为最后一个问题的所有上下文都相关,但它也指出第二个问题检索到的大多数上下文是不相关的。基于这一指标,你可以尝试调整检索上下文的数量以降低噪声。
  • context_recall(是否检索到回答问题所需的所有相关信息):LLMs 认为检索到的上下文包含了正确回答问题所需的全部相关信息。
  • faithfulness(生成答案的事实准确性):虽然 LLM 认为第一个和最后一个问题的答案是正确的,但它对第二个问题的答案(错误地声称总统没有提到英特尔的 CEO)的准确性评分为 0.5。
  • answer_relevancy(生成答案与问题的相关性):所有生成的答案都被评估为与问题高度相关。

正如 评估数据 一文中所述,利用大语言模型 (LLM) 进行无参考评估是当前研究的热点。我对这个领域的未来发展充满期待。

概述

虽然快速搭建一个概念验证阶段的 RAG 应用相对简单,但要提升其到生产级别的性能却颇具挑战。这类似于在机器学习项目中,需要借助验证数据集和评估标准来全面审视 RAG 流程的效能。

但由于 RAG 流程涉及多个组件,这些组件不仅要单独评估,还需联合考量,因此需要多种评估标准。而且,依靠人工标注创建高品质的验证数据集既耗时又成本高昂。

本文向大家介绍了 RAGAs [1] 这一评估框架。该框架定义了四个核心评估指标——context_relevancy(上下文相关性)、context_recall(上下文回溯)、faithfulness(忠实度)和 answer_relevancy(答案相关性)——这四个指标共同构成了 RAGAs 评分体系。此外,RAGAs 还巧妙利用了大语言模型 (LLM) 进行无参考评估,以降低成本。

现在,你已经掌握了评估 RAG 应用性能的必要工具,我建议你构建一个实验流程,并根据以下调优策略来逐步提升应用的表现:

打造生产级 RAG 应用的 12 种调优策略指南

生成这些数据集的代码可以在这个 GitHub 仓库中找到。