前言
在这篇文章中,围绕检索召回(Retrieval),风叔详细介绍如何优化RAG系统的召回结果,提升LLM大模型的回答准确度。
在检索召回的时候,用户的问题会被输入到嵌入模型中进行向量化处理,然后系统会在向量数据库中,搜索与该问题向量语义上相似的知识文本或历史对话记录并返回。
在Naive Rag中,系统会将所有检索到的块直接输入到 LLM生成回答,导致出现中间内容丢失、噪声占比过高、上下文长度限制等问题。
下面,我们结合源代码,详细介绍下Reranking(重排序)、Refinement(压缩)和Corrective Rag(纠正性Rag)这三种优化召回准确率的方案。
具体的源代码地址可以在文末获取。
1. Rerank(重排序)
重排序,顾名思义,就是将检索召回的结果,按照一定的规则或逻辑重新排序,从而将相关性或准确度更高的结果排在前面,提升检索质量。
重排序主要有两种类型,基于统计打分的重排序和基于深度学习的重排序。
基于统计的重排序会汇总多个来源的候选结果列表,使用多路召回的加权得分或倒数排名融合(RRF)算法来为所有结果重新算分。这种方法的优势是计算简单,成本低效率高,广泛用于对延迟较敏感的传统检索系统中,比如内部知识库检索、电商智能客服检索等。
基于深度学习模型的重排序,通常被称为 Cross-encoder Reranker,经过特殊训练的神经网络可以更好地分析问题和文档之间的相关性。这类 重排序可以给问题和文档之间的语义相似度进行打分,打分只取决于问题和文档的文本内容,不取决于文档在召回结果中的位置。这种方法的优点是检索准确度更高,但成本更高,响应时间更慢,比较适合于对检索精度要求极高的场景,比如医疗问诊。
我们也可以使用大名鼎鼎的Cohere进行重排,一个非常优秀的开源工具,支持多种重排序策略。
其使用方法也非常简单,如以下代码所示:
from langchain_community.llms import Cohere``from langchain.retrievers import ContextualCompressionRetriever``from langchain.retrievers.document_compressors import CohereRerank``from langchain.retrievers.document_compressors import CohereRerank`` ``retriever = vectorstore.as_retriever(search_kwargs={"k": 10})`` ``# Re-rank``compressor = CohereRerank()``compression_retriever = ContextualCompressionRetriever(` `base_compressor=compressor, base_retriever=retriever``)`` ``compressed_docs = compression_retriever.get_relevant_documents(question)
2. Refinement(压缩)
压缩,即对于检索到的内容块,不要直接输入大模型,而是先删除无关内容并突出重要上下文,从而减少整体提示长度,降低冗余信息对大模型的干扰。
langchain中有一个基础的上下文压缩检索器可以使用,叫做ContextualCompressionRetriever。
from langchain.retrievers import ContextualCompressionRetriever``from langchain.retrievers.document_compressors import LLMChainExtractor``from langchain_openai import OpenAI`` ``llm = OpenAI(temperature=0)``compressor = LLMChainExtractor.from_llm(llm)``compression_retriever = ContextualCompressionRetriever(` `base_compressor=compressor, base_retriever=retriever``)`` ``compressed_docs = compression_retriever.invoke(` `"What did the president say about Ketanji Jackson Brown"``)
LLMChainFilter是一个稍微简单但更强大的压缩器,它使用 LLM 链来决定过滤掉哪些最初检索到的文档以及返回哪些文档,而无需操作文档内容
from langchain.retrievers.document_compressors import LLMChainFilter`` ``_filter = LLMChainFilter.from_llm(llm)``compression_retriever = ContextualCompressionRetriever(` `base_compressor=_filter, base_retriever=retriever``)`` ``compressed_docs = compression_retriever.invoke(` `"What did the president say about Ketanji Jackson Brown"``)``pretty_print_docs(compressed_docs)
3. Corrective Rag(纠错性Rag)
Corrective-RAG (CRAG) 是一种 RAG 策略,它结合了对检索到的文档进行自我反思/自我评分。
CRAG 增强生成的方式是使用轻量级的“检索评估器”,该评估器为每个检索到的文档返回一个置信度分数,然后该分数决定触发哪种检索操作。例如评估器可以根据置信度分数将检索到的文档标记为三个桶中的一个:正确、模糊、不正确。
如果所有检索到的文档的置信度分数均低于阈值,则假定检索“不正确”。这会触发采取新的知识来源(例如网络搜索)的行动,以实现生成的质量。
如果至少有一个检索到的文档的置信度分数高于阈值,则假定检索“正确”,这会触发对检索到的文档进行知识细化的方法。知识细化包括将文档分割成“知识条”,然后根据相关性对每个条目进行评分,最相关的条目被重新组合为生成的内部知识。
所以,Corrective Rag的关键在于”检索评估器“的设计,以下是一个实现检索评估器的示例:
from langchain_core.prompts import ChatPromptTemplate``from langchain_core.pydantic_v1 import BaseModel, Field``from langchain_openai import ChatOpenAI`` ``# Data model``class GradeDocuments(BaseModel):` `"""Binary score for relevance check on retrieved documents."""`` ` `binary_score: str = Field(` `description="Documents are relevant to the question, 'yes' or 'no'"` `)`` ``# LLM with function call``llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)``structured_llm_grader = llm.with_structured_output(GradeDocuments)`` ``# Prompt``system = """You are a grader assessing relevance of a retrieved document to a user question. \n `` If the document contains keyword(s) or semantic meaning related to the question, grade it as relevant. \n` `Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question."""`` ``grade_prompt = ChatPromptTemplate.from_messages(` `[` `("system", system),` `("human", "Retrieved document: \n\n {document} \n\n User question: {question}"),` `]``)`` ``retrieval_grader = grade_prompt | structured_llm_grader``question = "agent memory"``docs = retriever.get_relevant_documents(question)``doc_txt = docs[1].page_content``print(retrieval_grader.invoke({"question": question, "document": doc_txt}))
但是,Corrective Rag的局限性是严重依赖于检索评估器的质量,并容易受到网络搜索引入的偏见的影响,因此微调检索评估器可能是不可避免的。
到这里,三种有效优化检索召回的方法就介绍完了。关注【风叔云】公众号,回复关键词“检索优化”,获取完整的源代码。
总结
在这篇文章中,风叔详细介绍了优化Retrival(检索召回)的三种方法,包括Rerank(重排序)、RefineMent(压缩)、Corrective Rag(纠错性Rag)。
检索召回的下一步是最终内容生成,即使使用了上述检索召回的优化方案,最终生成环节也可能遇到格式错误、内容不完整、政治不正确等问题。因此,在生成环节,我们也需要相应的优化方案,给整个RAG流程画上完美的句号。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。