简介:本文从定义、背景、核心组成、工作原理、典型场景和注意事项等方面,系统讲解RAG检索增强生成系统。读者可以理解为什么大模型需要外部知识库支持,如何通过文档分块、向量化和相似度检索减少无关信息干扰,以及在实际搭建RAG系统时需要关注哪些关键设计点。
RAG,全称为检索增强生成,是一种将信息检索与文本生成结合起来的技术方法。它的核心定义可以概括为:在语言模型生成回答之前,先从外部知识库中检索与当前问题最相关的文档片段,再将这些片段作为上下文输入给语言模型,从而提升回答的准确性、时效性和可解释性。
从技术视角看,RAG并不是一个单一的算法,而是一套由文档处理、向量表示、相似度检索和生成式模型共同组成的系统流程。从业务视角看,RAG解决的是“大模型不知道你手里有什么资料”的问题。企业或开发者往往拥有大量内部文档、产品说明、制度规范或技术资料,这些内容可能没有出现在语言模型的训练数据中,也可能更新频繁,无法每次重新训练模型。RAG允许系统在不重新训练模型的前提下,让模型能够“按需查询”这些资料并基于资料回答。
从使用视角看,RAG给用户带来的直接体验是:模型不再只依赖自身记忆生成内容,而是能够引用具体材料、给出更贴合实际场景的回答。对于知识库型应用、客服系统、企业问答助手等场景,这种能力尤为关键。
在没有RAG的情况下,常见做法是把整篇文档写入提示词中,再让语言模型根据这些内容回答。当文档规模较小时,这种方式可以工作;但当文档较大或知识库较丰富时,会产生几个明显问题。
首先是成本问题。语言模型的输入通常按令牌数量计费,频繁传入长文档会造成大量资源消耗。很多情况下,回答一个简单问题只需要文档中的一小段内容,却需要把整篇文档作为输入,这既不经济,也不高效。
其次是效果问题。过多无关信息会增加模型产生幻觉的概率。语言模型在面对冗长上下文时,容易出现“Lost in the Middle”现象,即对开头和结尾的信息记忆较好,而中间部分容易被忽略。这意味着即使把关键信息放在文档中部,也可能无法被有效利用。
第三是语境干扰。人类在阅读时也会受到无关信息干扰,语言模型同样如此。如果提示词中混入大量与当前问题无关的材料,模型可能被其他主题的表述带偏,生成偏离用户意图的回答。
RAG的思路改变了信息传递方式。它不再要求用户一次性提供所有背景材料,而是由系统在需要时检索最相关的内容。这种“按需取用”的方式,既降低了输入长度,也减少了上下文中的噪声,使模型可以专注于当前问题真正需要的证据材料。
一个基础的RAG系统通常包含离线构建和在线查询两个阶段,以及若干关键模块。
离线阶段负责将已有文档转换为可检索的形式,主要包括文档加载、文本分块、向量化和存储四个步骤。
文档加载是指从不同来源读取原始文本,例如本地文件、网页、数据库记录或办公文档。不同来源的数据格式差异较大,需要在加载阶段完成解析和文本提取。
文本分块是RAG效果的重要影响因素之一。分块的目标是把长文档切成若干较小的单元,使每个单元内容相对独立,便于后续检索。常见的分块策略包括:
例如,如果一份文档按小点列举内容,可以将每个小点作为一个独立分块。下面是一个通用示例,展示如何按某个特殊标记进行切分:
from pathlib import Pathfrom typing import Listdef load_rag_chunks(doc_path: Path) -> List[str]:"""读取文档,并按指定分隔标记切分为RAG分片。"""text = doc_path.read_text(encoding="utf-8")# 假设文档中每个独立条目以特定标记开始,例如“【”chunks = [chunk.strip() for chunk in text.split("【") if chunk.strip()]return chunks
该示例仅用于说明分块逻辑,实际系统中需要根据文档格式选择合适的分隔规则。
向量化是将文本块转换为数值向量的过程。向量可以理解为文本在语义空间中的坐标。语义相近的文本,其向量在空间中的距离也较近;语义无关的文本,其向量距离相对较远。通过专用嵌入模型对文本进行编码,可以得到能表达语义信息的向量表示。
存储是将生成的向量及对应文本写入向量数据库。向量数据库支持基于向量距离或相似度的快速检索,与传统关系型数据库基于精确匹配的查询方式不同,它更适合语义搜索场景。
在线阶段处理用户请求,主要包括问题向量化、相似度检索和上下文生成三个步骤。
当用户提出问题时,系统首先使用与离线阶段相同的嵌入模型将问题转换为向量。接着,在向量数据库中查询与问题向量最接近的若干文档分块。查询返回的通常是向量相似度最高的前K个结果,K值可以根据实际需要调整。最后,将这些文档分块与用户问题一起组合成提示词,交给语言模型生成回答。
整个过程可以用以下流程概括:
RAG之所以有效,是因为它把“记忆”和“查询”两种能力结合了起来。语言模型本身存储了大量训练阶段学到的知识,但这些知识存在截止时间和覆盖范围限制。RAG通过外部检索,让模型在生成回答时可以访问最新、更具体的资料。
从语义匹配的角度看,RAG克服了传统关键词搜索的局限。例如用户问“如何理解机器学习中的过拟合”,关键词搜索可能只会匹配包含“过拟合”或“机器学习”这些词的文档,而RAG基于向量相似度,还能找到包含“模型在训练集表现很好但在测试集表现差”这类语义相近但用词不同的内容。这种语义扩展能力使得检索结果更加全面。
从生成质量的角度看,RAG为语言模型提供了可依赖的证据材料。模型不再需要从记忆中“回忆”可能已经遗忘或混淆的信息,而是直接阅读给定的文档片段并基于此作答。这种方式显著降低了幻觉产生的可能,尤其适用于需要精确引用或更新频繁的知识场景。
企业通常积累大量内部资料,包括产品文档、规章制度、操作手册和常见问题记录。RAG可以将这些资料构建成可检索的知识库,让员工通过自然语言提问获得答案,而不必逐一翻阅文件。
客服场景中,大量用户咨询具有相似性。通过RAG,系统可以从历史工单或产品文档中检索相关处理方案,辅助客服人员快速回复,或直接由对话机器人给出参考解答。
开发者文档通常规模庞大、结构复杂。RAG可以帮助用户在文档站中以自然语言描述问题,系统自动检索相关章节并生成针对性说明,减少用户查找成本。
在需要基于大量报告、新闻或研究材料生成摘要或结论的场景中,RAG可以先检索与主题最相关的内容,再由模型整合生成,避免处理海量无关信息。
微调是在已有模型基础上,使用特定任务数据继续训练模型参数。微调改变的是模型本身,而RAG不改变模型参数,只改变模型获取信息的方式。微调更适合让模型掌握某种稳定的输出格式或特定领域语言习惯;RAG更适合需要频繁更新知识库或引用具体资料的情况。两者可以结合使用,但并不互相替代。
提示词工程通过设计更有效的提示词来激发模型已有能力,不涉及外部数据检索。RAG则引入了外部知识源,使模型能访问训练时没有的信息。即便提示词写得再好,如果模型训练数据中没有相关知识,也难以给出准确回答,这正是RAG补足的部分。
关键词搜索基于字符串匹配,计算方式简单,但无法处理同义替换、近义表达或跨语言语义。向量搜索通过语义向量进行相似度计算,能识别语义相近但用词不同的内容。不过向量搜索也并非万能,对于精确编号、专有代码等场景,关键词或混合搜索可能更可靠。
不同文档结构适合不同分块方式。例如,按条目列举的规范类文档适合按条目切分;叙述性长文可能适合递归分块或语义分块。分块过大容易引入噪声,分块过小又可能丢失完整上下文。实际项目中往往需要通过实验确定合适的分块大小和重叠策略。
嵌入模型的质量直接影响语义匹配效果。不同模型在中文、英文、长文本或垂直领域上的表现可能差异较大。建议根据业务语言和内容特点选择适合的嵌入模型,并保持离线入库和在线查询使用同一模型,否则向量空间不一致会导致检索失效。
检索返回的文档数量过少,可能遗漏关键信息;数量过多,则可能重新引入无关噪声。相似度阈值也需要根据业务场景调整,过高会过滤掉一些语义相关但表述不同的片段,过低则可能纳入弱相关甚至不相关内容。
即使检索结果准确,如果提示词设计不当,模型仍可能忽略给定材料或生成偏离要求的内容。应在提示词中明确说明回答必须基于提供的资料,并在资料不足时告知用户“未找到相关内容”,而不是强行编造。
随着文档规模增长,向量检索的延迟和存储成本会上升。需要评估向量索引类型、维度压缩方案以及缓存策略。对于更新频繁的文档,还要设计增量更新机制,避免每次全量重建。
在企业应用中,不同角色可能只能访问部分文档。RAG系统需要与现有权限体系结合,在检索阶段就进行权限过滤,避免用户通过提问获取无权查看的内容。
RAG是一种将外部知识检索与语言模型生成相结合的技术方法。它通过文档分块、向量化和相似度检索,使语言模型能够在回答时获取与问题最相关的资料,从而减少上下文噪声、降低幻觉风险,并让知识库可以独立更新而无需重新训练模型。理解RAG,不仅要掌握其流程,还要根据具体场景合理设计分块策略、选择嵌入模型、优化检索参数和控制输入质量。对于希望让大模型使用自有文档、内部知识或实时资料的开发者和企业来说,RAG是一个基础且实用的工程方案。