我们知道构建用于检索增强生成(Retrieval-Augmented Generation,简称RAG)应用的概念验证是容易的,但是要使其生产就绪非常困难。使RAG流水线的性能达到令人满意的状态尤其困难,因为RAG流水线中的不同组件:
在评估RAG流水线时,必须单独以及一起评估这两个组件,以理解RAG流水线是否以及在哪里还需要改进。此外,为了了解你的RAG应用的性能是否在提高,你必须进行定量评估。为此,你将需要两个要素:评估指标和评估数据集。
RAGA是什么
RAGA是一个框架,它为你提供了必要的要素,帮助你在组件级别评估RAG流水线。
评估数据
关于RAGA有趣的一点是它最初是作为一个“无需参考”的评估框架而开始的。这意味着,与其依赖于评估数据集中的人类注释的真实标签,RAGA更多地利用LLM来进行评估。
为了评估RAG流水线,RAGAs期望以下信息:
利用LLM进行无需参考的评估是一个活跃的研究话题。尽管使用尽可能少的人类注释数据使它成为一个更便宜、更快速的评估方法,但是人们仍在讨论它的一些缺陷,如偏差。然而,一些论文已经显示了有希望的结果。
请注意,该框架已扩展,以提供需要真实标签的指标和范例(例如,context_recall和answer_correctness)。
此外,该框架还为你提供了自动测试数据生成的工具。
评估指标
RAGA为你提供了一些指标,用于在组件级别以及端到端评估RAG流水线。
在组件级别,RAGA提供了评估检索组件(context_relevancy和context_recall)和生成组件(faithfulness和answer_relevancy)的指标:
所有指标都按[0, 1]的范围缩放,更高的值表示更好的性能。
使用RAGA评估RAG应用
本节使用RAGA评估一个最小的vanilla RAG流水线,向你展示如何使用RAGAs,并给你直观地了解其评估指标。
先决条件
确保你已经安装了所需的Python包:
#!pip install langchain openai weaviate-client ragas
另外,在你的根目录中创建一个 .env 文件来定义你的相关环境变量。要获取 OpenAI API 密钥,你需要一个 OpenAI 账户,然后在 API 密钥下选择“创建新的密钥”。
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
设置RAG应用程序
在你评估RAG应用程序之前,你需要进行设置。我们将使用一个原始的RAG管道。
首先,你必须准备数据,通过加载和分块处理文档。
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()
)
准备评估数据
因为RAGA旨在成为一个无需参考的评估框架,所以所需的评估数据集准备工作是最少的。你需要准备问题和ground_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)
如果你对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()
在下面,你可以看到示例的RAGA得分:
我们可以做出以下观察:
总结
构建概念验证的重复注意生成(RAG)应用程序很容易,但要使其性能达到生产就绪状态则很困难。和机器学习项目一样,你应该使用验证数据集和评估指标来评估RAG管道的性能。
然而,由于RAG管道包含多个必须单独并且组合评估的组件,你将需要一组评估指标。此外,从人类注释者那里生成高质量的验证数据集很困难,耗时且昂贵。
本文介绍了RAGA评估框架。该框架提出了四个评估指标 — 上下文相关性、上下文召回率、信实性和答案相关性 — 它们共同构成了RAGA得分。