# RAG_code **Repository Path**: km601/rag_code ## Basic Information - **Project Name**: RAG_code - **Description**: 欢迎来到当今最全面和最动态的检索增强生成(RAG)教程集合之一。此存储库充当旨在提高RAG系统的准确性、效率和上下文丰富性的尖端技术的中心。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-08-03 - **Last Updated**: 2025-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RAG技术锦囊妙计:提升您的检索-增强生成系统🚀 欢迎来到当今最全面和最动态的检索增强生成(RAG)教程集合之一。此存储库充当旨在提高RAG系统的准确性、效率和上下文丰富性的尖端技术的中心。 ## 一、前言 检索增强生成(RAG)正在彻底改变我们将信息检索与生成人工智能相结合的方式。此存储库展示了精心策划的高级技术集合,旨在增强您的RAG系统,使它们能够提供更准确、上下文相关和全面的响应。 我们的目标是为初学者和实践者提供一个有价值的资源,以突破RAG的极限。通过营造合作环境,我们的目标是加速这一令人兴奋的领域的创新。 ## 二、关键技术 - 🧠最先进的RAG增强功能 - 📚每种技术的综合文档 - 推荐️实用的实现指南 - 🌟定期更新最新进展
方法 策略 思路 效果
Simple RAG 基本的RAG技术 从 PDF 文档中提取文本,将其分割成小块(chunks),将这些文本块转换为数值化的嵌入向量(embeddings),根据查询(query)搜索最相关的文本块,最后利用检索到的文本块生成回答。 0.48
Semantic Chunking 分块策略 根据文本的语义来划分,将语义相关的句子组合在一起形成文本块。 0.46
Query Transformations Query Transformations 修改和扩展用户查询以提高检索效率 0.5
HyDE Query Transformations 生成假设问题以改进查询和数据之间的一致性 0.5
Context Enrichment Context and Content Enrichment 检索最相关的句子,同时访问原文中前后的句子。 0.6
Contextual Chunk Headers Context and Content Enrichment 上下文块头(CCH)是一种创建文档级和节级上下文的方法,并在嵌入块之前将这些块头添加到块中。 0.5
Document Augmentation Context and Content Enrichment 使用LLM来扩展文本数据集,其中包含可以向每个文档提出的所有相关的问题,并将这些问题也转换为嵌入向量。 0.8
Relevant Segment Extraction Context and Content Enrichment 使执行检索后处理步骤,分析最相关的块并识别较长的多块段,以便为LLM提供更完整的上下文。 0.8
Contextual Compression Context and Content Enrichment 使用LLM压缩或汇总检索到的块,保留与查询相关的关键信息 0.75
Fusion Retrieval Advanced Retrieval 结合了向量检索和关键词检索两种方法,取两者的优点,为检索结果提供更全面的语义信息和精确的关键词匹配 0.83
Intelligent Reranking Advanced Retrieval 通过一个额外的步骤对检索结果进行重新排序,将最相关的文本块放在最前面 0.7
Hierarchical Indices Advanced Retrieval 为有效的信息导航和检索创建一个多层次的系统 0.84
Multi-model RAG with Multimedia Captioning Multi-modal Retrieval 为了响应自然语言查询,实现从多模态文档(带有文本和图像的pdf)高效查询和内容生成 0.79
Retrieval with Feedback Loops Iterative and Adaptive 实现从用户交互中学习和改进未来检索的机制 0.7
Adaptive Retrieval Iterative and Adaptive 根据查询类型和用户上下文动态调整检索策略 0.86
Knowledge Graph Integration Graph RAG 将文档中的信息构建成一个知识图谱,其中节点代表概念、实体或信息片段,边代表这些节点之间的关系 0.78
Self RAG Advanced Architectures 不仅能够检索和生成回答,还能够自我反思,判断是否需要检索,以及如何利用检索到的信息。 0.65
Corrective RAG Advanced Architectures 纠正性 RAG(Corrective RAG,CRAG) 在检索之后,对检索到的信息进行评估,根据评估结果动态调整检索策略。 0.824
## 三、RAG技术 探索先进的RAG技术的广泛列表: ### 3.1 🌱基本的RAG技术 #### 3.1.1 Simple RAG 🌱:基础而不失经典 ![](img/微信截图_20250417084007.png) - 实现方式 - [python 实现](https://articles.zsxq.com/id_elhcdgj7eqcg.html) - [LangChain 实现](https://articles.zsxq.com/id_8lm3mf7rzfxr.html) - 概述🔎 - 在探索各种复杂的 RAG 技术之前,我们先从最简单的 RAG 方法说起。 - 实现🛠️ - 从 PDF 文档中提取文本,将其分割成小块(chunks),将这些文本块转换为数值化的嵌入向量(embeddings),根据查询(query)搜索最相关的文本块,最后利用检索到的文本块生成回答。 - 代码实现: ```s # 定义 PDF 文件路径 pdf_path = "data/AI_information.pdf" # 提取文本并分割成文本块 extracted_text = extract_text_from_pdf(pdf_path) text_chunks = chunk_text(extracted_text, chunk_size=1000, overlap=200) # 打印文本块数量 print("Number of text chunks:", len(text_chunks)) ``` - 优点: 实现简单、计算开销小,非常适合作为基线对比。 - 缺点: 当查询涉及复杂语境或需要多轮推理时,直接拼接的信息可能不够充分,容易遗漏细节。这种方法虽然能迅速响应,但在准确性上通常无法与更高级的技术相比。 #### 3.1.2 Reliable RAG 🏷️ - 实现方式 - python 实现 - [LangChain 实现](https://articles.zsxq.com/id_o3305ie2eiq9.html) - 概述🔎 - 通过添加验证和细化来增强Simple RAG,以确保检索信息的准确性和相关性。 - 实现🛠️ - 检查检索到的文档的相关性,并突出显示用于回答的文档片段。 ### 3.2 分块策略📏 #### 3.2.1 Choose Chunk Size 📏 - 实现方式 - [python 实现](https://articles.zsxq.com/id_ukj8wox9clx6.html) - LangChain - 概述🔎 - 为文本块选择合适的固定大小,以平衡上下文保存和检索效率。 - 实现🛠️ - 使用不同的块大小进行实验,以在保留上下文和维护特定用例的检索速度之间找到最佳平衡。 #### 3.2.2 Proposition Chunking ⛓️‍💥 - 实现方式 - [python实战](https://articles.zsxq.com/id_maghltglqmlc.html) - [LangChain实现](https://articles.zsxq.com/id_mlt7rsrwgfef.html) - 概述🔎 - 将文本分解成简洁、完整、有意义的句子,以便更好地控制和处理特定的查询(特别是提取知识)。 - 实现🛠️ - 💪命题生成:LLM与自定义提示一起使用,从文档块中生成事实陈述。 - ✅质量检查:生成的命题通过一个评估准确性、清晰度、完整性和简洁性的分级系统。 #### 3.2.3 语义切分(Semantic Chunking) 🧠:让文本块更有意义 ![](img/微信截图_20250417084246.png) - 实现方式 - [python实现](https://articles.zsxq.com/id_quxt7u1ek8p6.html) - [LangChain实现](https://articles.zsxq.com/id_7el92apff5ti.html) - 概述🔎 - 为了**解决简单 RAG 中文本块分割不够合理的问题**,语义分块(Semantic Chunking)应运而生。 - 实现🛠️ - 与简单 RAG 不同,语义分块不再是按照固定大小来分割文本,而是尝试根据文本的语义来划分,将语义相关的句子组合在一起形成文本块。 - 代码实现: ```s # 将提取的文本分割成句子 sentences = extracted_text.split(". ") # 为每个句子生成嵌入向量 embeddings = [get_embedding(sentence) for sentence in sentences] # 计算连续句子之间的相似度 similarities = [cosine_similarity(embeddings[i], embeddings[i + 1]) for i in range(len(embeddings) - 1)] # 使用百分位法计算断点 breakpoints = compute_breakpoints(similarities, method="percentile", threshold=90) # 根据断点将句子分组成语义块 text_chunks = split_into_chunks(sentences, breakpoints) ``` - 优点: 提高了检索系统在定位相关信息时的精度,有助于生成模型快速锁定问题核心。 - 缺点: 分块策略需要根据文档类型进行调优,不同文档结构下可能需要不同的处理方式。 - 性能:**语义分块的评分甚至低于简单 RAG,这说明仅仅改变文本块的分割策略,并不能保证检索效果的提升。这也提醒我们,技术的改进并非一蹴而就,需要更多的思考和尝试**。 ### 3.3 Query Transformations 🔄 #### 3.3.1 查询转换(Query Transformation):让查询更“友好”⛓️‍💥 ![](img/微信截图_20250417140659.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略。然而,我们忽略了一个重要的因素:**用户提出的查询可能并不总是能够很好地匹配文档中的内容,这可能会导致检索结果不准确**。那么,有没有一种方法能够让查询更“友好”,更容易被检索到呢? - 实现方式 - [python](https://articles.zsxq.com/id_m8kkelawkw11.html) - LangChain - [✍️查询重写(Query Rewriting)](https://articles.zsxq.com/id_e2c1fck5v641.html) - [🔙后退提示(Step-back Prompting)](https://articles.zsxq.com/id_re49w5bxe13b.html) - [⛓️子查询分解(Sub-query Decomposition)](https://articles.zsxq.com/id_6v3f29ttc3hc.html) - 概述🔎 - 修改和扩展用户查询以提高检索效率。 - 实现🛠️ - ✍️查询重写(Query Rewriting):重新制定查询以改进检索。 - 🔙后退提示(Step-back Prompting):生成更广泛的查询,以获得更好的上下文检索。 - ⛓️子查询分解(Sub-query Decomposition):将复杂查询分解为更简单的子查询。 - 代码实现: ```s # 查询重写 rewritten_query = rewrite_query(query) # 后退提示 step_back_query = generate_step_back_query(query) # 子查询分解 sub_queries = decompose_query(query, num_subqueries=4) ``` - 优点: 能够捕捉到查询中的隐含意图,降低因表述差异导致的匹配错误。 - 缺点: 需要确保转换后的查询与原意保持一致,防止出现语义偏差。 - 效果:经过测试,查询转换的评分达到了 0.5。虽然这个分数并不高,但它仍然表明查询转换技术在某些情况下能够提高检索的准确性。这也提醒我们,在 RAG 系统中,不仅需要关注文本块的表示和检索策略,还需要关注查询的质量。 #### 3.3.2 Hypothetical Questions (HyDE Approach) ❓ ![](img/微信截图_20250422084139.png) - 动机:之前主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思,以及如何构建知识图谱,以及如何平衡上下文信息和检索精确性。然而,我们忽略了一个重要的问题:如何更好地表示查询,以便更准确地检索到相关信息呢? - 实现方式 - [python](https://articles.zsxq.com/id_h77w3wzjxenr.html) - [LangChain](https://articles.zsxq.com/id_5dwbwqarisj9.html) - 概述🔎 - 型首先生成一个初步的假设答案,然后以该答案为查询条件重新检索相关文档,最终融合两者信息。 - 实现🛠️ - 创建指向数据中相关位置的假设性问题,从而增强查询-数据匹配。即先生成一个假设文档,这个文档是查询的理想答案。然后,系统对这个假设文档进行嵌入,并利用这个嵌入进行检索。 - 性能:这种方法能够更好地捕捉查询的语义信息,从而提高检索的准确性。经过测试,HyDE 的评分达到了 0.5。虽然这个分数并不高,但它仍然表明 HyDE 技术在某些情况下能够提高检索的准确性。这也说明,从假设文档出发是一个非常有趣的思路,能够帮助我们更好地表示查询。 - 优点: 能弥补直接检索过程中可能遗漏的隐性信息,生成更加全面的答案。 - 缺点: 需要设计合理的假设生成和融合机制,否则可能引入噪声信息。 ### 3.4 📚 Context and Content Enrichment #### 3.4.1 Hypothetical Prompt Embeddings (HyPE) ❓🚀 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_030v5t3jv21v.html) - 概述🔎 - HyPE(假设提示嵌入)是对传统RAG检索的增强,它在索引阶段预先计算假设提示,但在它们的位置插入数据块。这将检索转换为问题-问题匹配任务。这避免了对运行时合成答案生成的需要,减少了推理时间的计算开销,同时改进了检索一致性。 - 实现🛠️ - 📖预先计算的问题:HyPE没有嵌入文档块,而是在索引时为每个块生成多个假设查询。 - 🔍问题-问题匹配:用户查询与存储的假设问题进行匹配,从而实现更好的检索对齐。 - ⚡没有运行时开销:与HyDE不同,HyPE在查询时不需要LLM调用,使检索更快、更便宜。 - 📈更高的精度和召回率:提高检索上下文精度高达42个百分点,索赔召回率高达45个百分点。 #### 3.4.2 上下文增强检索(Context Enriched Retrieval) 📝:邻居也能提供帮助 ![](img/微信截图_20250417084607.png) - 动机:既然语义分块没有达到预期的效果,我们不妨换个思路。简单 RAG 的问题在于文本块过于孤立,缺乏上下文信息。那么,如果我们能够为每个文本块添加一些上下文信息,是不是就能提高检索的准确性呢? - 实现方式 - [python](https://articles.zsxq.com/id_1dij2vdrbeic.html) - [LangChain](https://articles.zsxq.com/id_vertr3h6jlgw.html) - 概述🔎 - 通过嵌入单个句子和将上下文扩展到相邻句子来提高检索精度。 - 实现🛠️ - 检索最相关的句子,同时访问原文中前后的句子。 - 核心代码介绍: ```s # 定义上下文增强检索函数 def context_enriched_search(query, text_chunks, embeddings, k=1, context_size=1): query_embedding = create_embeddings(query).data[0].embedding similarity_scores = [] for i, chunk_embedding in enumerate(embeddings): similarity_score = cosine_similarity(np.array(query_embedding), np.array(chunk_embedding.embedding)) similarity_scores.append((i, similarity_score)) similarity_scores.sort(key=lambda x: x[1], reverse=True) top_index = similarity_scores[0][0] start = max(0, top_index - context_size) end = min(len(text_chunks), top_index + context_size + 1) return [text_chunks[i] for i in range(start, end)] ``` - 优点: 能够有效过滤噪音信息,提升答案的相关性和准确性。 - 缺点: 需要额外的预处理步骤和上下文信息的构建,增加了系统复杂性。 - 性能:**在上下文增强检索中,我们不仅检索与查询最相关的文本块,还会检索其周围的文本块作为上下文信息。这些“邻居”文本块能够为检索提供更多的背景信息,帮助生成更准确的回答**。经过测试,上下文增强检索的评分达到了 0.6,相较于简单 RAG 和语义分块有了显著的提升。这表明,上下文信息在检索过程中确实起到了关键作用。 #### 3.4.3 上下文切块标题(Contextual Chunk Headers) 🏷️:给文本块加上“标签” ![](img/微信截图_20250417084954.png) - 动机:上下文增强检索虽然有效,但仍然存在一个问题:**即使有了上下文信息,文本块本身可能仍然缺乏足够的语义信息**。例如,一个文档可能包含多个主题,每个主题都对应着不同的文本块。在这种情况下,**如何快速准确地找到与查询最相关的文本块呢?** - 实现方式 - [python](https://articles.zsxq.com/id_1u8ef7c9aejh.html) - [LangChain](https://articles.zsxq.com/id_zmh92i6sz0la.html) - 概述🔎 - 上下文块头(CCH)是一种创建文档级和节级上下文的方法,并在嵌入块之前将这些块头添加到块中。 - 实现🛠️ - **上下文块头(CCH)在每个文本块的前面添加了一个描述性的标题(header),这个标题就像是一个“标签”,能够概括文本块的主要内容**,并将其添加到每个块,以提高检索准确性。 - 部分代码实现: ```s # 为每个文本块生成描述性标题 text_chunks_with_headers = chunk_text_with_headers(extracted_text, chunk_size=1000, overlap=200) # 打印一个样本以查看效果 print("Sample Chunk with Header:") print("Header:", text_chunks_with_headers[0]['header']) print("Content:", text_chunks_with_headers[0]['text']) ``` - 优点: 标题往往能简明扼要地反映内容核心,能快速引导模型关注重要信息。 - 缺点: 对于标题不明显或未提供标题的文档,效果可能不理想。 - 效果:在检索过程中,系统不仅会考虑文本块的内容,还会参考其标题,从而更准确地找到与查询相关的文本块。经过测试,上下文块头的评分达到了 0.5,虽然没有上下文增强检索高,但也比简单 RAG 和语义分块有了明显的提升。这说明,通过给文本块添加标题,我们能够为检索提供更多的语义信息,从而提高检索的准确性。 #### 3.4.4 文档增强(Document Augmentation):从文本块生成问题增强检索 ![](img/微信截图_20250417085513.png) - 动机:上下文块头(CCH)虽然能够提供更多的语义信息,但仍然存在局限性。**在某些情况下,文本块的内容可能过于复杂,难以用一个简单的标题来概括**。那么,有没有一种方法能够让文本块更容易被检索到呢? - 实现方式 - [python](https://articles.zsxq.com/id_hrhnjum41r95.html) - [LangChain](https://articles.zsxq.com/id_08gjre0ih2s7.html) - 概述🔎 - 这个实现演示了一种文本增强技术,该技术利用额外的问题生成来改进矢量数据库中的文档检索。通过生成和合并与每个文本片段相关的各种问题,系统增强了标准检索过程,从而增加了找到相关文档的可能性,这些文档可以用作生成式问答的上下文。 - 实现🛠️ - 使用LLM来扩展文本数据集,其中包含可以向每个文档提出的所有相关的问题,并将这些问题也转换为嵌入向量。 - 代码实现: ```s # 处理文档,提取文本、创建文本块、生成问题并构建向量库 text_chunks, vector_store = process_document( pdf_path, chunk_size=1000, chunk_overlap=200, questions_per_chunk=3 ) ``` - 优点: 增加了文档的信息量,使得后续检索与生成过程能够获得更多上下文支持。 - 缺点: 增强过程需要额外计算资源,并且处理不当可能引入噪声信息。 - 效果:这样一来,在检索过程中,系统不仅能够匹配文本块的内容,还能够匹配与查询相关的问题,从而提高检索的准确性。经过测试,文档增强的评分达到了 0.8,这是一个非常高的分数,表明文档增强技术能够显著提高检索的准确性。这也说明,通过为文本块生成相关问题,我们能够为检索提供更多的入口,从而更容易找到与查询相关的文本块。 #### 3.4.5 相关段落提取(Relevant Segment Extraction,RSE):寻找连续的相关文本 ![](img/微信截图_20250417141717.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序。然而,我们**忽略了一个重要的问题:有时候,最佳的信息可能分散在多个连续的文本块中**。那么,有没有一种方法能够让系统自动识别并提取这些连续的相关文本呢? - 实现方式 - [python](https://articles.zsxq.com/id_8vh91c6ivpzr.html) - [LangChain](https://articles.zsxq.com/id_xlqi3eojlmgw.html) - 概述🔎 - 相关片段提取(RSE)是一种动态构建与给定查询相关的多块文本片段的方法。 - 实现🛠️ - 执行检索后处理步骤,分析最相关的块并识别较长的多块段,以便为LLM提供更完整的上下文。 - 代码实现: ```s # 运行 RAG 并应用相关段落提取 rse_result = rag_with_rse(pdf_path, query) ``` - 优点: 能够提升检索结果的语义一致性,适用于信息复杂或语义模糊的问题。 - 缺点: 实现过程中对语义提取的依赖较高,需确保语义模型的准确性。 - 效果:经过测试,相关段落提取的评分达到了 0.8。这个分数表明,相关段落提取技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,识别并提取连续的相关文本是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 #### 3.4.6 上下文压缩(Contextual Compression):让信息更精炼 🗜️ ![](img/微信截图_20250421085541.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本。然而,我们忽略了一个重要的问题:有时候,检索到的信息可能过于冗长,包含了大量与查询不相关的内容。这不仅会浪费计算资源,还可能会影响生成回答的质量。那么,**有没有一种方法能够让检索到的信息更精炼,只保留与查询最相关的内容呢**? - 实现方式 - [python](https://articles.zsxq.com/id_qmd61weal6k7.html) - [LangChain](https://articles.zsxq.com/id_xzz4h8kbdemk.html) - 概述🔎 - 压缩检索到的信息,同时保留查询相关的内容。 - 实现🛠️ - 使用LLM压缩或汇总检索到的块,保留与查询相关的关键信息。 - 核心代码实现: ```s # 定义上下文压缩函数 def rag_with_compression(pdf_path, query, k=10, compression_type="selective", model="meta-llama/Llama-3.2-3B-Instruct"): vector_store = process_document(pdf_path) results = vector_store.similarity_search(create_embeddings(query), k=k) retrieved_chunks = [r["text"] for r in results] compressed = batch_compress_chunks(retrieved_chunks, query, compression_type, model) compressed_chunks, compression_ratios = zip([(c, r) for c, r in compressed if c.strip()] or [(chunk, 0.0) for chunk in retrieved_chunks]) context = "\n\n---\n\n".join(compressed_chunks) response = generate_response(query, context, model) return { "query": query, "original_chunks": retrieved_chunks, "compressed_chunks": compressed_chunks, "compression_ratios": compression_ratios, "context_length_reduction": f"{sum(compression_ratios)/len(compression_ratios):.2f}%", "response": response } ``` - 优点: 降低输入信息的冗余度,加快生成模型的处理速度,同时保持必要的语义信息。 - 缺点: 摘要质量直接影响最终答案的准确性,压缩过程需要精细调控以防信息丢失。 - 效果:上下文压缩的评分达到了 0.75。这个分数表明,上下文压缩技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,对检索到的信息进行压缩是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 ### 3.5 🚀 Advanced Retrieval Methods #### 3.5.1 Fusion Retrieval 🔗 ![](img/微信截图_20250422084359.png) - 动机:前面主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思,以及如何构建知识图谱,以及如何平衡上下文信息和检索精确性,以及如何从假设文档出发。然而,我们忽略了一个重要的问题:**不同的检索方法有各自的优缺点,如何将它们结合起来,发挥各自的优点呢**? - 实现方式 - [python](https://articles.zsxq.com/id_pc9w3nkozmmu.html) - [LangChain](https://articles.zsxq.com/id_jbo3kqnqwu6c.html) - 概述🔎 - 采用加权融合、投票机制或神经网络融合多路检索结果,确保多角度信息互补。 - 实现🛠️ - 将基于关键字的搜索与基于向量的搜索相结合,以获得更全面和准确的检索。 - 效果:这种方法能够更好地满足不同查询的需求,提高检索的准确性。经过测试,融合 RAG 的评分达到了 0.83。这个分数表明,融合 RAG 技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,结合多种检索方法是一个非常有效的策略,能够帮助我们更好地利用检索到的信息。 - 优点: 可以有效降低单一检索方法的局限性,提供更加多样和全面的信息。 - 缺点: 融合策略设计复杂,需要平衡各路信息的权重。 #### 3.5.2 重排序器(Re-Ranker):让检索结果更有条理📈 ![](img/微信截图_20250417141310.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量。然而,我们忽略了一个重要的环节:**检索结果的排序。简单相似性搜索通常会返回一组相关性和不相关性混杂的结果,这可能会导致生成的回答不够准确**。那么,有没有一种方法能够让检索结果更有条理,更容易被利用呢? - 实现方式 - [python](https://articles.zsxq.com/id_nurhvhi8gppo.html) - [LangChain](https://articles.zsxq.com/id_igihvkkpcs9a.html) - 概述🔎 - 在初始检索的基础上,通过一个额外的步骤对检索结果进行重新排序,将最相关的文本块放在最前面。重排序可以使用不同的方法,例如基于关键词的重排序或基于 LLM 的重排序。 - 实现🛠️ - 🧠基于llm的评分:使用语言模型对每个检索块的相关性进行评分。 - 🔀交叉编码器模型:联合重新编码查询和检索的文档,以便进行相似性评分。 - 🏆元数据增强排名:将元数据合并到评分过程中,以获得更细微的排名。 - 代码实现: ```s # 定义重排序函数 def rag_with_reranking(query, vector_store, reranking_method="llm", top_n=3, model="meta-llama/Llama-3.2-3B-Instruct"): query_embedding = create_embeddings(query) initial_results = vector_store.similarity_search(query_embedding, k=10) if reranking_method == "llm": reranked_results = rerank_with_llm(query, initial_results, top_n=top_n) else: reranked_results = initial_results[:top_n] context = "\n\n===\n\n".join([result["text"] for result in reranked_results]) response = generate_response(query, context, model) return { "query": query, "reranking_method": reranking_method, "initial_results": initial_results[:top_n], "reranked_results": reranked_results, "context": context, "response": response } ``` - 优点: 提高了最终传递给生成模型的信息质量,减少了低相关度文档的干扰。 - 缺点: 增加了系统的计算开销,需要设计高效的排序算法以保证响应速度。 - 性能:经过测试,重排序的评分达到了 0.7。这个分数表明,重排序技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,对检索结果进行重新排序是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 #### 3.5.3 层次化索引(Hierarchical Indices) 🗂️ ![](img/微信截图_20250422083932.png) - 动机:主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思,以及如何构建知识图谱。然而,我们忽略了一个重要的问题:**如何平衡上下文信息和检索的精确性呢**? - 实现方式 - [python](https://articles.zsxq.com/id_xml7i4ebnnna.html) - [LangChain](https://articles.zsxq.com/id_rw8w9aldk8xc.html) - 概述🔎 - 对文档进行分层处理,先粗略定位大块信息,再在内部进行精细检索。 - 实现🛠️ - 为文档摘要和详细块实现两层系统:摘要和详细文本块。首先,系统在摘要层次进行检索,快速缩小相关文档的范围;然后,在详细文本块层次进行检索,提供精确的检索结果。 - 优点: 能大幅降低检索时间,提升大文档库中的查找精度。 - 缺点: 对文档结构有一定依赖,结构不明显的文档可能难以应用。 - 性能:这种方法既保留了上下文信息,又提高了检索的精确性。经过测试,层次化索引的评分达到了 0.84。这个分数表明,层次化索引技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,平衡上下文信息和检索精确性是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 ### 3.6 Multi-modal Retrieval 📽️ #### 3.6.1 Multi-model RAG with Multimedia Captioning 🛠️ ![](img/微信截图_20250422084902.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思,以及如何构建知识图谱,以及如何平衡上下文信息和检索精确性,以及如何从假设文档出发,以及如何结合多种检索方法。然而,我们忽略了一个重要的问题:文档中的信息不仅包含文本,还可能包含图像、图表等其他形式的信息,如何将这些信息也纳入检索范围呢? - 实现方式 - [python](https://articles.zsxq.com/id_486w9rgz7hth.html) - [LangChain](https://articles.zsxq.com/id_iag3ledqjv44.html) - 概述🔎 - 为了响应自然语言查询,实现从多模态文档(带有文本和图像的pdf)高效查询和内容生成。 - 实现🛠️ - 多模态 RAG(Multi Model RAG) 不仅从文档中提取文本,还会提取图像,并为图像生成描述性的标题。然后,系统将文本和图像的嵌入向量一起存储在向量库中,从而实现对文本和图像的联合检索。 - 效果:这种方法能够更好地利用文档中的信息,提高检索的准确性。经过测试,多模态 RAG 的评分达到了 0.79。这个分数表明,多模态 RAG 技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,将图像信息纳入检索范围是一个非常重要的步骤,能够帮助我们更好地利用文档中的信息。 - 优点: 能利用不同模型的长处,弥补单一模型可能存在的信息盲区,提升整体回答的多样性与准确性。 - 缺点: 计算资源消耗较大,对系统并行处理能力要求较高。 #### 3.6.2 Multi-model RAG with Colpali 🎭 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_qptvfgjo707c.html) - 概述🔎 - 为了响应自然语言查询,实现从多模态文档(带有文本和图像的pdf)高效查询和内容生成。 - 实现🛠️ - 介绍 如何实现了多模型RAG的多种方式之一。该项目**处理PDF文件,使用Colpali检索相关内容,并使用多模式RAG系统生成答案**。**该过程包括使用Gemini模型编制文档索引、查询和汇总**。 ### 3.7 🔁 Iterative and Adaptive Techniques #### 3.7.1 反馈循环(Feedback Loop):让系统不断学习🔁 ![](img/微信截图_20250421090037.png) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩。然而,我们忽略了一个重要的问题:这些改进都是基于预先设定的策略,系统无法根据实际的使用情况进行自我调整。那么,**有没有一种方法能够让系统根据用户的反馈不断学习和调整呢**? - 实现方式 - [python](https://articles.zsxq.com/id_dchrpvopw94f.html) - [LangChain](https://articles.zsxq.com/id_trdu6lstgg7q.html) - 概述🔎 - 实现从用户交互中学习和改进未来检索的机制。 - 实现🛠️ - 初次生成答案后,利用其内容重新检索相关信息,再更新答案,形成闭环优化。 - 实现方式: ```s # 定义完整的 RAG 流程,包含反馈机制 def full_rag_workflow(pdf_path, query, feedback_data=None, feedback_file="feedback_data.json", fine_tune=False): if feedback_data isNone: feedback_data = load_feedback_data(feedback_file) print(f"Loaded {len(feedback_data)} feedback entries from {feedback_file}") chunks, vector_store = process_document(pdf_path) if fine_tune and feedback_data: vector_store = fine_tune_index(vector_store, chunks, feedback_data) result = rag_with_feedback_loop(query, vector_store, feedback_data) print("\n=== Would you like to provide feedback on this response? ===") print("Rate relevance (1-5, with 5 being most relevant):") relevance = input() print("Rate quality (1-5, with 5 being highest quality):") quality = input() print("Any comments? (optional, press Enter to skip)") comments = input() feedback = get_user_feedback( query=query, response=result["response"], relevance=int(relevance), quality=int(quality), comments=comments ) store_feedback(feedback, feedback_file) print("Feedback recorded. Thank you!") return result ``` - 优点: 通过多次迭代不断纠正偏差,能显著提升回答的准确性与完整性。 - 缺点: 多轮迭代会增加系统延时,对实时性要求较高的应用场景可能不适用。 - 效果:反馈循环的评分达到了 0.7。虽然这个分数并不高,但它仍然表明反馈循环技术能够让系统不断学习和调整,从而提高检索结果的质量。这也说明,用户反馈是一个非常重要的资源,能够帮助系统更好地满足用户的需求。 #### 3.7.2 自适应RAG(Adaptive RAG):智能选择检索策略🎯 ![](img/微信截图_20250421090444.png) - 动机:如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整。然而,我们忽略了一个重要的问题:**不同的查询可能需要不同的检索策略。那么,有没有一种方法能够让系统根据查询的类型自动选择最合适的检索策略呢**? - 实现方式 - [python](https://articles.zsxq.com/id_6ig3zwe315nz.html) - [LangChain](https://articles.zsxq.com/id_snx3mpukh2t0.html) - 概述🔎 - 设计一个策略模块,根据查询内容、上下文复杂度等因素选择最适合的检索方法和生成模型参数。 - 实现🛠️ - 介绍 一种基于查询类型调整检索策略的高级检索增强生成(RAG)方法。通过在不同阶段利用语言模型(llm),它旨在为用户查询提供更准确、相关和上下文感知的响应。它根据查询的类型,自动选择最合适的检索策略。 > 例如,对于事实性查询,系统会选择事实检索策略;对于分析性查询,系统会选择分析检索策略;对于观点性查询,系统会选择观点检索策略;对于上下文相关查询,系统会选择上下文检索策略。 - 核心代码实现: ```s # 定义自适应 RAG 函数 def rag_with_adaptive_retrieval(pdf_path, query, k=4, user_context=None): chunks, vector_store = process_document(pdf_path) query_type = classify_query(query) print(f"Query classified as: {query_type}") retrieved_docs = adaptive_retrieval(query, vector_store, k, user_context) response = generate_response(query, retrieved_docs, query_type) return { "query": query, "query_type": query_type, "retrieved_documents": retrieved_docs, "response": response } ``` - 优点: 实验结果显示其在各种指标上均表现优异,得分达到0.86;能在多种场景下保持较高准确率与响应速度。 - 缺点: 实现上需要较多调试和参数优化,但带来的性能提升使得投入是值得的。 - 效果:自适应 RAG 的评分达到了 0.86,这是所有方法中最高的分数。这个分数表明,自适应 RAG 技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,根据查询的类型自动选择检索策略是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 ### 3.8 📊 Evaluation #### 3.8.1 DeepEval Evaluation 📘 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_5hg30w4chmtj.html) - 概述🔎 - 通过覆盖几个度量和创建测试用例来执行评估 Retrieval-Augmented Generation systems。 - 实现🛠️ - 介绍 **如何使用deepeval库对 Retrieval-Augmented Generation (RAG) systems 执行全面的评估。它涵盖了各种评估指标,并为创建和运行测试用例提供了一个框架**。 #### 3.8.2 GroUSE Evaluation 🐦 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_smw4mezcgrnw.html) - 概述🔎 - 手动评估 RAG pipeline 输出可能具有挑战性。GroUSE框架利用llm与微调提示来解决 Grounded Question Answering 中的所有潜在故障模式。GroUSE单元测试用于识别最有效的提示,以优化这些评估器的性能。 - 实现🛠️ - 介绍 用于评估 Retrieval-Augmented Generation (RAG) pipelines 的框架GroUSE,重点关注最后阶段:**Grounded Question Answering (GQA)**。它演示了如何使用大型语言模型(LLM)跨四个不同的度量来评估GQA答案,并指导您使用GroUSE单元测试定制自己的Judge LLM。 ### 3.9 🔬 Explainability and Transparency #### 3.9.1 Explainable Retrieval 🔍 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_66c7vatftg68.html) - 概述🔎 - 传统的文档检索系统通常像黑盒子一样工作,提供结果而不解释选择这些结果的原因。在理解结果背后的原因至关重要的情况下,缺乏透明度可能会产生问题。可解释的检索器通过提供对每个检索文档的相关性的洞察来解决这个问题。 - 实现🛠️ - 介绍 如何实现了一个 Explainable retriver,这个系统不仅可以根据查询检索相关文档,还可以解释为什么每个检索到的文档都是相关的。它将基于向量的相似度搜索与自然语言解释相结合,提高了检索过程的透明度和可解释性。 ### 3.10 🏗️ Graph RAG Architectures #### 3.10.1 Knowledge Graph Integration (Graph RAG) 🕸️ ![](img/微信截图_20250422083605.png) - 动机:之前主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思。然而,我们忽略了一个重要的问题:**文档中的信息可能是相互关联的,如何构建一个知识网络,将这些信息有机地结合起来呢**? - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_q292x5hzoxeh.html) - 概述🔎 - 知识图谱 RAG(Knowledge Graph RAG)技术为我们提供了一个解决方案。它将文档中的信息构建成一个知识图谱,其中节点代表概念、实体或信息片段,边代表这些节点之间的关系。 - 实现🛠️ - 介绍 如何实现了一个 GraphRAG, **GraphRAG是一个先进的问答系统,它结合了基于图的知识表示和检索增强生成的能力**。它处理输入文档以创建丰富的知识图,然后用于增强对用户查询的检索和生成答案。该系统利用自然语言处理、机器学习和图论来提供更准确和上下文相关的响应。 - 性能:在检索过程中,系统不仅能够检索与查询直接相关的节点,还能够通过遍历知识图谱找到间接相关的节点,从而为生成回答提供更全面的上下文信息。经过测试,知识图谱 RAG 的评分达到了 0.78。这个分数表明,知识图谱 RAG 技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,构建知识图谱是一个非常重要的步骤,能够帮助我们更好地利用文档中的信息。 - 优点: 特别适用于专业领域或结构化知识密集型的问题,能提高回答的逻辑性和权威性。 - 缺点: 构建和维护知识图谱需要大量数据支持和专业知识。 ![](img/微信截图_20250422083852.png) #### 3.10.2 GraphRag (Microsoft) 🎯 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_j2649uk4wwhn.html) - 概述🔎 - Microsoft GraphRAG (Open Source)是一个先进的RAG系统,它集成了知识图谱来提高llm的性能 - 实现🛠️ - 介绍 如何实现了一个 Microsoft GraphRAG, **Microsoft GraphRAG 是一个先进的检索-增强生成(RAG)系统,它集成了知识图来提高大型语言模型(llm)的性能**。GraphRAG由微软研究院开发,通过使用 LLM-generated knowledge graphs 来增强文档分析并提高响应质量,从而解决了传统RAG方法的局限性。 #### 3.10.3 RAPTOR: Recursive Abstractive Processing for Tree-Organized Retrieval 🌳 - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_4mh07ub28u7m.html) - 概述🔎 - 实现递归方法,以树状结构处理和组织检索到的信息。 - 实现🛠️ - 介绍 如何实现了一个 RAPTOR, RAPTOR是一种先进的信息检索和问答系统,它结合了分层文档摘要、 embedding-based 的检索和上下文答案生成。它旨在通过创建一个多级摘要树来有效地处理大型文档集合,从而允许广泛和详细的信息检索。 ### 3.11 🏗️ Advanced Architectures #### 3.11.1 自我 RAG(Self RAG):让系统自我反思 🔁 ![](img/selfrag.webp) - 动机:在前面的讨论中,我们主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略。然而,我们忽略了一个重要的问题:**系统是否能够自我反思,判断是否需要检索,以及如何利用检索到的信息呢**? - 实现方式 - [python](https://articles.zsxq.com/id_v40sura1r0r5.html) - [LangChain](https://articles.zsxq.com/id_wvqvpaln3wv0.html) - 概述🔎 - 自我 RAG(Self RAG)技术为我们提供了一个解决方案。它不仅能够检索和生成回答,还能够自我反思,判断是否需要检索,以及如何利用检索到的信息。 - 实现🛠️ - 介绍 如何实现了一个 Self-RAG, Self-RAG是一种高级算法,它结合了自然语言处理中基于检索和基于生成方法的强大功能。**它动态地决定是否使用检索到的信息,以及如何在生成响应时最好地利用这些信息,以产生更准确、更相关和更有用的输出**。 - 核心代码实现: ```s # 运行自我 RAG result = self_rag(query, vector_store) ``` - 优点: 特别适合需要复杂逻辑推理和多轮交互的问题,能逐步逼近真实答案。 - 缺点: 迭代次数较多可能导致响应延迟,需要平衡准确率与效率。 - 性能:自我 RAG 的评分达到了 0.65。虽然这个分数并不高,但它仍然表明自我 RAG 技术能够让系统更加智能和灵活。这也说明,自我反思是一个非常重要的能力,能够帮助系统更好地适应不同的查询需求。 #### 3.11.2 Corrective RAG 🔧 ![](img/微信截图_20250422085207.png) - 动机:前面主要关注了如何改进文本块的表示和检索策略,以及如何改进查询的质量和检索结果的排序,以及如何识别并提取连续的相关文本,以及如何对检索到的信息进行压缩,以及如何根据用户的反馈不断学习和调整,以及如何根据查询的类型自动选择检索策略,以及如何让系统自我反思,以及如何构建知识图谱,以及如何平衡上下文信息和检索精确性,以及如何从假设文档出发,以及如何结合多种检索方法,以及如何将图像信息纳入检索范围。然而,我们忽略了一个重要的问题:**检索到的信息可能并不总是理想的,如何动态调整检索策略,以应对不同的情况呢**? - 实现方式 - [python](https://articles.zsxq.com/id_xnisk1rrdwga.html) - [LangChain](https://articles.zsxq.com/id_m2j03ipuqhgd.html) - 概述🔎 - 一种复杂的RAG方法,动态评估和纠正检索过程,结合向量数据库、网络搜索和语言模型,以获得高度准确和上下文感知的响应。 - 实现🛠️ - 纠正性 RAG(Corrective RAG,CRAG) 在检索之后,对检索到的信息进行评估,根据评估结果动态调整检索策略。如果检索到的信息质量高,系统会直接利用这些信息生成回答;如果检索到的信息质量低,系统会转而进行网络搜索;如果检索到的信息质量中等,系统会结合文档信息和网络搜索结果生成回答。 - 性能:经过测试,纠正性 RAG 的评分达到了 0.824。这个分数表明,纠正性 RAG 技术能够显著提高检索结果的质量,从而提高生成回答的准确性。这也说明,动态调整检索策略是一个非常重要的步骤,能够帮助我们更好地利用检索到的信息。 - 优点: 具有较高的稳定性和准确性,能适应复杂和多变的查询场景。 - 缺点: 实现相对复杂,整体系统调试和优化难度较大,虽然性能优异,但未能在得分上超越 Adaptive RAG。 ### 3.12 🌟 Special Advanced Technique 🌟 #### 3.12.1 Sophisticated Controllable Agent for Complex RAG Tasks - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_pnw222dmwv4h.html) - 概述🔎 - 虽然传统的RAG系统中用于处理简单的基于语义相似度的检索无法解决的复杂问题。 - 实现🛠️ - 介绍 **如何实现了一种高级的检索增强生成(RAG)解决方案,用于处理简单的基于语义相似度的检索无法解决的复杂问题**。 #### 3.12.2 R1 reasoning RAG - 实现方式 - python - [LangChain](https://articles.zsxq.com/id_sqkc0e8g7lzg.html) - 概述🔎 - 通过结合 DeepSeek-R1、Tavily 和 LangGraph,实现了由 AI 主导的动态信息检索与回答机制,利用 deepseek 的 r1 推理来主动地从知识库中检索、丢弃和综合信息,以完整回答一个复杂问题 - 实现🛠️ - 介绍 **如何实现了一种结合 DeepSeek-R1、Tavily 和 LangGraph,实现了由 AI 主导的动态信息检索与回答机制,利用 deepseek 的 r1 推理来主动地从知识库中检索、丢弃和综合信息,以完整回答一个复杂问题**。 ## 总结 通过上述对 不同 RAG 技术策略的测试和分析,可以看到,不同的技术有各自的优缺点,适用于不同的场景和需求。 1. 简单 RAG 提供了一个基础的框架,但其检索效果有限; 2. 语义分块、上下文增强检索、上下文块头、文档增强等技术通过改进文本块的表示和检索策略,提高了检索的准确性; 3. 查询转换、重排序、相关段落提取、上下文压缩等技术通过改进查询的质量和检索结果的排序,进一步提高了检索的效果; 4. 反馈循环、自适应 RAG、自我 RAG 等技术通过引入反馈机制和动态调整检索策略,让系统能够更好地适应不同的查询需求; 5. 知识图谱 RAG、层次化索引、HyDE、融合 RAG、多模态 RAG、纠正性 RAG 等技术通过结合多种方法和信息源,显著提高了检索的准确性和可靠性。 在这些技术中,自适应 RAG 以 0.86 的评分脱颖而出,成为表现最佳的 RAG 技术。它通过根据查询的类型自动选择最合适的检索策略,能够更好地满足不同用户的需求,生成更准确的回答。然而,这并不意味着其他技术没有价值。实际上,不同的技术可以在不同的场景下发挥重要作用,关键在于根据具体的需求和场景选择最适合的技术。 ## 致谢 - 18种RAG技术大比拼:谁才是检索增强生成的最佳选择? https://mp.weixin.qq.com/s/16Ra_wrH1igwiySPV9KkNA - 连续尝试了18种RAG技术之后,我找到了最优的那个 https://mp.weixin.qq.com/s/ZCFZy7B-Oe92G-H7I4_K9A - https://github.com/FareedKhan-dev/all-rag-techniques - https://github.com/NirDiamant/RAG_Techniques/ - https://levelup.gitconnected.com/testing-18-rag-techniques-to-find-the-best-094d166af27f