2026年7月9日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

RAG(检索增强生成)系统实践与调优

发布日期:2025-01-07 08:16:55 浏览次数: 4071
作者:AI遇见云

微信搜一搜,关注“AI遇见云”



在人工智能领域,检索增强生成(Retrieval Augmented Generation, RAG)是一种结合信息检索和生成式人工智能的技术,它通过从外部数据源中检索相关信息,来辅助大语言模型(Large Language Model, LLM)生成更为准确、上下文相关的答案。




1

什么是RAG



   检索增强生成(Retrieval Augmented Generation, RAG)是一种结合信息检索和生成式人工智能的技术,它通过从外部数据源中检索相关信息,来辅助大语言模型(Large Language Model, LLM)生成更为准确、上下文相关的答案。具体来说,RAG 的工作流程包括两个关键步骤:首先,系统会根据用户的查询从预先构建的数据源中检索相关的文档或片段;然后,将这些检索到的内容作为上下文信息,和用户的问题一起输入到大语言模型中,以生成更丰富、更具参考价值的回答。RAG系统结合了搜索技术和大语言模型的生成能力:搜索技术用于找到与问题最相关的事实或数据,而大语言模型则通过处理这些信息,生成连贯、准确且更符合用户需求的自然语言回答。因此,RAG 不仅能够弥补语言模型在训练数据之外的知识盲区,还可以显著提升回答的精准性和可靠性,特别是在需要实时更新或扩展知识的应用场景中。


RAG 的工作流程主要包含三个模块:

索引(Indexing):文本索引的构建包括以下步骤:文档解析、文本分块、Embedding 向量化和创建索引。先将不同格式的原始文件解析转换为纯文本,再把文本切分成较小的文本块。通过 Embedding 为每一个文本块生成一个向量表示,用于计算文本向量和问题向量之间的相似度。创建索引将原始文本块和 Embedding 向量以键值对的形式存储,以便将来进行快速和频繁的搜索。

检索(Retrieval):使用 Embedding 模型将用户输入问题转换为向量,计算问题的 Embedding 向量和语料库中文本块 Embedding 向量之间的相似度,选择相似度最高的前 K 个文档块作为当前问题的增强上下文信息。

生成(Generation):将检索得到的前 K 个文本块和用户问题一起送进大模型,让大模型基于给定的文本块来回答用户的问题。


2

RAG实践



下面是一个使用Xinference 部署bge-embedding 模型并结合Langchain 实现简单的 RAG(检索增强生成)应用的实践步骤:


1. 使用 Xinference部署bge-embedding模型


bge-embedding 模型(bge-m3-embedding)可以通过Xinference部署,具体步骤如下:


1.1 安装Xinference


JSON
pip install --upgrade --quiet "xinference[all]"


1.2 启动bge-embedding模型


JSON
xinference launch --model-name bge-m3 --model-type embedding


启动后可通过xinference webui查看running model


 

2. LangChain中集成bge-embedding模型和LLM


2.1 安装LangChain


JSON
pip install langchain


2.2集成远端bge-embedding 模型


LangChain提供了对嵌入模型的抽象,可以创建一个自定义的嵌入模型类来调用远端的bge-embedding 服务。


Python
import requests
from langchain.embeddings.base import Embeddings

class RemoteBGEEmbedding(Embeddings):
    def __init__(self, api_url):
        self.api_url = api_url

    def embed(self, text: str):
        response = requests.post(self.api_url, json={"text": text})
        if response.status_code == 200:
            return response.json()["embedding"]
        else:
            raise Exception(f"Failed to get embedding: {response.content}")


api_url 在远端部署的bge-embedding 模型的 API地址。


调用POST 请求,将文本传递给远端的bge-embedding 模型,获取对应的嵌入向量。


2.3 调用远端LLM,此处采用QWEN14B


同理,LLM也需要集成


Python
class RemoteQwenLLM:
    def __init__(self, api_url):
        self.api_url = api_url

    def generate(self, prompt: str):
        response = requests.post(self.api_url, json={"prompt": prompt})
        if response.status_code == 200:
            return response.json()["response"]
        else:
            raise Exception(f"Failed to get response: {response.content}")


api_url 是远端 LLM生成API地址。


3.构建 RAG管道


使用 LangChainRetrievalAugmentedGeneration 类来集成上述两个模型,实现检索增强生成:


Python
from langchain.chains import RetrievalAugmentedGeneration
from langchain.vectorstores import FAISS
from langchain.document_loaders import TextLoader

# 初始化远端的 bge-embedding 嵌入模型
bge_embedding = RemoteBGEEmbedding(api_url="http://your-bge-embedding-server.com/embedding")

# 加载文档数据并创建向量存储
loader = TextLoader("path/to/your/data.txt") # 替换为你的文档路径
documents = loader.load()
vector_store = FAISS.from_documents(documents, bge_embedding)

# 初始化远端的 Qwen 生成模型
qwen_llm = RemoteQwenLLM(api_url="http://your-qwen-server.com/generate")

# 创建 RAG 管道
rag_chain = RetrievalAugmentedGeneration(
    llm=qwen_llm, # 使用远程 Qwen 模型
    retriever=vector_store.as_retriever(),
    input_key="input",
    output_key="output"
)


4.执行RAG应用


Python
# 测试 RAG 流程
query = "中国的历史发展是怎样的?"
result = rag_chain.run(query)
print(result)



3

调优和进阶技术



随着技术的发展,RAG系统经历了几个阶段的演变,包括Naive RAGAdvanced RAGModular RAGNaive RAG是最基本的RAG实现,它通常只涉及简单的检索和生成步骤,没有太多复杂的优化。Advanced RAGNaive RAG的基础上增加了更多的策略和优化,如索引优化、迭代检索和检索后处理,以提高系统的性能。Modular RAG则进一步发展,提供了更高的灵活性和可定制性,允许通过引入不同的模块和调整模块间的流程来适应各种复杂的任务和需求。在Modular RAG中,数据清洗、问题转换、多路召回和重排序和过滤等是一些有效的调优技术模块实现,下面是这些技术的介绍和说明。




1. 数据清洗


RAG中,数据清洗至关重要,直接关系到了检索召回的效果,常用的数据清洗手段有低质量数据知识增强和非结构化数据处理。

(1)低质量数据知识增强


一般来说,对称召回任务比非对称召回任务要简单,特别在很多垂直领域,向量模型对领域知识的理解有限,对称召回很多时候理解了字面意思就能满足要求。为了方便描述,下文把对称召回称为 QQQuery-Question)召回,把非对称召回称为QDQuery-Document)召回。


知识增强一般是指,根据上下文重新 Refine原始的文本使得原始的文本信息更完整,自解释性更强。这个过程由于是离线的一次性处理,所以这里可以借助能力更强的商用LLM模型,生成的内容可能会更好。另外由于现在的LLM能支撑的上下文context长度很长,建议在生成的过程中,在prompt中去融入一些该场景的丰富背景信息。具体过程如下图所示:


 

通过知识增强,可以把文本文档也转化成 FAQ的形式,使得对于一般的文档也能够同时进行QQQD召回。


(2)非结构化数据处理


在文档数据处理时,一些关键信息以非结构化数据,以下面的社保卡换领流程图为例


 

上面的关键信息为流程图,常用的文档解析方式无法处理,从而导致召回时无法检索到响应内容并回答,为了解决该问题,可通过LLM将流程图转markdown代码


Plain Text
graph TD 
    A[2019新版社保卡换领] --> B{分批换领} 
    B -->|2019年1月-2019年6月| C[退休人员换领] 
    B -->|2019年8月-2019年9月| D[中小幼人员换领] 
    B -->|2019年7月-2020年12月| E[在职人员换领] 

    C --> F[本人到银行(社区)网点申领] 
    F --> G[填写申请表并签字] 

    D --> H[登录上海社会保障卡服务中心网站] 
    D --> I[通过“上海社保卡”微信公众号/APP换领] 
    D --> J[在“上海社保”微信公众号后台办理] 

    E --> K[单位组织员工填写申请表] 
    K --> L[银行批量提交] 

    H --> M[注册并实名认证] 
    I --> M 
    J --> M 

    M --> N[输入申领信息] 
    N --> O[集中制卡] 
    O --> P[邮政快递邮寄] 
    P --> Q[到银行网点开通金融、社保功能]


在召回时将上面的markdown代码给到LLM即可完成流程图相关内容的问答。




2. 问题转换


问题转换 RAG系统中的一个重要步骤,尤其在面对复杂、多样化的用户问题时,能够对检索结果的质量产生深远影响。问题转换的核心思想是将用户输入的问题转化为适合检索的形式,以提高检索效率和准确性。常用方式有:


1.语义转换:很多用户提问时,可能会使用自然语言的表达,而这些表达未必最适合直接进行检索。问题转换模块通过分析问题的语义,将自然语言问题转换为适合关键词匹配或向量检索的形式。例如,将复杂问题分解为简单的子问题,或者提取出问题中的关键信息进行检索。


2.问题重构:对于多轮对话,问题转换模块可以结合之前的上下文,重构当前问题,使其在检索时更具连贯性。比如,如果当前问题是一个不完整的询问,问题转换模块会根据之前的对话历史补充必要的细节,以提升检索的精准度。


3.多模式转换:问题转换还可以针对不同类型的数据源(文本、图像、视频等)进行不同的处理。例如,针对多模态数据源的系统,问题转换模块需要将自然语言问题转化为对应模态的检索形式(如图像特征、视频片段等)。


 

以历史对话为例,通过输入用户与系统的多轮对话,目标是根据上下文重构问题,使其在检索时更具准确性。


对话上下文:


JSON
用户:请告诉我任务管理的最佳实践。
系统:任务管理的最佳实践包括任务优先级排序、时间管理、团队协作等。你是否想了解某个具体的方面?
用户:好的,关于任务优先级。


原始问题:


用户当前的问题是关于任务优先级。这是一个不完整的自然语言问题,在没有上下文的情况下,这个问题可能不明确,检索系统可能无法理解用户的具体需求。


问题重写提示词:


JSON
## 任务:根据用户和AI的历史对话内容进行总结。

## 要求:- 使用专业且简洁的语言。- 将用户当前的问题重新表述为一个清晰、简洁且自包含的查询,适合信息检索使用。- 如果当前问题已经足够清晰和完整,请保持原样输出。

## 示例:---### 历史信息:用户咨询了关于 Spring 动态 Bean 管理的技术问题,AI 提供了使用 ConcurrentHashMap 管理 Bean 的建议。### 当前问题:动态管理 Spring 的 Bean?### 总结:如何使用 ConcurrentHashMap 动态管理 Spring Bean?

## 历史信息:{{history_summary}}
## 当前问题:{{question}}


重写后问题:


JSON
“任务管理的最佳实践中,如何有效进行任务优先级排序?”


在多轮对话和复杂查询场景中,通过问题重写转换可以显著提升召回率。




3. 多路召回


多路召回(Multi-Channel Retrieval)是RAG系统中用于提升检索结果多样性和覆盖度的关键机制。通过使用不同的检索策略和通道,系统可以最大程度地覆盖问题相关的文档,确保生成的答案基于更全面的上下文信息。其中多路的概念可表示为对多个向量库进行检索,也可表示采用多种召回算法进行混合检索。



混合检索


向量检索和关键词检索在检索领域各有其优势。向量检索优势:复杂语义的文本查找,相近语义理解,多语言理解,多模态理解,容错性。传统关键词搜索优势:精确匹配,少量字符的匹配,倾向低频词汇的匹配。混合检索结合了向量检索和关键词检索的优势,通过多个检索系统的组合,实现了多个检索技术之间的互补。


1.倒排召回:倒排索引是一种经典的关键词匹配方式,主要应用于基于传统文本搜索的场景,如使用 BM25等方法。倒排召回速度快,适合处理精确匹配场景。它基于词项的出现频率和文档倒排索引进行匹配,在面对具体的术语或关键词查询时效果尤为显著。

2.向量召回:向量召回基于语义嵌入,通过将文档和查询转换为向量表示,并在向量空间中计算它们的相似度来进行检索。向量召回特别适合处理模糊、语义相关性较强的问题,能够在概念上找到更具相关性的文档,即使这些文档没有包含查询中的具体关键词。



4. 重排序和过滤


重排序在RAG过程中起着至关重要的作用。在简单的RAG方法中,可能会检索到大量上下文,但并非所有上下文都与问题相关。重新排序可以对文档进行重新排序和过滤,将相关文档放在最前面,从而提高RAG的效率。


(1)RRF多检索融合


RRFRanked Retrieval Fusion)是一种将多个检索系统的排名结果进行融合的方法,它能够综合不同检索方法的优点。将关键词检索(BM25等)和向量检索(基于嵌入的检索)结合在一起,可以提升检索的效果。RRF通常按照检索结果的排名进行分数计算,最终得出一个融合后的排名。


下面通过一个具体的检索结果例子展示关键词检索(BM25)和向量检索的结果如何结合RRF排序来得到最终的排序结果。


假设我们有以下五个文档D1~D5,并且进行两个不同的检索:


文档ID


关键词检索BM25)排名


向量检索(基于嵌入的语义相似度)排名


D1


3


1


D2


1


4


D3


5


2


D4


2


3


D5


4


5


根据RRF公式分别计算D1~D5文档得分,


 

其中,k 为常数,通常选择k = 60rank_i(d) 表示第 i种检索方法中文档d 的排名。


文档D10.03226


文档D20.03202


文档D40.03200


文档D30.03151


文档D50.03101


根据RRF分数排序,最终的文档排名为:


1.D1(分数:0.03226


2.D2(分数:0.03202


3.D4(分数:0.03200


4.D3(分数:0.03151


5.D5(分数:0.03101


(2)语义检索:相似相关



- EmbeddingBi-Encoder)双编码器


结构:Bi-Encoder使用两个独立的编码器来处理查询(query)和文档(document),分别生成它们的嵌入表示(embeddings)。


Embedding模型根据查询(query)和文档(document)给出相似度得分,但是这个得分描述的更多的是相似性。Embedding本质上是一个双编码器,两个文本在模型内部没有任何信息交互。只在最后计算两个向量的余弦相似度时才进行唯一一次交互。


- RerankCross-Encoder)交叉编码器


结构:Cross-Encoder将查询和文档拼接在一起,作为一个整体输入到一个单一的编码器中。


Rerank本质是一个Cross-Encoder的模型。Cross-Encoder能让两个文本片段一开始就在BERT模型各层中通过self-attention进行交互。


采用两阶段检索结合可以兼顾效果和效率:


第一个阶段的目标是尽可能多的召回相似的文本片段,这个阶段的文本得分排序不是特别靠谱,所以候选的 topK可以设置大一些,比如topK=10


第二个阶段的目标是对 10个粗排的候选文本片段进行重新排序,用cross-encoder计算10个候选文本和query的相关度得分。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅