在人工智能领域,检索增强生成(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**管道
使用 LangChain的RetrievalAugmentedGeneration 类来集成上述两个模型,实现检索增强生成:
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 RAG、Advanced RAG和Modular RAG。Naive RAG是最基本的RAG实现,它通常只涉及简单的检索和生成步骤,没有太多复杂的优化。Advanced RAG在Naive RAG的基础上增加了更多的策略和优化,如索引优化、迭代检索和检索后处理,以提高系统的性能。Modular RAG则进一步发展,提供了更高的灵活性和可定制性,允许通过引入不同的模块和调整模块间的流程来适应各种复杂的任务和需求。在Modular RAG中,数据清洗、问题转换、多路召回和重排序和过滤等是一些有效的调优技术模块实现,下面是这些技术的介绍和说明。
1. 数据清洗
在RAG中,数据清洗至关重要,直接关系到了检索召回的效果,常用的数据清洗手段有低质量数据知识增强和非结构化数据处理。
(1)低质量数据知识增强
一般来说,对称召回任务比非对称召回任务要简单,特别在很多垂直领域,向量模型对领域知识的理解有限,对称召回很多时候理解了字面意思就能满足要求。为了方便描述,下文把对称召回称为 QQ(Query-Question)召回,把非对称召回称为QD(Query-Document)召回。
知识增强一般是指,根据上下文重新 Refine原始的文本使得原始的文本信息更完整,自解释性更强。这个过程由于是离线的一次性处理,所以这里可以借助能力更强的商用LLM模型,生成的内容可能会更好。另外由于现在的LLM能支撑的上下文context长度很长,建议在生成的过程中,在prompt中去融入一些该场景的丰富背景信息。具体过程如下图所示:
通过知识增强,可以把文本文档也转化成 FAQ的形式,使得对于一般的文档也能够同时进行QQ和QD召回。
(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多检索融合
RRF(Ranked 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 = 60,rank_i(d) 表示第 i种检索方法中文档d 的排名。
•文档D1:0.03226
•文档D2:0.03202
•文档D4:0.03200
•文档D3:0.03151
•文档D5:0.03101
根据RRF分数排序,最终的文档排名为:
1.D1(分数:0.03226)
2.D2(分数:0.03202)
3.D4(分数:0.03200)
4.D3(分数:0.03151)
5.D5(分数:0.03101)
*(2)语义检索:相似**≠**相关*
- Embedding(Bi-Encoder)双编码器
•结构:Bi-Encoder使用两个独立的编码器来处理查询(query)和文档(document),分别生成它们的嵌入表示(embeddings)。
Embedding模型根据查询(query)和文档(document)给出相似度得分,但是这个得分描述的更多的是相似性。Embedding本质上是一个双编码器,两个文本在模型内部没有任何信息交互。只在最后计算两个向量的余弦相似度时才进行唯一一次交互。
- Rerank(Cross-Encoder)交叉编码器
•结构:Cross-Encoder将查询和文档拼接在一起,作为一个整体输入到一个单一的编码器中。
Rerank本质是一个Cross-Encoder的模型。Cross-Encoder能让两个文本片段一开始就在BERT模型各层中通过self-attention进行交互。
采用两阶段检索结合可以兼顾效果和效率:
•第一个阶段的目标是尽可能多的召回相似的文本片段,这个阶段的文本得分排序不是特别靠谱,所以候选的 topK可以设置大一些,比如topK=10;
•第二个阶段的目标是对 10个粗排的候选文本片段进行重新排序,用cross-encoder计算10个候选文本和query的相关度得分。
如何学习大模型 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 的正确特征了。