Loading

RAG高效召回方法

RAG技术树

image-20260508113926999

  • RAG研究的技术树主要涉及预训练(Pre-training)、微调(Fine-tuning)和推理(Inference)等阶段。

  • 随着LLM的出现,RAG的研究最初侧重于利用LLMs强大的上下文学习能力,主要集中在推理阶段。

  • 随后的研究进一步深入,逐渐与LLMs的微调阶段更加融合。研究人员也在探索通过检索增强技术来提升预训练阶段的语言模型性能

image-20260508113906811

参考文章:https://www.promptingguide.ai/research/rag

RAFT方法

什么是RAFT

RAFT全称是 Retrieval-Augmented Fine-Tuning(检索增强微调),一种给大模型做「RAG 专用微调」的方法,用来解决普通 RAG “检索不准、容易被干扰、不会用文档” 的问题。

  • 普通 RAG:推理时把检索文档塞到 Prompt 里 → 模型临时学着读文档,容易被干扰、瞎编(幻觉)。

  • RAFT:先微调、再 RAG。训练时就教会模型:

    • 从一堆文档里挑有用的、无视干扰的

    • 引用原文证据来答题

    • 检索不到时也能靠自己知识答

  • 可以理解为:普通 RAG 是「开卷裸考」,RAFT 是「先做模拟卷、再上考场」

image-20260508112336957

核心背景
  • 标准 RAG 缺陷:检索结果常混有无关 / 干扰文档,模型分不清、跟着错;模型没学过 “怎么读检索文档”,只会硬套。
  • 普通微调缺陷:模型容易死记硬背,到了真实 RAG 场景(给陌生文档)反而不会用。
  • RAFT 目标:把「微调」和「RAG」结合,让模型擅长开卷考试、抗干扰、会用证据
核心思路
  1. 训练数据构造(关键)

    干扰文档 = 和问题主题沾点边、但实际没用、不能用来答题的垃圾检索文档,看起来像相关,其实是废话、误导、无关内容,专门用来迷惑模型

​ 每个样本 = 问题 Q + 文档集合 D(含:1 个相关文档 + N 个干扰文档)+ 答案 A(带引用)。

  1. 训练目标(3 点)

    1. 忽略干扰:从一堆文档里只看有用的,无视无关的。

    2. 强制引用:答案必须引用相关文档的原文片段,减少幻觉。

    3. 链式推理:输出包含「思考过程 + 证据引用 + 最终答案」,强化逻辑。

  2. 训练流程

    • 用「问题 + 相关文档 + 干扰文档」做微调

    • 让模型学会:有文档就用文档、没文档就靠自己

RAFT 和普通 RAG / 微调 的区别
方法 特点 缺点
普通 RAG 只在推理时给文档,不微调 抗干扰差、幻觉多、不会用文档
普通微调 只学 QA,不给检索文档 死记硬背、泛化差、不会开卷
RAFT 训练时就给「相关 + 干扰」文档 需额外微调、数据构造稍复杂
  • 显著提升 RAG 准确率,尤其检索噪声大、多跳推理场景(如 HotpotQA、医疗 / 法律问答)。
  • 减少幻觉、答案可追溯(有原文引用),更可信。
  • 工业界常用:做领域知识库(企业 / 医疗 / 金融)、文档问答、客服机器人等。

训练示例:https://github.com/lumpenspace/raft

RAG高效召回的方法

合理设置TOP_K

top-k比如top-3,就是把和用户问题最相关的前 3 篇文档拿出来,塞进大模型的上下文里辅助答题

在 RAG 里,用户提问后,检索器会把知识库中所有文档按 “和问题的相似度” 排个序:

  • 第 1 名:相关性最高
  • 第 2 名:次之
  • 第 3 名:再次之
  • …… 后面的文档相关性越来越低

直接把所有文档都塞给模型会有两个致命问题:

  1. 上下文窗口装不下:大模型一次能处理的 token 有限,太多文档会超出限制。
  2. 噪声太多:后面相关性低的文档会变成 “干扰信息”,反而误导模型,降低回答质量。

所以我们一般只取最靠前的 k 个,这就是 top-k 检索

k应该怎么选

k 是一个需要自己调的超参数,没有固定值,一般经验是:

  • k 太小(比如 k=1):只取 1 篇文档,信息可能不全,回答不完整。
  • k 太大(比如 k=20):文档太多,噪声大,模型容易被干扰,还容易超出上下文限制
  • 实际业务里,一般会选 k=3~10 之间,再配合 ** 重排序(rerank)** 把相关性最高的几篇再筛一遍,效果会更好
#使用加载的知识库查询top_5
docs = knowledgeBase.similarity_search(query,k=5)

与RAFT的关系

  • 训练时就给模型喂「1 个正向文档 + 多个干扰文档」(模拟真实 top-k 检索结果里混了垃圾信息)

  • 让模型学会:在一堆 top-k 文档里,自动识别哪些是有用的,哪些是干扰信息,忽略噪声,只用有效文档答题

改进索引算法

知识图谱:利用知识图谱中的语义信息和实体关系,增加对查询文档的理解,提升召回的相关性

知识图谱是改进索引算法的重要手段,它通过给检索过程加入「语义和实体关系」的维度,解决了传统向量检索 “只看字面、不懂语义” 的短板,让 RAG 能召回更贴合用户真实意图的文档

基于知识图谱的RAG:

  • GraphRag
  • LightRag
  1. 知识图谱在 RAG 中的作用

    • 传统向量检索只靠「字面相似度」匹配,容易出现「语义相关但词不一样」(同义词、上下位词)、「词一样但语义无关」(一词多义)的问题。

    • 知识图谱的优化逻辑:

      • 语义增强理解:识别用户问题里的实体、概念(比如 “阿司匹林”“Transformer”),利用图谱里的关系(如 “发明于”“属于”),理解问题的真实意图,避免只看关键词。

      • 召回相关性提升:检索时,不只是匹配字面向量,还会根据图谱关系扩展检索范围(比如用户问 “Transformer 的变体”,会关联到 BERT、GPT 等实体),召回更相关的文档。

  2. 知识图谱在 RAG 里的典型应用方式

    环节 具体做法 效果
    查询理解 对用户问题做实体链接、关系抽取,明确问题的核心意图 减少歧义,避免检索跑偏
    检索增强 基于图谱实体扩展查询词,或给文档打上实体标签,实现多维度匹配 召回更多语义相关但字面不同的文档
    生成增强 把图谱中的实体关系作为上下文喂给模型,辅助生成答案 减少幻觉,答案更严谨、有依据
引入重排序

重排序模型: 对召回结果进行重排,提升问题和文档的相关性。常见的重排序模型有 BGE-RerankCohere Rerank

  • 场景:用户查询“如何提高深度学习模型的训练效率?”

  • 召回结果:初步召回10篇文档,其中包含与“深度学习”、“训练效率”相关的文章。

  • 重排序:BGE-Rerank对召回的10篇文档进行重新排序,将与“训练效率”最相关的文档(如“优化深度学习训练的技巧”)排在最前面,而将相关性较低的文档(如“深度学习基础理论”)排在后面。

混合检索: 结合向量检索和关键词检索的优势,通过重排序模型对结果进行归一化处理,提升召回质量。

优化查询扩展

相似语义改写: 使用大模型将用户查询改写成多个语义相近的查询,提升召回多样性,例如,LangChain的 MultiQueryRetriever 支持多查询召回,再进行回答问题

import os
from langchain.retrievers import MultiQueryRetriever
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.llms import Tongyi

# 初始化大语言模型
DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY")
llm = Tongyi(
    model_name="qwen-max",
    dashscope_api_key=DASHSCOPE_API_KEY
)

# 创建嵌入模型
embeddings = DashScopeEmbeddings(
    model="text-embedding-v3",
    dashscope_api_key=DASHSCOPE_API_KEY
)

# 加载向量数据库,添加allow_dangerous_deserialization=True参数以允许反序列化
vectorstore = FAISS.load_local("./vector_db", embeddings, allow_dangerous_deserialization=True)

# 创建MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(),
    llm=llm
)

# 示例查询
query = "客户经理的考核标准是什么?"
# 执行查询
results = retriever.get_relevant_documents(query)

# 打印结果
print(f"查询: {query}")
print(f"找到 {len(results)} 个相关文档:")
for i, doc in enumerate(results):
    print(f"\n文档 {i+1}:")
    print(doc.page_content[:200] + "..." if len(doc.page_content) > 200 else doc.page_content)
双向改写

将查询改写成文档(Query2Doc)或为文档生成查询(Doc2Query),缓解短文本向量化效果差的问题

1. Query2Doc:将查询改写成文档

  • 用户查询:“如何提高深度学习模型的训练效率?”

  • Query2Doc 改写:

    • 原始查询较短,可能无法充分表达用户意图。

    • 通过 Query2Doc 生成一段扩展文档:

      提高深度学习模型的训练效率可以从以下几个方面入手:

      1. 使用更高效的优化算法,如AdamW或LAMB。

      2. 采用混合精度训练(Mixed Precision Training),减少显存占用并加速计算。

      3. 使用分布式训练技术,如数据并行或模型并行。

      4. 对数据进行预处理和增强,减少训练时的冗余计算。

      5. 调整学习率调度策略,避免训练过程中的震荡。

2. Doc2Query:为文档生成关联查询

  • 文档内容:

    本文介绍了深度学习模型训练中的优化技巧,包括:

    1. 使用AdamW优化器替代传统的SGD。

    2. 采用混合精度训练,减少显存占用。

    3. 使用分布式训练技术加速大规模模型的训练……

  • 通过 Doc2Query 生成一组可能的查询:

    1. 如何选择深度学习模型的优化器?

    2. 混合精度训练有哪些优势?

    3. 分布式训练技术如何加速深度学习?

    4. 如何减少深度学习训练中的显存占用?

    5. 深度学习模型训练的最佳实践是什么?

索引扩展

离散索引

使用关键词抽取、实体识别等技术生成离散索引,与向量检索互补,提升召回准确性

  1. 关键词抽取: 从文档中提取出重要的关键词,作为离散索引的一部分,用于补充向量检索的不足。

    文档内容:

    本文介绍了深度学习模型训练中的优化技巧,包括: 
    1. 使用AdamW优化器替代传统的SGD。 
    2. 采用混合精度训练,减少显存占用。 
    3. 使用分布式训练技术加速大规模模型的训练。
    
    • 通过关键词抽取技术(如TF-IDF、TextRank)提取出以下关键词:
      • ["深度学习", "模型训练", "优化技巧", "AdamW", "混合精度训练", "分布式训练"]
    • 当用户查询“如何优化深度学习模型训练?”时,离散索引中的关键词能够快速匹配到相关文档。
  2. 实体识别:从文档中识别出命名实体(如人名、地点、组织等),作为离散索引的一部分,增强检索的精确性。

    文档内容:

    2023年诺贝尔物理学奖授予了三位科学家,以表彰他们在量子纠缠领域的研究成果。
    
    • 通过实体识别技术(如SpaCy、BERT-based NER)提取出以下实体:
      • ["2023年", "诺贝尔物理学奖", "量子纠缠"]
    • 当用户查询“2023年诺贝尔物理学奖的获奖者是谁?”时,离散索引中的实体能够快速匹配到相关文档。
混合索引

将BM25等离散索引与向量索引结合,通过Ensemble Retriever实现混合召回,提升召回多样性

将离散索引(如关键词、实体)与向量索引结合,通过混合召回策略提升检索效果

文档内容:

本文介绍了人工智能在医疗领域的应用,包括: 
1. 使用深度学习技术进行医学影像分析。 
2. 利用自然语言处理技术提取电子病历中的关键信息。 
3. 开发智能诊断系统辅助医生决策。
  • 关键词抽取:["人工智能", "医疗领域", "深度学习", "医学影像分析", "自然语言处理", "电子病历", "智能诊断系统"]
  • 实体识别:["人工智能", "医疗领域", "深度学习", "自然语言处理"]

当用户查询“人工智能在医疗领域的应用有哪些?”时:离散索引通过关键词和实体匹配到相关文档。向量索引通过语义相似度匹配到相关文档。综合两种召回结果,提升检索的准确性和覆盖率。

连续索引

连续索引: 结合多种向量模型(如OpenAI的Ada、智源的BGE)进行多路召回,取长补短。

Small-to-Big 索引策略:理解为一种「连续索引召回」的特殊实现 一种高效的检索方法,特别适用于处理长文档或多文档场景。核心思想是通过小规模内容(如摘要、关键句或段落)建立索引,并链接到大规模内容主体中。这种策略的优势在于能够快速定位相关的小规模内容,并通过链接获取更详细的上下文信息,从而提高检索效率和答案的逻辑连贯性

  1. 小规模内容(索引部分):

摘要:从每篇论文中提取摘要作为索引内容。

  • 摘要1:本文介绍了Transformer 模型在机器翻译任务中的应用,并提出了改进的注意力机制。

  • 摘要2:本文探讨了Transformer 模型在文本生成任务中的性能,并与RNN 模型进行了对比。

关键句:从论文中提取与查询相关的关键句。

  • 关键句1:Transformer 模型通过自注意力机制实现了高效的并行计算。

  • 关键句2:BERT 是基于Transformer 的预训练模型,在多项NLP 任务中取得了显著效果。

  1. 大规模内容(链接部分):

每篇论文的完整内容作为大规模内容,通过链接与小规模内容关联。

  • 论文1:链接到完整的PDF 文档,包含详细的实验和结果。

  • 论文2:链接到完整的PDF 文档,包含模型架构和性能分析。

  1. Small-to-Big机制:

1. 小规模内容检索: 用户输入查询后,系统首先在小规模内容(如摘要、关键句或段落)中检索匹配的内容。小规模内容通常是通过摘要生成、关键句提取等技术从大规模内容中提取的,并建立索引。

2. 链接到大规模内容: 当小规模内容匹配到用户的查询后,系统会通过预定义的链接(如文档ID、URL 或指针)找到对应的大规模内容(如完整的文档、文章)。大规模内容包含更详细的上下文信息,为RAG 提供丰富的背景知识。

3. 上下文补充: 将大规模内容作为RAG 系统的上下文输入,结合用户查询和小规模内容,生成更准确和连贯的答案。

实现原理:

  1. 文档 -> 生成摘要(LLM + Prompt)

    原始文档文件夹 -> 向量数据库 faiss-1

    摘要文档文件夹 -> 向量数据库 faiss-2

    两者建立1v1对应关系

  2. Small-to-Big 检索策略

    query -> faiss-2 -> faiss-1

posted @ 2026-05-08 13:45  木子七  阅读(41)  评论(0)    收藏  举报