首页 > 教程攻略 > ai资讯 >RAG(检索增强生成)系统的问题及解决思路

RAG(检索增强生成)系统的问题及解决思路

来源:互联网 时间:2026-08-20 14:39:26

大型语言模型(LLM)的出现,让搜索这件事儿彻底变了样。传统的关键词搜索和推荐系统虽然还能用,但LLM直接把搜索能力拉到了一个新高度。这个方向虽然还比较新,但研究成果已经铺天盖地了。下面就来盘点一下目前提升检索增强生成(RAG)系统性能和输出相关性的一些主流技术。

RAG(检索增强生成)系统的问题及解决思路

当然,好想法远不止这些,比如用

知识图谱来增强RAG

也是值得关注的方向。我们先把注意力放在最核心的实践上。

RAG 存在的问题

RAG 的概念最早由 Lewis 在2020年的论文中正式提出

(https://arxiv.org/abs/2005.11401)。核心思路很简单:在知识密集型任务中,让LLM先从外部文档里检索相关信息,再结合自身理解能力生成答案——这种做法效果非常明显。

具体流程可以拆成四步:

  1. 用户发出查询;
  2. 系统搜索可能包含答案的文档并检索;
  3. 把检索到的文档作为上下文,连同查询一起喂给LLM;
  4. LLM理解提示,消化文档信息,最终生成答案。

这个机制解决了几个痛点。比如,如果LLM在训练时从未接触过查询中的信息,直接回答很容易出错;或者LLM缺乏所需细节,甚至产生

所谓的“幻觉”

——给出不正确的信息。再比如,如果LLM没有针对企业内部数据训练过,面对企业特定问题也容易翻车。

幻觉和准确性问题

早期为了增强搜索效果,有人提出用额外文档(比如行业特定、最新资料)对LLM做微调,也就是

fine-tuning

。但这个想法很快就降温了——原因很现实:用额外文档训练LLM成本太高,不是所有组织都有资源反复折腾。就算有能力,每次更新文档都得重新训练,这成了一个无底洞。

于是RAG的研究重点转向了下面这些问题:

  1. 检索什么?
  2. 怎么检索?
  3. 检索多少?
  4. 检索之前数据怎么存?
  5. 检索到的数据以什么顺序喂给LLM?
  6. 输出怎么生成?
  7. 如果答案有多个,最终怎么排序显示?

最初的RAG框架集中在三个环节:索引、检索和生成。索引阶段要处理数据的收集、清理、存储和准备。数据可以是文档、PDF、图片、视频等各种格式。首先转成纯文本,然后切成小块(几个词、句子或段落),这就是所谓的

chunking

。接着用标准嵌入模型把这些块转成向量表示,最后把文本块和向量一起存入向量数据库,形成键值对。

检索阶段则把用户查询也转成向量,通过相似度索引找出与查询最匹配的文档向量,返回前K个。然后查询和前K个文档一起喂给LLM,生成答案。根据模型的训练方式,LLM要么靠自身参数记忆,要么靠提供的文档来合成答案。

但问题在于,

这种简单方法有不少硬伤

。检索精度可能不够,导致返回的文档里混进不相关的内容;也可能漏掉一些相关文档,召回率偏低。而且RAG系统需要访问最新文档,如果数据库没更新,答案就不会太好。生成环节更麻烦:幻觉依然存在,没有足够的护栏,系统可能输出有毒、有偏见甚至令人反感的内容。更头疼的是,当检索到不相关的信息时,LLM生成的答案会变得支离破碎、重复或者离题。检索文档中的语气、时态、人称差异也会干扰LLM,导致效果打折。

在一些简单的RAG系统里,输出过于依赖增强信息,只是机械地提取上下文,而不是合成出更好的结果。另外,前K个文档的长度不能超过上下文窗口,否则会引入噪音,分散对关键信息的关注。有一篇论文(https://arxiv.org/pdf/2310.05029)提出了一个方法,可以在减小上下文窗口的同时保持生成质量。其中一种叫MemWalker的做法,把上下文窗口转成由文档摘要节点构成的树结构。LLM收到查询后,遍历这棵树找到相关摘要,再执行查询生成答案。

最佳实践

想要设计出最好的RAG系统,拿到最好的结果,下面这些实践是不错的参考。

改进索引

:文档分块的质量直接决定索引效果。块的大小要合适,才能让嵌入和索引更精准。常见的分块策略有:

  1. 所有块大小一致,比如100个token;
  2. 按页面、段落或句子来分块;
  3. 混合搭配,各种大小混着来。

分块越小,检索精度可能越高,但嵌入和存储的成本也会飙升。而且分块策略要和LLM的能力匹配——不同LLM的上下文长度限制不一样。任务类型也影响分块:如果目标是回答问题,和搜索文档相比,块大小显然不同。给数据加上元数据,比如日期、用途、作者、文档风格(报告、书籍、博客等)、原始语言,能显著提升查询的准确性。

搜索和检索

:除了向量相似度检索,还可以结合关键词和其他元数据来丰富上下文。传统搜索方法也能派上用场,语义搜索更是增强效果的好帮手。如果检索到多个文档,必须用排名机制筛选出前K个,再送入生成环节。有些实践者还会用搜索引擎或类似系统来获取最新信息,进一步喂给RAG。

图数据库

:并非所有人都偏爱向量搜索。有人用图数据库来找文档之间的关系。文档和它们的关联被转换成节点和边,这种方式检索更快,相关性也更高。

微调 LLM

:在某些场景下,微调LLM能提升检索效果。比如医疗健康应用,如果LLM已经针对医疗信息做过微调,那么它在理解上下文时会更在行——毕竟它本来就熟悉这块知识。

prompt 优化

:用户输入的提示常常夹杂很多噪音,导致模型理解效率低下。可以用一个小型LLM来清理和重写提示,突出要点、去除冗余、压缩长度。也有人用提示摘要来做这件事。

RAG 融合

:有一篇不错的博客介绍了RAG融合(https://towardsdatascience.com/forget-rag-the-future-is-rag-fusion-1147298d8ad1):从原始提示出发,生成多个提示,每个提示聚焦不同视角,从而丰富主查询的焦点。之后可以再用重新排名器来挑出更好的查询。

查询路由

:企业的数据往往存在多个数据库中——向量数据库存向量化数据,图数据库存关系,关系数据库存结构化数据,数据湖里还有最新流数据。不同类型的数据(文档、PDF、图片、视频等)分散在各个存储里。当RAG融合产生多个查询时,需要把查询路由到正确的数据源去检索,这也是实践者必须考虑的一环。

查询重写

:用户通常不擅长写精炼的查询。那为什么不借助LLM来重写查询,从而提升检索质量呢?

RAG 和 GAR

(检索增强生成和生成增强检索):一篇论文(https://arxiv.org/pdf/2305.15294)提出了一种迭代方法:先用查询生成答案,再用答案生成更好的查询,如此循环。换句话说,生成的结果反过来增强检索,检索的结果再增强生成。

微调嵌入模型

:用针对特定领域数据微调过的嵌入模型来生成提示和数据的嵌入,能有效提升检索效果。比如,同样一个模型,在通用维基百科数据上训练的,和针对医疗信息微调过的,后者生成的嵌入显然更优。

检索-读取 vs 检索-生成-再读取

:另一篇论文(https://arxiv.org/pdf/2209.10063)对传统的“检索-读取”流程做了改进。他们提出的GenRead方法,先根据检索到的文档生成一个上下文,然后对这个上下文做清理,再基于干净版本生成答案。这样减少了冗余和噪音。

假设文档嵌入

:还有一种很有意思的方法:假设存在一个包含查询答案的文档(即假设文档),这个文档可能信息不完全甚至包含错误。然后把这个假设文档编码成向量,在向量数据库中搜索它的邻近向量。检索到的向量再喂给LLM,获得准确答案。这种方法被证明在多种任务和语言中都表现出惊人的准确率。

父文档检索器

:有博客建议,先把大文档切成小块的子文档并向量化。当子向量被检索到时,再找到对应的父文档,把完整的父文档喂给LLM,获得更好的响应。

摘要

:如果检索结果包含多个文档,为了节省成本,可以把这些文档的摘要版本输入LLM。这样既能提供上下文,又能降低幻觉发生的概率。

“中间迷失”(Lost in the Middle)综合症

:当LLM面对较大的上下文窗口时,会表现出一种“中间迷失”的行为——它会更关注开头和结尾的信息,而中间部分容易被忽略。为了避免这种情况,可以在输入前对数据做几次重新排列。

多样性排名

:按照文档内容的多样性来排序,越多样化的文档越靠近,让LLM得到更均衡的信息分布。这种方法期望LLM生成一个更加平衡、多样化的答案,更贴近查询需求。相关实现可以参考Cohere的重新排名器,以及一些关于检索器和重新排名器的优秀博客。