RAG,也就是检索增强型生成,是现在大型语言模型(LLMs)时代里的一个超火的AI框架,比如你知道的ChatGPT。它通过把外面的知识整合进来,让这些模型变得更聪明,能给出更准确、更及时的回答。详见前篇文章《什么是检索增强生成(RAG)》
概括来说,一个典型的RAG系统得有一个LLM,一个像Milvus这样的向量数据库,还得有一些提示,就像下图所示那样。
现在越来越多的开发者和公司开始用RAG来开发GenAI应用了,所以评价这些应用好不好用就变得越来越关键了。这篇文章会深入聊聊怎么评价RAG应用,还会介绍一些超给力的评估工具和一些标准指标。
评价RAG应用不是随便比较几个例子那么简单。重要的是得用那些有说服力的、可以量化的、能重复的指标来评价这些应用。我们会介绍三种类型的指标:
-
基于ground truth(已知答案)的指标
-
没有ground truth(未知答案)的指标
-
基于LLM给出的响应的指标
所谓的“ground truth”,就是数据集中那些已经确定的答案或者知识文档的片段,它们和用户的查询是匹配的,就像“已知答案”一样。如果ground truth是答案,我们可以直接拿它和RAG的响应比一比,用一些指标比如答案的语义相似度或者答案的正确性来从头到尾测量一下。
那怎么根据答案的正确性来评估它们?比如说,我们有个事实:爱因斯坦是在1879年在德国出生的,这就是我们说的“ground truth”。
如果一个答案说的是:“1879年,在德国,爱因斯坦出生了。”那这个答案就非常准确,我们可以说它具有高答案正确性。
但是,如果答案说的是:“在北京,爱因斯坦于1879年出生。”那这个答案就不靠谱,我们说它具有低答案正确性。
当我们评估的是知识文档的一部分,而不是一个完整的答案时,我们可以用一些传统的指标,比如精确匹配(EM)、Rouge-L和F1,来衡量文档和检索到的上下文之间的相关性。实际上,我们是在评估RAG应用的检索效果。
我们已经知道,用有ground truth的数据集来评估RAG应用是很重要的。但是,如果你手头上有的是一个没有标注ground truth的私有数据集,你要怎么评估RAG应用呢?你又怎么为你的数据集生成需要的ground truth呢?
最简单的一个办法就是让像ChatGPT这样的大型语言模型(LLM)根据你的专有数据集生成一些示例问题和答案。还有一些工具,比如Ragas和LlamaIndex,它们也能帮你生成专门为你的知识文档定制的测试数据。
Ragas评估工具生成的示例问题和答案
这些生成的测试数据集包含了问题、上下文和相应的答案,这使得我们能够进行定量的评估,而不需要依赖于那些可能不相关的外部基准数据集。这种方法让用户可以使用他们自己的独特数据来评估RAG系统,确保了评估过程更加个性化和有意义。
即使没有每个查询的确切答案,我们也能评估RAG应用。TruLens-Eval这个开源评估工具就挺厉害的,它提出了RAG三元组的概念,专注于评估查询、上下文和响应三元组中元素的相关性。这里有三个相关的指标:
-
上下文相关性:这个指标用来衡量检索到的上下文对查询的支持程度。
-
基础性:这个指标用来评估LLM的响应和检索到的上下文是否一致。
-
答案相关性:这个指标用来衡量最终的响应和查询的相关性。
举个例子,我们来评估一下答案和问题的相关性。
问题:法国在哪里,它的首都是哪里?
低相关性答案:法国在西欧。
这个答案只回答了问题的一部分,所以相关性不高。
高相关性答案:法国在西欧,巴黎是它的首都。
这个答案就全面多了,不仅提到了法国的位置,还提到了首都,所以相关性很高。
RAG三元组
此外,这些三元组指标还能更细致地分,让评估更精确。比如,Ragas这个专门用来评估RAG系统性能的开源框架,就把上下文相关性拆成了三个更具体的指标:上下文精确度、上下文相关性和上下文召回率。
这些指标用来评估LLM的响应,会考虑像友好性、有害性和简洁性这样的因素。LangChain提出了一系列指标,比如简洁性、相关性、正确性、连贯性、有害性、恶意性、有用性、争议性、厌女症、犯罪性和不敏感性等等。
举个简洁性评估答案的例子:
问题:2+2等于多少?
低简洁性答案:2+2等于多少?这是一个基本问题。你要找的答案是2加2等于4。
这个答案绕来绕去的,不够直接。
高简洁性答案:4
这个答案就简单明了,直接给出了结果。
要得到那些指标的分数,通常得输入文本,这可是个费事儿的活儿。不过,有了像GPT-4这样的大型语言模型(LLM),这事儿就变得简单多了。你只需要想出一个合适的提示语就行。
有篇论文叫做《Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena》,里面就给GPT-4设计了一个这样的提示,用来评价AI助手回答问题的质量。我来给你举个例子:
[System]
请扮演一个公正的裁判,评估AI助手对下面显示的用户问题的回答质量。你的评估应该考虑回答的帮助性、相关性、准确性、深度、创造力和细节水平。在提供评分之前,请先提供一个简短的解释。尽可能客观。在提供解释后,请严格遵循以下格式给出评分:"[[rating]]",例如:"Rating: [[5]]"。
[Question]
{问题}
[The Start of Assistant's Answer]
{答案}
[The End of Assistant's Answer]
这个提示就是让GPT-4来评价回答的质量,然后按照1到10的等级给个分数。
需要注意的是,就像任何裁判一样,GPT-4也不是完美无缺的,它可能会有偏见或者犯错误。所以,设计一个好的提示特别重要,有时候可能还得用上一些高级的提示技巧,比如多镜头或者思维链(Chain-of-Thought,CoT)。不过,我们也不用太担心,因为很多用来评估RAG应用的工具都已经内置了设计得很好的提示。
现在我们已经聊了怎么评估RAG应用,接下来咱们来看看有哪些工具可以用来评估RAG应用,了解一下它们是怎么工作的,以及哪些情况最适合用这些工具。
Ragas就是一个开源的评估工具,专门用来评估RAG应用的。它的界面挺简单的,能简化评估过程。你只需要创建一个符合格式的数据集实例,就能快速开始评估,然后得到像'ragas_score'、'context_precision'、'faithfulness'和'answer_relevancy'这样的指标。
from ragas import evaluate
from datasets import Dataset
# 准备你的huggingface数据集,格式如下
# Dataset({
# features: ['question', 'contexts', 'answer', 'ground_truths'],
# num_rows: 25
# })
dataset: Dataset
results = evaluate(dataset)
# {'ragas_score': 0.860, 'context_precision': 0.817,
# 'faithfulness': 0.892, 'answer_relevancy': 0.874}
Ragas支持很多种不同的指标,而且不限制你非得用某个特定的框架,这样你在评估不同的RAG应用的时候就更灵活了。Ragas还能通过LangSmith实现实时监控评估,这样你就能知道每次评估的原因和API密钥的使用情况。
LlamaIndex:轻松构建和评估
LlamaIndex这个AI框架挺强大的,它可以用来构建RAG应用,而且还自带了评估工具。这就意味着,如果你的RAG应用是在LlamaIndex框架里构建的,你就可以用它来评估这些应用。
下面这段代码展示了怎么用LlamaIndex来评估:
from llama_index.evaluation import BatchEvalRunner
from llama_index.evaluation import (
FaithfulnessEvaluator,
RelevancyEvaluator,
)
service_context_gpt4 = ...
vector_index = ...
question_list = ...
faithfulness_gpt4 = FaithfulnessEvaluator(service_context=service_context_gpt4)
relevancy_gpt4 = RelevancyEvaluator(service_context=service_context_gpt4)
runner = BatchEvalRunner(
{"faithfulness": faithfulness_gpt4, "relevancy": relevancy_gpt4},
workers=8,
)
eval_results = runner.evaluate_queries(
vector_index.as_query_engine(), queries=question_list
)
这里,我们首先导入了需要的评估类,然后创建了评估器的实例,告诉它们用哪个服务上下文。接着,我们用BatchEvalRunner
来运行评估,指定了要评估的指标(比如忠实性和相关性),并传入了问题列表。这样,我们就能批量评估一系列问题,得到评估结果了。
TruLens Eval这个工具,它提供了一个挺方便的方法来评估那些用LangChain和LlamaIndex搭建的RAG应用。下面这段代码就展示了怎么给基于LangChain的RAG应用设置评估。
from trulens_eval import TruChain, Feedback, Tru, Select
from trulens_eval.feedback import Groundedness
from trulens_eval.feedback.provider import OpenAI
import numpy as np
tru = Tru()
rag_chain = ...
# 初始化提供商类
openai = OpenAI()
grounded = Groundedness(groundedness_provider=OpenAI())
# 定义一个基础性反馈函数
f_groundedness = (
Feedback(grounded.groundedness_measure_with_cot_reasons)
.on(Select.RecordCalls.first.invoke.rets.context)
.on_output()
.aggregate(grounded.grounded_statements_aggregator)
)
# 问题和答案之间的相关性。
f_qa_relevance = Feedback(openai.relevance).on_input_output()
tru_recorder = TruChain(rag_chain,
app_id='Chain1_ChatApplication',
feedbacks=[f_qa_relevance, f_groundedness])
tru.run_dashboard()
在这段代码里,我们首先导入了需要的TruLens Eval组件,然后创建了一个Tru实例和一个RAG链。我们用OpenAI作为提供商,来初始化一个基础性(Groundedness)的评估。然后我们定义了一个反馈函数,它会在特定的调用和输出上测量基础性,并且聚合这些评估结果。
我们还定义了另一个反馈函数来评估问题和答案之间的相关性。最后,我们创建了一个TruChain实例,传入了RAG链和反馈函数,然后运行了仪表盘,这样就可以看到评估结果了。
TruLens-Eval这个工具可以评估用其他框架搭建的RAG应用,不过在代码实现上可能有点复杂。如果你想知道更多细节,可以去看看官方文档。
而且,TruLens-Eval还有一个挺酷的功能,就是在浏览器里提供视觉监控,这样你就可以分析评估的原因,还能看到API密钥的使用情况。
Phoenix这个工具,它能提供一整套指标来评估LLMs,比如评估生成的嵌入的质量,还有LLM的响应。它也能评估RAG应用,不过跟其他我们提到过的评估工具比起来,它包含的指标可能少一些。下面这段代码就是用Phoenix来评估用LlamaIndex搭建的RAG应用的例子:
import phoenix as px
from llama_index import set_global_handler
from phoenix.experimental.evals import llm_classify, OpenAIModel, RAG_RELEVANCY_PROMPT_TEMPLATE, \
RAG_RELEVANCY_PROMPT_RAILS_MAP
from phoenix.session.evaluation import get_retrieved_documents
px.launch_app()
set_global_handler("arize_phoenix")
print("phoenix URL", px.active_session().url)
query_engine = ...
question_list = ...
for question in question_list:
response_vector = query_engine.query(question)
retrieved_documents = get_retrieved_documents(px.active_session())
retrieved_documents_relevance = llm_classify(
dataframe=retrieved_documents,
model=OpenAIModel(model_name="gpt-4-1106-preview"),
template=RAG_RELEVANCY_PROMPT_TEMPLATE,
rails=list(RAG_RELEVANCY_PROMPT_RAILS_MAP.values()),
provide_explanation=True,
)
这段代码里,我们首先导入了Phoenix需要的组件,然后启动了Phoenix应用,设置了全局处理器,并打印出了Phoenix的URL。接着,我们用查询引擎来查询问题列表中的问题,获取检索到的文档。最后,我们用llm_classify函数来评估这些文档的相关性,这个函数会用OpenAI的模型和一些预设的模板来分类文档,并给出解释。
除了我们刚才聊的那些工具,还有其他几个平台,比如DeepEval、LangSmith和OpenAI Evals,它们也能评估RAG应用。这些工具的方法都大同小异,但在设计提示和实施细节上会有所不同,所以得挑一个最适合你需求的工具。
总的来说,我们刚才回顾了不少评估RAG应用的方法论、指标和工具。我们特别看了三类指标:
-
那些基于已知正确答案的,
-
那些不需要已知正确答案的,
-
还有那些基于大型语言模型(LLMs)给出的响应的。
基于已知正确答案的指标就是把RAG的响应和标准答案比一比。而不需要已知正确答案的指标,比如RAG三元组,就更注重评估查询、上下文和响应之间的相关性。基于LLM响应的指标则考虑了回答的友好性、有害性和简洁性。
我们还讨论了如何用设计好的提示让LLMs来评分,介绍了一些RAG评估工具,比如Ragas、LlamaIndex、TruLens-Eval和Phoenix,来帮助完成评估任务。
在这个AI飞速发展的时代,定期评估和提升RAG应用真的很重要,这关系到它们的可靠性。用我们刚才讨论的方法论、指标和工具,开发者和企业可以更明智地决定他们的RAG系统的性能和能力,进而推动AI应用的发展。