FareedKhan-dev/all-rag-techniques: Implementation of all RAG techniques in a simpler way的笔记,方便后续查阅。
简单RAG Simple RAG
简单RAG流程:文本提取 → 文本分块 → 文本嵌入生成 → 语义检索 → 生成回答 → 答案评测
chunk之间会有overlap部分(提升检索准确性)
语义分块 Semantic Chunking
文本提取 → 句子级分割和嵌入生成 → 相似度计算和分割点设置 → 语义分块 → 块级嵌入生成 → 语义检索 → 生成式问答 → 答案评测
基于语义的文本分块分割点设置方法有:
- 百分比:查找所有相似性差异的第 X 个百分位数,并分割差异大于该值的块;
- 标准差:拆分相似度低于平均值 X 个标准差以上的数据块
- Interquartile Range (IQR,是统计学中衡量数据分布离散程度的一个指标,表示数据中间 50% 的范围):使用四分位距(Q3 - Q1)来确定分割点(Q1(第一四分位数):数据中 25% 的位置(下四分位数);Q3(第三四分位数):数据中 75% 的位置(上四分位数))
分块大小设置 Chunk Size Selector
块大小设置目的是为了平衡检索性能和回复质量,要根据实际数据选择合适的分块大小
上下文增强检索 Context-Enriched Retrieval in RAG
传统的检索方式找到的是孤立的文件块,可能会导致不完整的问题回答。上下文增强检索通过检索相关文本块及其邻近块,提升生成答案的完整性和连贯性。
上下文头信息增强 Contextual Chunk Headers (CCH) in Simple RAG
上下文头信息增强通过为每个文本块添加高层次上下文(如标题或小节名),提升检索相关性和生成准确性,减少“断章取义”现象。
关键步骤:文本分块与头信息生成
- 定义
generate_chunk_header
函数,利用 LLM 为每个文本块生成简明标题。 - 定义
chunk_text_with_headers
函数,将文本按指定长度和重叠度分块,并为每块生成头信息,返回包含header
和text
的字典列表,遍历所有块,生成并保存正文和头信息的嵌入。 - 相似度设置为融合相似度
avg_similarity = (sim_text + sim_header) / 2
。
基于问题生成的文档增强型RAG Document Augmentation RAG with Question Generation
基于问题生成的文档增强型RAG是为每个文本块自动生成相关问题,并将这些问题与原文块一同向量化入库,提升检索相关性和问答效果。
关键步骤:定义 generate_questions
函数,利用 LLM
为每个文本块生成若干可由该块回答的问题,并为文本块和问题分别生成嵌入向量。
查询变换 Query Transformations for Enhanced RAG Systems
通过对用户查询进行多种变换,提升检索相关性和答案的全面性,无需依赖 LangChain 等专用库。
三种常见的查询变换技术:
- Query Rewriting(查询重写):将原始查询改写为更具体、更详细的表达,提升检索精度。
- Step-back Prompting(后退式提示):将查询泛化为更宽泛的问题,以获取更多背景信息。
- Sub-query Decomposition(子查询分解):将复杂查询拆解为多个简单子问题,便于全面检索。
重排序 Reranking for Enhanced RAG Systems
通过在初步检索后对候选文档进行重排序,提升最终用于生成答案的内容相关性和准确性。
核心流程:
- 初始检索:第一遍使用基本相似性搜索(准确性较低,但速度较快)
- 文档评分:评估每个检索到的文档与查询的相关性
- 重排序:根据相关性得分对文档进行排序
- 选择:只使用最相关的文档生成回复
- 重排序方法有:
- LLM-based Reranking:调用大模型对每个候选块与查询的相关性打分(0-10分),按分数重新排序,选取最优内容。
- Keyword-based Reranking:基于关键词匹配和出现位置等简单规则对候选块打分并排序。
- 无重排序:直接使用初步检索结果。
- 重排序(尤其是基于大模型的相关性打分)能显著提升 RAG 系统检索内容的相关性和最终答案的准确性。
- 简单的关键词重排序也能在部分场景下提升效果,但不如 LLM 重排序智能。
相关片段提取 Relevant Segment Extraction (RSE) for Enhanced RAG
通过识别和重构(也就是自动拼接)文档中连续且相关的文本片段(而非孤立的 chunk),为大模型提供更连贯、更高质量的上下文,提升问答效果。
RSE核心算法:
- 相关性打分:对每个 chunk 计算与查询的相关性分数,并对不相关块施加惩罚。
- 片段搜索:采用变体的最大子数组和算法,自动寻找一组最优的连续 chunk 片段(可多段),使得总相关性最大且片段长度受控。
- 片段重构:将选中的 chunk 连续拼接为完整的上下文片段,供大模型生成答案。
上下文压缩 Contextual Compression for Enhanced RAG Systems
对检索到的文本块进行压缩,只保留与查询高度相关的内容,减少噪音,提高生成答案的准确性和上下文利用率。
- 上下文压缩方式:
- Selective:仅保留与查询直接相关的句子或段落,保留相关句子的准确措辞,保留原文顺序。
- Summary:对 chunk 进行与查询相关的信息摘要。
- Extraction:逐句抽取与查询相关的原文句子。
- 实现方式:利用大模型(LLM)对每个检索到的 chunk
进行压缩,输出压缩后的内容及压缩率。通过关键函数
rag_with_compression
检索 top-k chunk,逐个压缩,拼接为最终上下文,再用 LLM 生成答案。 - 适用于长文档问答、知识密集型检索、窗口受限的 LLM 应用等
反馈闭环 Feedback Loop in RAG
通过收集和利用用户反馈,动态调整检索与生成流程,使系统随用户交互不断自我优化,提升答案相关性和质量。
传统RAG与反馈闭环的区别
- 传统RAG系统只基于embedding相似度检索文档,系统是静态的。
- 引入了用户反馈的RAG系统,能够根据用户的评价不断调整文档相关性和检索效果,实现动态自我优化。
RAG反馈闭环流程
- 用户提问 → 检索相关文档 → 生成回答 → 收集用户反馈 → 反馈影响下次检索和生成 → 循环优化。
自适应检索 Adaptive Retrieval for Enhanced RAG Systems
利用大模型自动将用户查询分为四类:Factual(事实型)、Analytical(分析型)、Opinion(观点型)、Contextual(情境型),然后采用不同的检索策略。
- 针对不同类型的查询,自动选择最合适的检索策略:
- Factual:增强查询精度,重点检索最相关内容。
- Analytical:将复杂问题拆分为子问题,检索覆盖面更广的内容。
- Opinion:识别不同观点,检索多元化内容。
- Contextual:结合用户上下文,检索与情境高度相关的内容。
自反式检索增强生成 Self-RAG: A Dynamic Approach to RAG
在传统RAG基础上引入了“自我反思”机制,让系统在检索和生成过程中动态决策、评估和优化,提升回答的相关性和可靠性。
- 核心思想
- 不是每个问题都需要检索,系统会先判断是否需要检索(Retrieval Decision)
- 检索后对每个候选文档进行相关性评估(Relevance Evaluation)
- 生成回答后,进一步评估回答是否被检索内容充分支持(Support Assessment)
- 对最终回答的实用性进行打分(Utility Evaluation)
- 通过这些“反思点”,动态选择最优回答
命题式分块 Proposition Chunking for Enhanced RAG
将文档拆解为原子化、事实性陈述的高级技术,以实现更精准的信息检索。与传统仅按字符数分块容易导致信息冗余或语义不完整的方法不同,命题式分块能够保留每个事实的语义完整性。
命题式分块的优势
- 将内容拆解为原子化、自洽的事实
- 创建更小、更细粒度的检索单元
- 使查询与相关内容之间的匹配更加精准
- 过滤掉低质量或不完整的命题
关键步骤:
- 命题生成:用大模型将每个初步块进一步拆解为若干原子命题(propositions),每条命题只表达一个具体事实,避免代词和歧义。
- 命题质量评估与筛选:对每条命题用大模型自动评估其准确性、清晰度、完整性和简洁性,低于阈值的命题会被过滤掉,保证检索单元的高质量。
参考prompt:
请将下列文本拆解为简单、独立的命题。
确保每条命题都符合以下标准:
- 表达单一事实:每条命题应陈述一个具体事实或主张。
- 无需上下文即可理解:命题应自洽,无需额外上下文也能理解其含义。
- 使用全称而非代词:避免使用代词或含糊的指代,应使用完整的实体名称。
- 包含相关日期/限定词:如适用,请包含必要的日期、时间或限定词,使事实更为准确。
- 只包含一个主谓关系:每条命题只聚焦一个主语及其对应的动作或属性,不要包含并列或多个从句。
只输出命题列表,不要包含任何额外文字或解释。
你是一位评估从文本中提取命题质量的专家。请根据以下标准(1-10分)对给定命题进行评分:
- 准确性(Accuracy):命题与原文信息的吻合程度
- 清晰度(Clarity):在无需额外上下文的情况下,命题的易理解程度
- 完整性(Completeness):命题是否包含必要的细节(如日期、限定词等)
- 简洁性(Conciseness):命题在不丢失重要信息的前提下是否简明扼要
请以有效的JSON格式返回每项评分,示例: {“accuracy”: X, “clarity”: X, “completeness”: X, “conciseness”: X}
多模态 Multi-Modal RAG with Image Captioning
核心思想是将文档中的文本和图片(如图表、表格等)都纳入知识库,通过图像描述(captioning)技术为图片生成可检索的文本描述,从而实现文本与视觉信息的联合检索和问答。
关键内容:
- 图片描述生成:图片提取并保存为文件,利用多模态大模型(如LLaVA)对每张图片生成详细的学术型描述(caption),使图片信息可被文本检索系统利用。
- 向量化与多模态向量库:对文本块和图片描述统一生成embedding,构建一个支持文本和图片描述混合检索的向量库(MultiModalVectorStore)。
- 多模态检索与问答:用户查询时,将问题embedding与向量库比对,检索出最相关的文本块和图片描述,并在生成回答时明确区分信息来源(文本/图片)。
融合检索 Fusion Retrieval: Combining Vector and Keyword Search
将语义向量检索(Vector Search)与关键词检索(BM25)结合起来,提升了检索的全面性和准确性。
传统的RAG系统通常只依赖向量检索,但这种方式存在局限性:
- 向量检索擅长捕捉语义相似性,但可能遗漏精确的关键词匹配
- 关键词检索适合查找特定术语,但缺乏语义理解能力
- 不同类型的查询在不同检索方式下表现各异
融合检索过程:
- 同时进行向量检索和关键词检索,对同一查询,分别用向量检索和BM25检索获取得分;
- 对两种检索方式的得分进行归一化并用加权公式将两种得分结合,按照综合得分对文档进行排序;
- 问答生成时,用融合检索结果拼接上下文,调用大模型生成答案。
BM25实现逻辑:
- 提取文本:从每个分块(chunk)中提取出文本内容,形成一个文本列表。
- 分词:对每个文本块按空格进行分词,得到一个“分词后的文档”列表(即每个文档是一个词的列表)。
- 构建BM25索引:用分词后的文档列表初始化
BM25Okapi
,从而建立BM25关键词检索索引。 - 打印文档数:输出BM25索引中包含的文档数量,便于调试和确认。
- 返回BM25索引对象:返回构建好的BM25索引,供后续关键词检索使用。
Graph RAG: Graph-Enhanced Retrieval-Augmented Generation
将知识组织为连接图(而非扁平文档集合)来增强传统RAG系统的技术,实现在相关概念之间的导航,比标准的向量相似度方法能检索到更具上下文相关性的信息。
主要优势:
- 保留信息片段之间的关系
- 支持通过连接的概念进行遍历,找到相关上下文
- 提升对复杂、多步骤查询的处理能力
- 通过可视化知识路径,提供更好的可解释性
重要函数
extract_concepts(text)
从一段文本中自动提取5-10个最重要的关键概念、实体或术语,返回一个字符串列表。
build_knowledge_graph(chunks)
将一组文本块(chunks)构建为知识图谱(Knowledge
Graph),节点为文本块,边表示块之间的语义和概念关联。
在构建图时,两两遍历节点,判断是否有共享概念:
- 如果有共享概念,计算embedding的语义相似度,计算概念重叠得分(重叠概念数/较小概念数)。
- 综合语义相似度和概念重叠得分,得到边的权重(0.7语义相似度 + 0.3概念得分),只有权重大于0.6时才在节点间加边,边属性包括权重、相似度、共享概念。
traverse_graph
在知识图谱上,结合“查询与节点的语义相似度”和“节点间的概念/语义关联”,优先遍历最相关的知识块,最终返回一组与问题最相关的上下文内容,为后续生成答案提供依据。
分层索引 Hierarchical Indices for RAG
通过两级检索流程提升检索效果:首先通过摘要定位相关文档部分,然后再从这些部分中检索具体细节(有点像CCH的改进)。
新增内容:
- 从PDF中按页提取文本,每页生成一个摘要(summary),每页再细分为多个重叠的详细文本块(chunk)。
- 分别为所有摘要和详细块生成embedding,分别建立“摘要向量库”和“详细块向量库”。
分层检索流程:
- 在摘要向量库中检索最相关的若干摘要,确定相关页。
- 第二步:仅在这些相关页的详细块中检索,获取最相关的内容块。
- 检索结果带有详细的上下文和页码信息。
- 将检索到的详细块拼接为上下文,调用大模型生成答案,并在答案中引用具体页码。
假设文档嵌入 Hypothetical Document Embedding (HyDE) for RAG
在检索前将用户查询转化为假设的答案文档。传统RAG直接对用户短查询做embedding,容易语义信息不足,检索效果有限。HyDE方法先用大模型生成一个“假设文档”(即假设性的详细答案),再对这个文档做embedding,用于检索,能更好地弥合短查询与长文档的语义鸿沟。
HyDE检索流程
- 针对用户查询,先用大模型生成一份假设性详细答案(假设文档)。
- 对假设文档做embedding,然后用该embedding在向量库中检索最相关的真实文档块。
- 可选:将检索到的内容作为上下文,调用大模型生成最终答案。
校正性RAG Corrective RAG (CRAG) Implementation
在必要时动态评估检索到的信息,并通过网络搜索进行校正。
- 传统RAG只用本地知识库检索,可能遇到信息缺失或不相关的问题。
- CRAG流程:先检索本地知识块,自动评估其相关性,若相关性不足则自动调用网络搜索(如DuckDuckGo),甚至融合多源信息,最后生成答案。
CRAG相较于传统RAG的改进包括:
- 在使用检索内容前先进行评估
- 根据相关性动态切换知识来源
- 当本地知识不足时,用网络搜索进行校正
- 在合适的情况下结合多种来源的信息
CRAG核心流程
- 对用户查询做embedding,检索本地最相关的k个文档块。
- 用大模型自动评估每个检索结果的相关性(0~1分)。
- 根据最高相关性分数采取不同策略:
- 高相关性(>0.7):直接用本地文档生成答案。
- 低相关性(<0.3):自动重写查询,调用网络搜索,提炼网络结果生成答案。
- 中等相关性:本地文档和网络搜索结果都用,分别提炼后合并生成答案。
- 所有答案都带有信息来源说明。
Simple RAG with RL
一个简单的RAG包含三个基本步骤:
- 索引:将文档切分为若干片段,并转换为向量嵌入。
- 检索:当有问题被提出时,找到最相关的片段。
- 生成:将问题与检索到的片段结合,让AI基于这些信息生成答案。
实际问题是:如何利用提供的文档为给定问题生成答案。简单RAG由于检索片段缺乏足够上下文,往往难以生成准确答案。RL RAG
(强化学习RAG)方法可以利用提供的文档为给定问题生成更优答案。
RL RAG中的设定:
- 状态(State):包括原始查询、当前查询、检索到的上下文、历史响应和奖励。
- 动作空间(Action Space):
rewrite_query
:重写查询以提升检索效果expand_context
:扩展上下文,获取更多内容块filter_context
:过滤上下文,仅保留最相关内容generate_response
:基于当前上下文生成答案
- 奖励(Reward):用生成答案与标准答案的embedding余弦相似度作为奖励信号。
- 策略网络(Policy Network):采用epsilon-greedy策略,结合启发式规则选择动作。
- 训练循环:每轮训练中,RL agent根据当前状态选择动作,执行动作并更新状态,最终生成答案并计算奖励,更新策略。
适用场景与优势:
- 复杂/开放性问题:RL增强RAG能动态调整检索范围和内容,适合处理信息分散、答案需要多步推理的问题。
- 检索-生成协同优化:不仅优化检索,还能优化生成prompt和答案结构。
- 可持续学习:随着用户反馈和奖励信号的积累,系统能持续自我提升。
端到端流程 End-to-End Pipeline: Big Data with Knowledge Graph
- 数据准备
- 信息抽取
- 实体识别(NER):
- 先用spaCy做初步实体类型分布探索。
- 再用LLM(大语言模型)根据定制的实体类型(如ORG、PERSON、MONEY、DATE等)对新闻进行更精准的实体抽取。
- 关系抽取(RE):
- 用LLM抽取实体间的关键关系(如ACQUIRED、HAS_PRICE、ANNOUNCED_ON等),输出结构化的关系三元组。
- 知识图谱构建
- 实体消歧与标准化:对实体文本进行归一化(如去除公司后缀),为每个唯一实体生成URI。
- 本体对齐:将实体类型和关系映射到Schema.org等标准本体或自定义本体。
- 三元组生成:用rdflib将实体和关系转化为RDF三元组,形成知识图谱。
- 图片精炼与推理
- 实体嵌入:用LLM生成实体名称的向量表示(embedding)。
- 相似度与链接预测:通过计算实体嵌入的余弦相似度,演示基于语义相似度的潜在关系发现(简化版的链接预测)。
- 持久化
- 存储:将知识图谱以Turtle格式持久化保存。
- 查询:用SPARQL对知识图谱进行结构化查询,获取如公司列表、收购事件、带价格的收购等信息。
- 可视化:用pyvis对部分知识图谱进行交互式可视化展示。