RAG快速开发实战

月伴飞鱼 2025-05-26 19:32:31
学习专栏 > AI相关
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

image-20250526193804770

选择RAG而不是直接将所有知识库数据交给大模型处理,主要是因为模型能够处理的Token数有限。

  • 输入过多Token会增加成本。

更重要的是,提供少量相关的关键信息能够带来更优质的回答。

image-20250526195416646

RAG标准技术流程

image-20250526195818930

RAG标准流程由索引(Indexing)、检索(Retriever)和生成(Generation)三个核心阶段组成:

索引阶段

通过处理多种来源多种格式的文档提取其中文本,将其切分为标准⻓度的文本块(chunk),并进行嵌入向量化(embedding)。

  • 向量存储在向量数据库(vectordatabase)中。

检索阶段

用户输入的查询(query)被转化为向量表示,通过相似度匹配从向量数据库中检索出最相关的文本块。

最后生成阶段

检索到的相关文本与原始查询共同构成提示词(Prompt),输入大语言模型(LLM),生成精确且具备上下文关联的回答。

索引是RAG系统的基础环节,包含四个关键步骤:

首先,将各类数据源及其格式(如书籍、教材、领域数据、企业文档等,txt、markdown、doc、ppt、excel、pdf、html、json等格式)统一解析为纯文本格式。

接着,根据文本的语义或文档结构,将文档分割为小而语义完整的文本块(chunks),确保系统能够高效检索和利用这些块中包含的信息。

然后,使用文本嵌入模型(embeddingmodel),将这些文本块向量化,生成高维稠密向量,转换为计算机可理解的语义表示。

最后,将这些向量存储在向量数据库(vectordatabase)中,并构建索引,完成知识库的构建。

这一流程成功将外部文档转化为可检索的向量,支撑后续的检索和生成环节。

检索是连接用户查询与知识库的核心环节

首先,用户输入的问题通过同样的文本嵌入模型转换为向量表示,将查询映射到与知识库内容相同的向量空间中。

通过相似度度量方法,检索模块从向量数据库中筛选出与查询最相关的前K个文本块,这些文本块将作为生成阶段输入的一部分。

通过相似性搜索,检索模块有效获取了与用户查询切实相关的外部知识,为生成阶段提供了精确且有意义的上下文支持。

生成是RAG流程中的最终环节

将检索到的相关文本块与用户的原始查询整合为增强提示词(Prompt),并输入到大语言模型(LLM)中。

LLM基于这些输入生成最终的回答,确保生成内容既符合用户的查询意图,又充分利用了检索到的上下文信息。

  • 使得回答更加准确和相关,充分使用到知识库中的知识。

通过这一过程,RAG实现了具备领域知识和私有信息的精确内容生成。

RAG与微调的选择

RAG更适用于需要动态响应、频繁更新外部知识的场景,而微调则适合固定领域内的深度优化与推理。

当应用场景中既需要利用最新的外部知识,又需要保持高水平的领域推理能力时,可以考虑结合使用RAG和微调。

从0到1搭建RAG应用

技术框架与选型

技术框架:LangChain

LangChain是专为开发基于大型语言模型(LLM)应用而设计的全面框架。

其核心目标是简化开发者的构建流程,使其能够高效创建LLM驱动的应用。

索引流程-文档解析模块:pypdf

pypdf是一个开源的Python库,专⻔用于处理PDF文档。

pypdf支持PDF文档的创建、读取、编辑和转换操作,能够有效提取和处理文本、图像及⻚面内容。

索引流程-文档分块模块:RecursiveCharacterTextSplitter

采用LangChain默认的文本分割器-RecursiveCharacterTextSplitter。

该分割器通过层次化的分隔符(从双换行符到单字符)拆分文本,旨在保持文本的结构和连贯性,优先考虑自然边界如段落和句子。

索引/检索流程-向量化模型:bge-small-zh-v1.5

bge-small-zh-v1.5是由北京人工智能研究院(BAAI,智源)开发的开源向量模型。

虽然模型体积较小,但仍然能够提供高精度和高效的中文向量检索。

  • 该模型的向量维度为512,最大输入⻓度同样为512。

索引/检索流程-向量库:Faiss

Faiss全称Facebook AI Similarity Search,由Facebook AI Research团队开源的向量库。

因其稳定性和高效性在向量检索领域广受欢迎。

生成流程-大语言模型:通义千问 Qwen

通义千问Qwen是阿里云推出的一款超大规模语言模型,支持多轮对话、文案创作、逻辑推理、多模态理解以及多语言处理。

在模型性能和工程应用中表现出色。

  • 采用云端API服务,注册有1,000,000token的免费额度。

上述选型在RAG流程图中的应用如下所示:

image-20250526205137422

LangChain提供用于构建LLM RAG的应用程序框架。

索引流程:使用pypdf对文档进行解析并提取信息。

随后,采用RecursiveCharacterTextSplitter对文档内容进行分块(chunks)。

最后,利用bge-small-zh-v1.5将分块内容进行向量化处理,并将生成的向量存储在Faiss向量库中。

检索流程:使用bge-small-zh-v1.5对用户的查询(Query)进行向量化处理。

然后,通过Faiss向量库对查询向量和文本块向量进行相似度匹配,从而检索出与用户查询最相似的前top-k个文本块(chunk)。

生成流程:

通过设定提示模板(Prompt),将用户的查询与检索到的参考文本块组合输入到Qwen大模型中,生成最终的 RAG 回答。

案例代码:https://gitee.com/techleadcy/rag_app

文档解析技术

LangChain Document Loaders文档加载器

LangChain提供了一套功能强大的文档加载器(Document Loaders),帮助开发者轻松地将数据源中的内容加载为文档对象。

LangChain定义了BaseLoader类和Document类,其中BaseLoader类负责定义如何从不同数据源加载文档。

  • 而 Document类则统一描述了不同文档类型的元数据。

分块策略与Embedding技术

文档数据(Documents)经过解析后,通过分块技术将信息内容划分为适当大小的文档片段(chunks)。

  • 从而使RAG系统能够高效处理和精准检索这些片段信息。

分块的本质在于依据一定逻辑或语义原则,将较⻓文本拆解为更小的单元。

嵌入模型(Embedding Model):

负责将文本数据映射到高维向量空间中,将输入的文档片段转换为对应的嵌入向量(embeddingvectors)。

  • 这些向量捕捉了文本的语义信息,并被存储在向量库(VectorStore)中,以便后续检索使用。

用户查询(Query)同样通过嵌入模型的处理生成查询嵌入向量。

  • 这些向量用于在向量数据库中通过向量检索(Vector Retrieval)匹配最相似的文档片段。

根据不同的场景需求,评估并选择最优的嵌入模型,以确保RAG的检索性能符合要求。

image-20250527100501183

分块策略

分块策略最大的挑战在于确定分块的大小。

  • 如果片段过大,可能导致向量无法精确捕捉内容的特定细节并且计算成本增加。

  • 若片段过小,则可能丢失上下文信息,导致句子碎片化和语义不连贯。

较小的块适用于需要细粒度分析的任务,例如情感分析,能够精确捕捉特定短语或句子的细节。

更大的块则更为合适需要保留更广泛上下文的场景,例如文档摘要或主题检测。

因此,块大小的确定必须在计算效率和上下文信息之间取得平衡。

多种分块策略从本质上来看,由以下三个关键组成部分构成:

大小:每个文档块所允许的最大字符数。

重叠:在相邻数据块之间,重叠字符的数量。

拆分:通过段落边界、分隔符、标记,或语义边界来确定块边界的位置。

上述三个组成部分共同决定了分块策略的特性及其适用场景:

基于这些组成部分,常⻅的分块策略包括:

  • 固定大小分块(Fixed Size Chunking)、重叠分块(Overlap Chunking)

  • 递归分块(Recursive Chunking)、文档特定分块(Document Specific Chunking)

  • 语义分块(Semantic Chunking)、混合分块(Mix Chunking)

image-20250527101116620

固定大小分块(Fixed Size Chunking)

最基本的方法是将文档按固定大小进行分块,通常作为分块策略的基准线使用。

Chunk切分可视化呈现链接:https://chunkviz.up.railway.app/

重叠分块(Overlap Chunking)

通过滑动窗口技术切分文本块,使新文本块与前一个块的内容部分重叠,从而保留块边界处的重要上下文信息。

  • 增强系统的语义相关性。

虽然这种方法增加了存储需求和冗余信息,但它有效避免了在块之间丢失关键语义或句法结构。

递归分块(Recursive Chunking)

通过预定义的文本分隔符(如换行符\n\n、\n,句号、逗号、感叹号、空格等)迭代地将文本分解为更小的块。

  • 以实现段大小的均匀性和语义完整性。

此过程中,文本首先按较大的逻辑单元分割(如段落\n\n),然后逐步递归到较小单元(如句子\n和单词)。

  • 确保在分块大小限制内保留最强的语义片段。

文档特定分块(Document Specific Chunking)

根据文档的格式(如Markdown、Latex、或编程语言如Python等)进行定制化分割的技术。

此方法依据文档的特定格式和结构规则。

  • 例如Markdown的标题、列表项,或Python代码中的函数和类定义等,来确定分块边界。

通过这种方式,确保分块能够准确反映文档的格式特点,优化保留这些语义完整的单元,提升后续的处理和分析效果。

语义分块(Semantic Chunking)

基于文本的自然语言边界(如句子、段落或主题中断)进行分段的技术,需要使用NLP技术根据语义分词分句。

  • 旨在确保每个分块都包含语义连贯的信息单元。

语义分块保留了较高的上下文保留,并确保每个块都包含连贯的信息,但需要更多的计算资源。

常用的分块策略有spaCy和 NLTK 的NLP库,spaCy适用于需要高效、精准语义切分的大规模文本处理。

  • NLTK更适合教学、研究和需要灵活自定义的语义切分任务。

混合分块(Mix Chunking)

混合分块是一种结合多种分块方法的技术,通过综合利用不同分块技术的优势,提高分块的精准性和效率。

  • 例如,在初始阶段使用固定⻓度分块快速整理大量文档,而在后续阶段使用语义分块进行更精细的分类和主题提取。

根据实际业务场景,设计多种分块策略的混合,能够灵活适应各种需求,提供更强大的分块方案。

Embedding嵌入

指将文本、图像、音频、视频等形式的信息映射为高维空间中的密集向量表示。

  • 这些向量在语义空间中起到坐标的作用,捕捉对象之间的语义关系和隐含的意义。

通过在向量空间中进行计算(例如余弦相似度),可以量化和衡量这些对象之间的语义相似性。

Embedding Model嵌入模型

在 RAG 系统中,Embedding Model嵌入模型扮演着关键⻆色,负责将文本数据映射到高维向量空间,以便高效检索和处理。

具体而言,Embedding Model将输入的文档片段(Chunks)和查询文本(Query)转换为嵌入向量(Vectors)。

  • 这些向量捕捉了文本的语义信息,并可在向量空间中与其他嵌入向量进行比较。

在 RAG 流程中,文档首先被分割成多个片段,每个片段随后通过 Embedding Model进行嵌入处理。

生成的文档嵌入向量被存储在VectorStore中,供后续检索使用。

用户查询会通过 EmbeddingModel转换为查询嵌入向量,这些向量用于在向量数据库中匹配最相似的文档片段。

  • 最终组合生成指令(Prompt),大模型生成回答。

向量数据库

为什么需要向量数据库?

如果你的目标是了解书籍之间的推荐关系,或者探索作者之间的合作网络,图数据库可以高效存储和查询这些复杂的关系数据。

最后,如果你希望找到与某本书内容相似的书籍,比如基于主题、⻛格等特征进行相似性搜索。

  • 向量数据库则能够通过计算书籍内容语义在向量空间中的距离,为你提供语义最相关的数据信息。

向量数据库的核心在于其能够基于向量之间的相似性,快速、精确地定位和检索数据。

向量数据库是如何工作的?

向量数据库是一种专⻔用于存储和检索多维向量的数据库类型,与传统的基于行列结构的数据库不同。

  • 它主要处理高维空间中的数据点。

传统数据库通常处理字符串、数字等标量数据,并通过精确匹配来查询数据。

然而,向量数据库的操作逻辑则是基于相似性搜索。

  • 即在查询时,应用特定的相似性度量(如余弦相似度、欧几里得距离等)来查找与查询向量最相似的向量。

向量数据库的核心在于其高效的索引和搜索机制:

为了优化查询性能,它采用了如哈希、量化和基于图形的多种算法。

这些算法通过构建如层次化可导航小世界(HNSW)图、产品量化(PQ)和位置敏感哈希(LSH)等索引结构。

  • 显著提升了查询速度。

这种搜索过程并非追求绝对精确,而是通过近似最近邻(ANN)算法在速度与准确性之间进行权衡,从而实现快速响应。

向量数据库的索引结构可以理解为一种预处理步骤:

类似于为图书馆中的书籍编制索引,方便快速找到所需内容。

HNSW图通过在多层结构中将相似向量连接在一起,快速缩小搜索范围。

PQ则通过压缩高维向量,减少内存占用并加速检索,而LSH则通过哈希函数将相似向量聚集在一起,便于快速定位。

向量数据库的搜索机制不是追求精确匹配:

而是通过近似最近邻(ANN)算法在速度与准确性之间找到最佳平衡。

ANN算法通过允许一定程度的误差,在显著提高搜索速度的同时,依然能够找到与查询相似度较高的向量。

  • 这种策略对于需要实时、高精度响应的应用场景尤为重要。

向量数据库的工作流程涵盖了从数据处理、向量化、向量存储、向量索引到最终检索的全链条操作。

确保在复杂的数据环境中实现高效的存储、索引和相似性搜索。

具体流程如下:

数据处理与向量化原始数据首先被处理并转化为向量嵌入

  • 这一步通过嵌入模型实现,模型利用深度学习算法提取数据的语义特征,生成适合后续处理的高维向量表示。

向量存储转化后的向量嵌入存储在数据库中。

这一环节确保数据在高效检索的同时,能够以优化的方式管理和维护存储资源,以适应不同规模和复杂度的应用需求。

向量索引存储的向量嵌入需要经过索引处理,以便在后续查询中快速定位相关数据。

索引过程通过构建特定的结构,使得数据库能够在大规模数据集上实现高效的查询响应。

向量搜索在接收到查询后,数据库通过已建立的索引结构执行相似性搜索,找出与查询向量最为接近的数据点。

这一阶段的重点在于平衡搜索的速度与准确性,确保在大数据环境下提供快速且相关的查询结果。

  • 常⻅的向量搜索方法包括余弦相似度、欧几里得距离和曼哈顿距离。

其中,余弦相似度主要用于文本处理和信息检索,关注向量之间的⻆度,以捕捉语义相似性。

  • 欧几里得距离则测量向量之间的实际距离,适用于密集特征集的聚类或分类。

  • 而曼哈顿距离则通过计算笛卡尔坐标中的绝对差值之和,适用于稀疏数据的处理。

数据检索最后,数据库从匹配的向量中检索出对应的原始数据,并根据特定的需求进行必要的后处理。

这一步骤确保最终结果能够准确反映用户的查询意图,并提供有意义的输出。

常用向量数据库

对于需要快速开发和轻量化部署的项目,Chroma、Qdrant是不错的选择。

而对于追求高性能和可扩展性的企业级应用,可以考虑 Milvus/Zilliz。

FAISS 是适合对性能有极致要求、不要求持久化和数据管理的场景。

Weaviate、LanceDB 在处理多模态数据方面表现突出,适用于需要管理多种数据类型(如图像、文本、音频等)的 AI 应用。

如果需要无缝集成现有数据库并进行向量搜索,PGVector、Elasticsearch、Redis是理想的方案。

而不希望管理基础设施的用户则可以选择 Pinecone这样的全托管服务。

RAG检索

当前主流的 RAG 检索方式主要采用向量检索(VectorSearch),通过语义相似度来匹配文本切块。

混合检索(Hybrid Search)

通过结合关键词检索和语义匹配的优势,可以首先利用关键词检索精确定位到订单12345的信息。

  • 然后通过语义匹配扩展与该订单相关的其他上下文或客户操作的信息,例如12开头的订单、包装破损严重等。

这样不仅能够获取精确的订单详情,还能获得与之相关的额外有用信息。

索到的结果还需要经过优化排序:

重排序(Reranking)的目的是将混合检索的结果进行整合,并将与用户问题语义最契合的结果排在前列。

混合检索(多路召回)

混合检索,又称融合检索/多路召回,是指在检索过程中同时采用多种检索方式,并将各类检索结果进行融合。

  • 从而得到最终的检索结果。

混合检索的优势在于能够充分利用不同检索方式的优点,弥补各自的不足,从而提升检索的准确性和效率。

为什么要使用重排序技术?

尽管向量检索技术能够为每个文档块生成初步的相关性分数,但引入重排序模型仍然至关重要。

向量检索主要依赖于全局语义相似性,通过将查询和文档映射到高维语义空间中进行匹配。

  • 然而,这种方法往往忽略了查询与文档具体内容之间的细粒度交互。

重排序模型大多是基于双塔或交叉编码架构的模型:

在此基础上进一步计算更精确的相关性分数,能够捕捉查询词与文档块之间更细致的相关性,从而在细节层面上提高检索精度。

因此,尽管向量检索提供了有效的初步筛选,重排序模型则通过更深入的分析和排序。

  • 确保最终结果在语义和内容层面上更紧密地契合查询意图,实现了检索质量的提升。

重排序模型RerankingModel

RAG流程有两个概念,粗排和精排。粗排检索效率较快,但是召回的内容并不一定强相关。

而精排效率较低,因此适合在粗排的基础上进行进一步优化。

  • 精排的代表就是重排序(Reranking)。

重排序模型(Reranking Model)查询与每个文档块计算对应的相关性分数,并根据这些分数对文档进行重新排序。

  • 确保文档按照从最相关到最不相关的顺序排列,并返回前top-k个结果。
image-20250527110107426

RAG生成

经过RAG索引流程外部知识的解析及向量化,RAG检索流程语义相似性的匹配及混合检索,系统进入RAG生成流程。

生成流程中,首先需要组合指令,指令将携带查询问题及检索到的相关信息输入到大模型中。

  • 由大模型理解并生成最终的回复,从而完成整个应用过程。

大模型原理

与传统的循环神经网络(RNN)相比,Transformer模型不依赖于序列顺序。

  • 而是通过自注意力(Self-Attention)机制来捕捉序列中各元素之间的关系。

Transformer由多个堆叠的编码层(Encoder)和解码层(Decoder)组成,每一层包括自注意力层、前馈层和归一化层。

  • 这些层协同工作,逐步捕捉输入数据信息特征,从而预测输出,实现强大的语言理解和生成能力

Transformer模型的核心创新在于位置编码和自注意力机制:

位置编码帮助模型理解输入数据的顺序信息,而自注意力机制则允许模型根据输入的全局上下文。

  • 为每个词元分配不同的注意力权重,从而更准确地理解词与词之间的关联性。

这种机制使得Transformer特别适用于语言模型。

  • 因为语言模型需要精确捕捉上下文中的细微差别,生成符合语义逻辑的文本。
image-20250527111022205

上图展示了Transformer模型的架构及其核心机制的可视化示例。

左图中,Transformer模型由编码器和解码器两部分组成。

编码器负责理解输入信息的顺序和语义,解码器则输出概率最高的词元。

右上图中的示例显示了输入句子中的填空任务。

  • 解码器依据输入句子的特征和已生成的部分句子,生成了She作为模型的预测结果。

生成She的核心原因在于右下图所示的注意力机制。

其中需要填空的部分对输入句子中的词元The Doctor和Nurse分配了较高的注意力权重。

  • 从而提高了She作为输出词元的生成概率。

基于Transformer模型通过预测下一个词元的原理:

大语言模型在分析了海量的语料库后,能够在逻辑上精准补全不完整的句子,甚至生成新的句子。

这一推理模式赋予了大语言模型生成连贯且上下文相关文本的能力。

  • 使其在文本生成、翻译、问答系统等多个领域得到广泛应用。

RAG中如何选择大模型?

需要关注的是SuperCLUE-RAG 检索增强生成测评,在RAG场景中,大模型的检索能力表现是核心。

https://www.superclueai.com/

RAG效果提升

数据清洗和预处理

在RAG索引流程中,文档解析之后、文本块切分之前,进行数据清洗和预处理能够有效减少脏数据和噪声。

  • 提升文本的整体质量和信息密度。

通过清除冗余信息、统一格式、处理异常字符等手段,数据清洗和预处理过程确保文档更加规范和高质量。

  • 从而提高RAG系统的检索效果和信息准确性。

处理冗余的模板内容:

在企业内部文档中,特别是合同或报告等类型的文档,通常会出现大量的重复段落。

  • 例如多个合同中包含相同的法律条款或说明性文字。

这类重复内容会增加向量数据库的存储负担,并影响检索效率。

通过去除冗余内容,能够减少不必要的干扰,提升检索速度和相关性。

消除文档中的额外空白和格式不一致:

文档中可能存在多余的空行、缩进或其他格式不一致的情况。

  • 这些多余的空白和格式会影响文本块的切分和向量化过程。

通过清理这些格式化问题,能够确保文本块的划分更加精准,减少分块过程中的误差。

去除文档脚注、⻚眉⻚脚、版权信息:

在文档解析时,可能会从网⻚或PDF中提取出脚注、版权声明、⻚眉⻚脚等无关信息。

这些内容会增加数据的噪声,影响向量生成的精度。

  • 去除这些无关的⻚脚和版权信息,有助于提升文本块的语义密度。

查询扩展

在RAG系统的典型检索步骤中,用户的查询会转化为向量后进行检索,但单个向量查询只能覆盖向量空间中的一个有限区域。

  • 如果查询中的嵌入向量未能包含所有关键信息,那么检索到的文档块可能不相关或缺乏必要的上下文。

因此,单点查询的局限性会限制系统在庞大文档库中的搜索范围,导致错失与查询语义相关的内容。

查询扩展策略:

通过大模型从原始查询语句生成多个语义相关的查询,可以覆盖向量空间中的不同区域,从而提高检索的全面性和准确性。

这些查询在嵌入后能够击中不同的语义区域,确保系统能够从更广泛的文档中检索到与用户需求相关的有用信息

通过这种查询扩展策略,原始问题被分解为多个子查询,每个子查询独立检索相关文档并生成相应的结果。

  • 随后,系统将所有子查询的检索结果进行合并和重新排序。

此方法能够有效扩展用户的查询意图,确保在复杂信息库中进行更全面的文档检索。

  • 从而避免遗漏与查询语义密切相关的重要内容。

自查询

在将用户查询转化为向量的过程中,无法确保查询中的所有关键信息都被充分捕捉到向量中。

例如,若希望检索结果依赖于查询中的标签,直接通过嵌入向量进行检索并不能确保这些标签在向量表示中被完整表达。

  • 或者在与其他向量的距离计算中占有足够的权重。

这种不足可能会导致检索结果缺乏相关性和准确性。

自查询策略:

通过大语言模型自动提取查询中对业务场景至关重要的元数据字段(如标签、作者ID、评论数量等关键信息)。

  • 并将这些信息结合到嵌入检索过程中。

通过这种方式,可以确保嵌入向量中包含这些关键信息,从而提高检索的全面性与精确性。

通过这种自查询策略,系统能够精准提取查询中的关键信息,结合关键词检索及向量检索。

确保这些元数据在向量检索中得以充分利用,从而提高检索结果的相关性和准确性。

提示压缩

提示压缩旨在减少上下文中的噪声,并突出最相关的信息,从而提高检索精度和生成质量。

在RAG系统中,检索到的文档通常包含大量无关的文本,这些无关内容可能会掩盖与查询高度相关的信息。

  • 导致生成结果的相关性下降。

提示压缩通过精简上下文、过滤掉不相关的信息,确保系统只处理与查询最相关、最重要的内容。

通过提示压缩,系统能够准确提取出与查询高度相关的核心信息,去除冗余内容,并返回简洁的压缩结果。

组合成为新的指令,输入大模型获得回复,提高RAG系统答案准确度。

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!