DECEMBER
点击上方蓝字关注我们
在前面的两篇关于RAG优化的文章中,我们直接聚焦在应用本身的输出:如何提升语意检索精度、处理多模态知识等。本篇我们将关注一个重要工程问题: 当我们了构建了一个完整的RAG应用以后,在交付生产之前,如何对应用作一个科学的评估(Evaluation),以发现问题并确保我们有信心将其投入生产?
PART\
01
为什么需要评估RAG应用
当前,借助于开源框架,比如LangChain或者LlamaIndex;或者一些RAG应用SaaS平台,可以在较短的时间内快速构建一个RAG应用;如果您的企业一直都有较完善的知识管理与维护平台及机制,这个时间或许还可以进一步缩短。但是正如我们之前提到的大模型在真实的企业应用场景中的一些挑战:
- 大模型的输出不确定性会带来一定的不可预知性,一个RAG应用在投入生产之前需要科学的测试以衡量这种不可预知性
- RAG应用上线后的持续维护增强中,需要科学、快速、可复用的手段来衡量其改进,比如回答的置信度是上升了10%还是下降了5%?
- RAG应用中的“外挂”知识库是动态的,在不断的维护过程中,可能会产生新的相互干扰,因此,定期的检测与评估是必要的
- 如何在遍地的商业与开源大模型选择最适合企业的模型?或者如何知道大模型一次版本升级对我的RAG应用产生了多大影响?
传统的软件开发在交付之前必然会经过完整的测试,借助科学的用例、脚本与工具来评估软件的输入输出是否符合预期。基于大模型的RAG应用同样也需要这样的过程,但是不同的是, 传统应用软件的输出大多是确定且易于衡量的,而RAG应用中的输入输出都是自然语言,评估其相关性与准确性等都无法通过简单的观察判断,需要借助工具与评估模型来完成。
本文介绍如何借助开源的RAGAS评估框架,来科学地评估RAG应用的一些关键指标,以实现指标驱动开发(MDD,Metrics-Driven Development)的愿景,确保RAG应用的持续监控与增强。
PART\
02
了解RAGAS框架及指标体系
RAGAs ( R etrieval- A ugmented G eneration As sessment)是一个针对大模型RAG应用的评估框架。借助它你可以快速对构建的RAG应用做性能评估,以建立用于持续改进的量化指标体系。
RAGAS需要的输入信息
RAGAS评估需要的输入信息包括以下四项:
- question :作为 RAG 应用的输入,通常是用户问题。
- answer :RAG应用的输出结果,比如问题的答案。
- contexts :从“外挂”知识库语义检索出的相关知识。
- ground_truths :人类需要标注/提供的事实即正确答案。
因此,基于这些信息的评估流程大致如下:
组件级评估
组件评估是对构成RAG的两个重要组件进行独立评估,并生成相关指标,用于更细致地观察与分析问题所在,从而进行优化与增强。 任何RAG应用都必然包含的两个组件:
检索器组件(Retriever): 代表 RAG中的“R”。 用于从外部向量数据库中通过语意检索生成与Question最相关的知识上下文,提供给大模型用于生成回答。
生成器组件(Generator): 代表 RAG中的“G”。 也就是大模型根据检索到的相关上下文、输入问题及指令,生成输出回答。
RAGAS提供了对RAG应用的这两个组件评估的一系列标准指标(Metrics):
主要包括如下几个关键的评估指标,在后续的例子中会进一步阐述如何观察与解释指标:
名称 | 相关输入 | 解释 |
忠实度 |
faithfulness | answer
contexts | 答案与检索出的上下文的一致性。即答案内容是否能从检索出的context中推理出来。 | | 答案相关性
Answer
relevancy | answer
question | 答案与用户问题的相关性。即答案是否完整且不冗余地回答了输入问题,此次不考虑答案的正确性。 | | 上下文精度
Context
precision | contexts
ground-truths | 检索出的相关上下文中与正确答案相关的条目是否排名较高。 | | 上下文召回率
Context
recall | contexts
ground-truths | 检索出的相关上下文与正确答案之间的一致程度。即正确答案的内容是否能够归因到上下文。 | | 上下文相关性
Context
relevancy | contexts
question | 检索出的上下文与用户问题之间的相关性。即上下文中有多少内容是和输入question相关。 |
端到端评估
所谓端到端评估是对RAG应用的端到端性能进行评估,即从用户体验的角度感知到的RAG的整体性能指标。 主要包括两个指标:
回答的语意相似度: 简单地说,就是输出的答案与你提供的“标准答案”之间的语意相似度,在0到1之间,分数越高表示生成的答案与正确答案越一致。
回答的正确性: 回答的正确性是一个更笼统的指标,涵盖了回答的语意相似度与事实相似度,并可对这两方面设定权重,计算出一个在0到1之间的正确性。
PART\
03
RAGAS评估实测
本部分我们使用RAGAS来评估一个最小粒度构建的RAG应用,以直观的展示与了解RAGAS的应用与其指标,此处以组件级评估做例子,端到端评估方法类似。
准备工作
01
RAGAS需要应用到的python包有langchain,openai,ragas,其他则根据自身应用情况而定。请使用pip自行安装。另外,由于 需要使用OpenAI模型作为评估使用,请确保拥有OpenAI账户及API-key。
应用构建
02
此处我快速构建一个简单的RAG应用作为测试,借助Langchain可以轻易实现: 首先, 准备用于构建的私有知识数据(此处用一个包含若干问答的test.csv),加载后通过embedding模型生成向量,并进入向量数据库(Chroma):
#加载测试知识test.csv
loader = CSVLoader(
file\_path='test.csv',
encoding="utf-8",
csv\_args={'delimiter':',','quotechar':'"','fieldnames':['q','a']})
data = loader.load()
#embedding进入向量数据库(chroma)
embeddings = OpenAIEmbeddings()
chroma\_client =chromadb.PersistentClient(path='./chroma\_db')
vs = Chroma.from\_documents(
documents = data,
embedding = embeddings,
client = chroma\_client,
collection\_name = 'test\_collection')
接下来, 构建一个RAG简单应用,借助Langchain的Chain组件实现:
#检索器
retriever = vs.as\_retriever()
#大模型
llm = ChatOpenAI(model\_name="gpt-3.5-turbo-1106",temperature=0)
#prompt模板
template = """您是一个用于问答任务的助手,请使用下面提供的上下文来回答问题,并保持简洁的答案。
Question: {question}
Context: {context}
Answer:
"""
prompt = ChatPromptTemplate.from\_template(template)
#RAG生成器
rag\_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
#简单测试下结果
rag\_chain.invoke('如何进入国税电子税务局报送汇算清缴?')
应用评估
03
现在,我们需要准备一个评估数据集 。RAGAS框架需要的唯一人类工作就是准备question与ground_truths数据对,即问题与正确答案,然后让已经构建的RAG应用来生成另外两个必需的信息:answer,contexts,即推理的答案与检索出的上下文。
在真实应用评估时,测试数据集的准备最好是从真实的生产应用场景中获得,比如从现有的在线咨询或者搜索历史中获得用户的真实问题和正确答案,且需要人工来检查确认,这在首次准备时会有一定工作量。
questions = [ "小规模转一般纳税人之后,企业的税务登记信息会变更吗(比如企业的纳税人识别号,公司的纳税人名称)?", "生产企业外购货物直接出口可以享受出口退税吗?", "总公司与重点人群签订劳动合同,员工实际在分公司工作,并由分公司为其缴纳社保,应当由总公司还是分公司享受税收政策?", "中国首都在哪里,有哪些名胜古迹可以参观呢?" ]
ground\_truths = [["小规模转一般纳税人以后,不会变更公司的税务登记信息的,只是企业的资格认定信息中会有一般纳税人资格认定。"],
["生产企业外购货物直接出口是否享受出口退税首先看企业是否属于列名生产企业出口非自产货物适用免抵退政策,具体情况详见相关政策。"],
["对于与总公司签订劳动合同,分公司缴纳社保的情形,应当由总公司享受税收政策。"],
["中国的首都是北京。北京有颐和园、长城、故宫等著名的风景名胜区。"]]
最后,我们借助RAGAS框架评估生成简单的评估报告。 这里我们导入了四个ragas的指标,然后调用evaluate方法并简单的传入指标和数据集即可。
answers = []
contexts = []
# 生成answer和context
for query in questions:
answers.append(rag\_chain.invoke(query))
contexts.append([docs.page\_content for docs in retriever.get\_relevant\_documents(query)])
# 构建ragas需要的输入信息
data = {
"question": questions,
"answer": answers,
"contexts": contexts,
"ground\_truths": ground\_truths
}
#开始评估
dataset = Dataset.from\_dict(data)
result = evaluate(
dataset = dataset,
metrics=[
context\_precision,
context\_recall,
faithfulness,
answer\_relevancy,
],
)
#评估结果输出到excel
df = result.to\_pandas()
df.to\_excel('eval\_result.xlsx', index=False)
评估完成。 可以在输出结果中看到如下示例的RAGA分数:
借助评估报告,我们可以观察指标并做简单解读:
- 上下文精度(context_precision) : 这个指标衡量能够推导出正确答案的上下文的排名是否较高。 此处第4个问题我们故意设定了不相干的问题,所以检索出的上下文中无法推导出正确答案,导致得分为0。 这通常说明导入知识库涵盖范围不足、或者虽然能够检索相关知识,但是却无法推导出正确答案,可能存在知识错误情况。
- 上下文召回(context_recall) :这个指标衡量检索出的上下文与正确答案的相关性和一致性。 这里最后的不相关问题的召回率也是1,这可能是由于测试中我们把语义相似检索的阀值设置比较低,导致检索了一批语义距离较远、携带内容过多的context,误导了ragas(需进一步确认)。
- 忠实度(faithfulness) : 这个指标说明生成的答案(注意不是正确答案)是否能从检索出上下文推导出。 和context_precision一样,由于第4个问题是个不相干的问题,上下文无法推导出最后的答案,所以得分0。
如果这里得分为0或者得分较低,但仍然获得了答案。就说明获得的答案全部或者部分由大模型自己“编造”生成(当然也可能是对的),而不是从上下文推理获得。 当然,你可以在提示词上要求大模型这种情况拒绝回答。
- 答案相关性(answer_relevancy) : 这个指标说明生成的答案是否完整且简洁地回答了问题,但不考虑答案是否正确。 这里的指标较高,说明最后的输出答案还是涵盖了问题中需要回答的关键点, 尽管这些答案不一定是从context得出,也不一定正确。
PART\
04
与LangSmith配合使用
LangSmith是Langchain团队构建生产级大模型应用的平台,专注于LLM应用的跟踪、调试与评估阶段。由于RAGAS在底层使用了Langchain,因此可以很方便地与langsmith集成,方便跟踪evaluator的运行过程。
如果需要设置langsmith,只要确保设置以下环境,然后正常运行evaluator即可:
export LANGCHAIN\_TRACING\_V2=true
export LANGCHAIN\_ENDPOINT=https://api.smith.langchain.com
export LANGCHAIN\_API\_KEY=<your-api-key>
export LANGCHAIN\_PROJECT=<your-project>
请从smith.langchain.com获得自己API_KEY。运行RAGAS的evaluate之后,就可以登录langsmith查看运行轨迹:
PART\
05
结束语
以上我们介绍了如何借助开源的评估框架RAGAS来验证RAG应用的各项性能指标。大模型RAG应用的概念验证很容易,但是要为真实的生产准备好,就需要借助这样完整的指标体系来科学地评估与发现问题,从而能够采取针对性的优化以增强可用性。
需要指出的是, 构建一个高质量的评估数据集也是一个较复杂且工作量较大的任务 。因此也有一些项目在研究无参考的指标评估方法,即无需借助人类标注数据集的自动化评估框架,让我们拭目以待。
END
点击下方关注我,不迷路