首页 > 教程攻略 > ai资讯 >RAG实践中的关键模块解析

RAG实践中的关键模块解析

来源:互联网 时间:2026-07-31 13:55:22

RAG(检索增强生成)这个概念,最早是Meta在2020年那篇著名的《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》里提出来的。简单说,就是让大模型不局限于自己脑子里那点东西,能从外部知识库里现查现用。在大模型时代,这招儿简直是解决幻觉问题、知识过时、处理超长文本这些系统级问题的“标配”技术了。

RAG的挑战

不过,理想很丰满,现实很骨感。RAG真正落地的时候,挑战主要集中在三个环节:检索够不够准、增强过程够不够顺、生成质量够不够好。

检索质量

  • 语义歧义

    :最典型的例子,“苹果”到底是指水果还是那个科技公司?向量表示有时候就是会犯这种糊涂,把概念搞混,结果就是搜出一堆不相干的东西。
  • 用户输入变复杂

    :现在用户的提问不再是几个关键词了,而是整段整段的自然对话,还可能带着多轮上下文,口语化很严重,这让传统的关键词搜索逻辑直接失效。
  • 文档切分

    :这是个很有意思的技术活。是按标点符号、段落切,还是按语义来切?切完的“块”怎么变成机器能懂的向量?这些细节直接决定了后面匹配的准头。
  • 多模内容的提取及表征

    :现实世界里的文档,谁还没个表格、图表、公式啊。怎么把这些非纯文本的内容也提取出来、表达清楚,是个很现实的问题,尤其是在处理一些模糊、否定的查询时,影响特别大。

增强过程

  • 上下文的集成

    :查到的资料和当前要生成的任务怎么无缝衔接?弄不好,生成出来的内容就跟拼接似的,前言不搭后语,缺乏连贯性。
  • 冗余和重复

    :要是搜出来的几段话都讲着差不多的信息,那生成的时候很可能就会车轱辘话来回说,内容冗余。
  • 排名和优先级

    :搜出来一堆东西,到底哪个对当前任务最重要?怎么给它们排个优先级?增强过程得学会给每段信息“掂量掂量”分量。

生成质量

  • 过度依赖检索内容

    :模型有时候会走到另一个极端,就是太“信”搜到的资料了,自己反而没了主见,甚至会把检索结果里的错误也一并“消化”了,加剧幻觉。
  • 无关性

    :更让人头疼的是,生成的答案根本解决不了用户问的问题,答非所问。
  • 毒性或偏见

    :这就不用多说了,生成的内容有害或者带有偏见,是绝对要避免的。

整体架构

面对这么多挑战,一个健壮的RAG系统应该是什么样的?我们来看看一个典型的分层架构。

产品架构

放眼望去,整个产品架构大致分四层:

  • 模型层

    :这是地基,要能屏蔽掉不同模型(比如自研的序列猴子、各种开源模型、第三方API)的差异。同时,为了搞定向量的跨语言检索问题,还得专门搞出一个跨语言的Embedding模型。
  • 离线理解层

    :这是“后勤部”,核心是做两件事。一是搞个智能知识库,把非结构化的文本(PDF、表格、图片里的文字等)进行解析、打标、入库。二是做搜索增强,通过问句改写、重排这些小技巧,先把检索的精准度提上来。
  • 在线问答层

    :这是“前线”,要直接面向用户,必须支持多文档、多轮对话、多模态问答,还得做好安全性和拒识,用户体验和竞争力都靠这一层了。
  • 场景层

    :针对不同行业(比如金融、医疗、法律),预制好相应的角色和模板,降低用户的使用门槛。

技术架构

如果从技术实现的角度来看,RAG的核心可以拆成三个部分:Query理解、检索模型和生成模型。

  • Query理解

    :这个模块的使命是搞清楚用户到底想问什么,然后把问题“翻译”成系统能高效执行的结构化查询。它涵盖了Query改写、扩写和意图识别等子模块。
  • 检索模型

    :它的任务是从知识库里把最相关的信息“捞”出来,技术核心就是文档加载、文本转换、Embedding和向量检索。
  • 生成模型

    :给定Prompt和检索到的上下文,生成最终的、连贯且有价值的答案。这里面包括聊天系统(短期/长期记忆管理)、Prompt优化等。

说白了,RAG就是让检索的“准确”和生成的“创意”互补,用知识库给大模型“打底”,让它说话更有根有据。

Query理解

很多RAG系统效果不好,根子就在Query理解上。用户提问的方式可能不适合检索,或者需要从问题里提取出结构化的查询条件。所以,我们得在这里下功夫。

意图识别

简单说,就是判断用户想干什么。比如,用户是想要一段摘要,还是要一个具体的答案?这通常可以用LLM来做决策(把各种选择都塞到Prompt里让它选),也可以单独训练一个传统的分类模型(比如基于Bert的意图分类器)。它的应用场景很广,比如决定从哪个数据源查、该用摘要还是搜索策略、要不要同时试好几个方案。

Query改写

原始的用户问题,往往不是最优的检索词。所以,我们要利用LLM来“润色”一下。

  • HyDE

    :这个想法很巧妙。它先让LLM根据问题生成一个“假设的”完美答案,然后用这个假设答案的向量去搜真实文档。因为假设答案的语义空间和文档更接近,所以往往能搜到更相关的东西。
  • Rewrite-Retrieve-Read

    :这个框架更直接,就是拿LLM来改写查询。它还训练了一个小模型(比如T5)专门干这个活儿,甚至用强化学习来优化改写的策略,目标是让改写后的query在后面的检索和生成环节表现更好。

Query扩写

遇到复杂问题怎么办?“分而治之”是个好办法。把一个大问题拆成几个小的、更具体的子问题,分别去搜,最后再把结果组装起来。

  • Step-Back Prompting

    :这个方法鼓励LLM“后退一步”,先抽象出问题的更高层级概念。比如问你“水温是多少”,它可能先抽象成“水的物理性质”,然后用这个抽象概念和原问题一起去搜,效果往往更好。
  • CoVe

    :Chain of Verification。它让LLM自己给自己“挑错”。先生成一个初步答案,然后围绕这个答案生成一系列的验证问题,去搜知识库来验证,最后修正答案。这就好比让模型有了自我纠错的能力。
  • RAG-Fusion

    :一个简单粗暴但有效的方法。让LLM生成多个不同角度的子查询,然后并行搜索,最后用一个叫“倒数排名融合”的算法把结果排序合并,能覆盖更广的知识面。
  • ReAct

    :这是把推理和行动结合起来的经典范式。模型可以一边推理(CoT),一边执行动作(比如搜索知识库),根据搜索回来的信息再更新推理,循环往复,直到解决问题。

Query重构

在实际的pipeline里,我们把这些思想综合起来,自研了一个“Query重构”模块。只需要一次请求,就能把用户的复杂问题同时完成改写、拆解和拓展,挖掘出更深层次的子问题,一举解决复杂问题检索不准的痛点。

检索模型

检索模型的挑战

检索这个环节,挑战也很直接:Embedding模型向量化得准不准?文档切分得合不合理?还有,当把搜到的内容拼接成Prompt送给大模型时,它能不能在长上下文中“一眼”就定位到真正有用的信息?《Lost in the Middle》那篇论文就专门指出过,大模型对长上下文中间位置的信息很“迟钝”,放在开头或结尾的信息才容易被它采纳。

文档加载器

这个模块负责把各种来源(.txt文件、网页、甚至YouTube视频的字幕)的文档数据加载进来,变成文本和元数据。它还支持“懒加载”,避免一下子把所有东西都塞到内存里。

文本转换器

加载进来的文档不能直接用,得先“切块”。这个切块是个技术活,理想情况是把语义相关的片段放在一起,还要控制块的大小,确保能塞进模型的上下文窗口。常见的切分方式有:按字符递归切分(最推荐)、按HTML/Markdown标签切分(能保留结构化信息)、按代码语言切分、甚至按Token数量切分。有个叫Chunkviz的开源工具可以帮你可视化这个过程,调整参数。

文本嵌入模型

这是将文本转化为向量表示的核心。一个理想的嵌入模型,应该具备跨语种关联能力(比如“苹果”和“Apple”),能把长原文和短摘要关联起来,能把不同表述但语义相同的文本关联起来,能把问题和可能的答案文本关联起来。更重要的是,检索出来的结果,越靠前的越有用,最好还能自动过滤掉低质量的片段。

向量数据库与索引

数据处理好后,就要建立索引来支持快速检索了。常见的索引结构有:摘要索引(按顺序存)、树索引(构建层级摘要树,便于高层检索)、关键词表索引(建立关键词到文档块的多对多映射)、以及目前最主流的向量索引(用向量相似度来匹配)。

排序和后处理

搜出来一堆结果,总得排个队吧。常用的策略有:按相似度分数过滤、按关键词过滤、让LLM自己给结果打分重排、按时间过滤、或者按时间对相似度加权排序等等。

生成模型

回复生成策略

拿到检索出来的文本块,怎么喂给大模型生成回答?有两种常见思路:一种是“吃一口,想一步”,每拿一个块就让大模型修正一次答案;另一种是“吃饱再想”,一次性把所有块都塞进Prompt,让大模型一次性生成。实践中也可以组合使用。

Prompt拼接策略

如何把系统指令、检索到的文档、历史对话和用户问题组装成一个有效的Prompt?常用的有字符串提示(直接把所有模板拼起来)和聊天提示(按消息列表来组织,比如SystemMessage, HumanMessage, AIMessage等)。

基于混合演示检索的上下文学习

这个听起来有点绕,其实就是在做RAG的时候,不仅检索知识库,还检索“过往的成功问答案例”(示范性示例)。把和当前问题最相似的几个问答对也一起塞进Prompt,让大模型模仿着回答。但问题来了,怎么找到最合适的示例?单靠一种检索方法(比如纯语义检索或纯文本检索)效果不够好。

我们的解法是搞了一个“混合检索+重排”的插件模块。

检索模块

采用多路召回。语义检索用双塔模型(比如OpenAI的embedding-ada),文本检索用BM25。这样既能捕捉语义相似,又能确保关键词匹配,互补短板。

重排模块

多路召回的结果怎么融合?不同算法的分数区间不一样,不能直接比。我们引入了一个很有效的融合算法——倒数排名融合。它不看分数,只看排名,把各个算法给候选示例的排名位置综合起来,算出个新分数。然后,考虑到大模型“偏食”开头和结尾的特点,我们不是简单地按新分数排序,而是把结果“两头填”。比如排好的12345,重排后变成13542,确保最重要的信息被放到大模型最容易看到的两端。

生成模块

最后,把重排好的示例、系统Prompt、长期/短期对话记录、以及用户当前问题,一起组装成一个Prompt,送给大模型生成最终的答案。

引用或归因生成

让模型“说人话”还不行,还得让它“有理有据”。归因,就是让生成的答案能指向知识库中的具体来源,这不仅能提高用户的信任感,也是减少幻觉的有效手段。

如何实现?目前主要有两种做法。一种是

模型生成

,在Prompt里直接要求模型“每个观点后面都要注明来源”。这个方法最直接,但对模型的指令遵循能力要求极高,而且很容易自己编造引用。另一种是

动态计算

,在模型流式生成的同时,实时地让生成的句子和参考源进行匹配(用关键词或向量相似度),找出最可能的来源并附上。这种方法更可控,badcase修复周期也短,但依赖一个好的匹配阈值,并假设模型生成的文本确实来源于参考信息。

评估

做开发的同学都听过TDD,做AI应用也得有MDD(指标驱动开发)的意识。理想情况是先把场景、数据、指标、目标分值都定好,然后一步步实现。但现实往往是场景不清、数据难洗、指标没想过。

那该怎么量化证明你的RAG系统比别人的牛?核心要关注这几个方面对系统性能的影响:位置偏见(大模型偏爱开头和结尾),检索内容的相关性(不相关的内容就是噪音)。

评测指标

  • Faithfulness

    :生成的回答是否忠实地基于检索到的上下文?这是避免幻觉的关键。
  • Answer Relevance

    :生成的答案是否真正解决了用户提出的问题?
  • Context Relevance

    :检索到的上下文是否足够精炼,尽可能少地包含无关信息?冗余信息越少,相关性越高。

评测方法

  • RGB

    :系统地评估LLM在噪声鲁棒性、拒答能力、信息整合和反事实鲁棒性这四项基本能力上的表现。
  • RAGAS

    :提供一个无需参考答案的评估框架,从检索、利用和生成质量三个维度打分,已经开源。
  • Llamalindex-Evaluating

    :LlamaIndex提供了衡量生成和检索质量的模块,非常实用。

总结

大模型这波浪潮,催生出来的技术细节实在太多了。从Query理解到检索,再到生成和评估,每个环节想要做到极致、符合企业级应用,都需要花很长时间去研究、去实践、去打磨。这篇文章就是我们团队在过去一年RAG实践中的一些核心模块总结,希望能给你带来一些启发。