简介:文章围绕检索增强生成(RAG)这一技术概念展开,从其定义、产生背景、核心组成、工作原理到典型应用场景进行了系统梳理。通过一个基于开发规范文档构建简易RAG流程的示例,说明文本分块、向量化、相似度检索与生成增强之间的关系,帮助读者理解为什么大语言模型需要外部知识介入,以及如何在工程实践中规避常见问题。
检索增强生成(Retrieval-Augmented Generation,简称RAG)是一种将信息检索机制与大语言模型生成能力相结合的技术范式。其核心思想是:在用户提出问题之后、由语言模型生成最终回答之前,先从外部知识库中检索出与问题最相关的文本片段,再将这些片段作为上下文提供给语言模型,从而引导模型基于可靠资料进行回答,而不是只依赖模型参数中固化的知识。
从本质上看,RAG并不是某一种具体的算法或产品,而是一套由“检索模块”和“生成模块”共同协作的架构方法。它的目标非常明确——让语言模型在回答问题的时候,能够“临时查阅”外部资料,而不是仅靠训练阶段记住的信息。
如果一个用户提问:“AI是什么?”如果没有RAG机制,模型只能根据自身已有的知识进行回答,既可能过时,也可能不够精确。而在RAG系统中,系统会先从知识库中检索出与人工智能、深度学习、机器学习等概念相关的资料片段,再把这些片段连同问题一起交给语言模型,由模型综合外部资料生成答案。这正是RAG名称中“增强”二字的含义:外部检索为模型生成提供了增强信息。
大语言模型虽然具备很强的语义理解和文本生成能力,但存在几个难以回避的局限。
第一,模型知识是静态的。语言模型在训练完成之后,其参数中记住的知识就固定下来了。对于训练截止日期之后出现的新信息、新政策、新事件,模型无法自然获知。
第二,模型在缺乏外部知识时容易产生“幻觉”。当被问到某个非常具体、生僻或需要精确依据的问题时,模型有时会生成看起来合理、实际上错误的内容。这种错误对于资料查询、技术支持、法律咨询等场景会造成严重误导。
第三,模型难以回答私有知识。企业内部文档、项目资料、操作手册、内部规范等内容不属于公开训练数据,模型不可能在训练阶段见过。直接使用大语言模型时,这类私有知识无法进入回答范围。
RAG的价值正是在于解决这些问题。它把“检索”引入生成流程,使得语言模型在回答问题时可以基于最新、准确且可追溯的外部资料。知识库可以按需更新,而无需重新训练模型;模型回答的依据也可以定位到具体的文档片段,提高了可解释性。
从工程角度来看,RAG把“知识维护”与“文本生成”解耦。知识内容存储在外部的文档或数据库中,生成模型则专注于理解和表达。这种解耦让系统能够灵活应对知识变化,也降低了对模型训练数据进行持续更新的依赖。
一个典型的RAG系统由多个相互配合的模块组成。每个模块承担不同职责,整体形成一个从文档准备到最终回答生成的完整链路。
RAG系统的起点是知识来源。知识来源可以是本地文档、网页、数据库记录、PDF文件、Markdown文件、办公文档等。文档加载层的任务是将这些不同格式的内容读取到系统中,统一转换成后续可以处理的文本格式。
原始文档可能很长,直接整篇放入检索单位并不合适。一方面,语言模型能够接收的上下文长度有限;另一方面,检索引擎也更擅长在短小、主题集中的片段之间进行匹配。因此,需要把长文档切分成若干较小的文本块。
常见的分块策略包括:
分块质量对整个RAG系统的效果影响很大。分块过大,可能带入大量无关信息,干扰模型判断;分块过小,又可能丢失上下文,导致检索结果不完整。
向量化是将文本块转换成高维空间中坐标向量的过程。其背后的基本假设是:语义相近的文本,在向量空间中距离更近。
例如,一段关于“软件开发规范”的文本和一段关于“代码评审要求”的文本,即使二者在字面上没有大量重叠,但如果它们表达的是相近主题,经过向量化之后得到的向量应当比较接近。
向量模型的选择直接影响语义表达质量。不同的向量模型对同一种语言、同一类文本的理解能力不同,工程中通常需要根据语料类型和语言选择合适模型。
文本块被转换成向量之后,需要存储到能够支持向量检索的数据库中。与传统关系型数据库通过等值匹配或关键词匹配不同,向量数据库更适合根据向量之间的相似度进行查询。
当用户提出问题时,系统把问题同样转换为一个向量,然后在向量数据库中查找与问题向量最接近的若干个文本块。常用的相似度度量方式包括余弦相似度、内积和欧氏距离等。检索结果按照相似度从高到低排序,通常取最靠前的若干条作为候选上下文。
检索到的文本块需要与用户的原始问题组装成新的输入,再交给语言模型。组装方式通常是将问题放置在开头,把检索到的资料放在问题之后或之前,并明确提示模型“请基于以下资料回答问题”。
语言模型在这个阶段看到的不只是用户问题,还包括一组经过初步筛选的相关资料。模型根据这些资料组织语言,生成最终回答。回答内容因此更可能贴近知识库中的真实信息。
下面通过一个具体示例说明RAG的工作流程。假设一个团队希望构建一个基于内部开发规范的问答助手,知识库中的内容来自一份开发手册。
整个流程可以分为两个阶段:离线构建阶段和在线查询阶段。
离线阶段的目标是提前准备好可被向量检索的知识材料。
第一步是加载文档。比如开发手册可能是一个文本文件,需要读取其中内容并去除无关字符。
第二步是分块。如果手册中的内容是以条目方式组织的,例如每条规则前都有明确的编号或标记,那么可以利用这些标记进行分块。比如某份开发手册中,每个独立条款以全角方括号“【”开头,此时可以按照“【”出现的位置进行切分,使每个分块对应一条相对独立的规范。
示意代码如下:
from pathlib import Pathfrom typing import Listdef load_rag_chunks(doc_path: Path) -> List[str]:"""读取文档并按条目标记切分为文本分块。"""raw_text = doc_path.read_text(encoding="utf-8")chunks = []current_chunk = []for line in raw_text.splitlines():# 以条目标记作为新分块的起点if line.startswith("【"):if current_chunk:chunks.append("".join(current_chunk))current_chunk = [line]else:current_chunk.append(line)if current_chunk:chunks.append("".join(current_chunk))return chunks
第三步是将每个分块向量化,并把向量及其对应的原始文本一起写入向量数据库。向量化过程可以理解为把文本块送入一个经过预训练的语义编码模型,从而得到一组浮点数表示。
第四步是保存映射关系。数据库中不仅要保存向量,还要保存原始文本内容以及可能的来源信息,以便后续检索时能够把向量对应的文本取出来交给语言模型。
在线阶段发生的动作如下:
请根据以下资料回答用户问题。如果资料中没有相关信息,请明确说明。资料:1. 【命名规范】类名使用大驼峰命名法,方法名使用小驼峰命名法……2. 【常量定义】常量名全部大写,单词之间用下划线分隔……3. 【包名规范】包名统一使用小写字母……用户问题:开发手册中关于命名规范有什么要求?
在这个流程中,语言模型没有直接从自己的参数记忆中“回忆”开发手册,而是从外部知识库中获取了相关条目。因此回答更容易与手册保持一致。
需要特别说明的是,RAG之所以要使用向量数据库和语义相似度检索,是因为用户的问题与知识库中的表述往往不会完全一致。
例如用户问的是“AI是什么?”,但知识库中保存的可能是“人工智能是一门研究如何让机器模拟人类智能的学科”,以及“深度学习是机器学习的一个分支”。这些文本在字面上与“AI”三个字母并不完全相同,但在语义上高度相关。向量检索能够捕捉这类语义关联,而传统的关键词检索很难覆盖这些情形。
RAG已经在多种需要知识问答、资料查找和内容辅助生成的场景中得到应用。
企业内部通常积累了大量制度文档、操作手册、技术规范、培训资料等。员工在遇到具体问题时,需要从这些文档中寻找答案。RAG可以把这些资料构建成可检索的知识库,员工用自然语言提问,系统从文档中查找相关片段,并由语言模型归纳出答案。
这类场景对答案的准确性要求很高。RAG的价值在于回答可以追溯到具体文档片段,降低了模型凭空编造的风险。
在客服系统中,客服人员或对话机器人需要根据产品说明、售后政策、常见问题列表等资料来回答用户。RAG能够帮助机器人从大量支持文档中检索出与当前问题最相关的内容,再基于这些内容生成回复。
开发人员面对框架用法、配置方式、接口含义、错误排查等问题时,RAG可以从内部Wiki、代码文档或运维手册中获取相关资料,辅助开发人员定位问题。相比于依赖模型自身可能过时的知识,基于文档检索的答案更具现实参考价值。
在需要基于指定资料生成摘要、报告或说明文档时,RAG可以先检索出与写作主题相关的资料片段,再交给语言模型进行整合与扩写。这样生成的内容更贴合给定素材,减少了无依据发挥。
微调是在已有语言模型基础上,使用领域数据对模型参数进行继续训练,从而让模型掌握新的知识或任务能力。RAG则不需要修改模型参数,而是通过检索机制动态引入外部知识。
两者的主要区别在于知识更新方式和资源消耗。微调需要准备训练数据并消耗训练资源,更新知识时通常需要重新训练或继续训练;RAG只需要更新外部知识库,生成模型本身可以保持不变。与此同时,微调后的模型可能对训练数据产生记忆,但难以回答训练数据之外的内容;RAG则更擅长动态获取最新资料。
传统关键词搜索依赖于词形匹配或字符串匹配,例如查找同时包含“人工智能”和“定义”的文档。RAG使用向量检索,更关注语义层面的相似性。即使两个文本在字面上没有多少重合,只要表达相似含义,也有机会被检索到。
当然,关键词检索速度快、可解释性强,在一些精确匹配场景中仍有优势。实际系统中也可能将关键词检索与向量检索结合,组成混合检索策略。
部分语言模型支持很长的输入上下文,因此有一种做法是把大量文档直接放入提示词中,让模型自行查找信息。这种方式在文档规模较小时简单有效,但当知识库很大时,不可能把所有内容都放入上下文。RAG通过先检索再组装,可以在有限上下文窗口里放入最可能相关的资料,从而兼顾知识覆盖范围和上下文约束。
不同文档结构差异很大。规范类文档可能适合按条目分块,技术手册可能适合按章节分块,而会议记录或新闻文章可能需要按段落甚至按句分块。分块之前应先分析文档结构,尽量让每个分块包含一个相对完整的语义单元。
向量模型的质量直接影响检索效果。如果知识库以中文为主,就应选择对中文语义理解较好的向量模型;如果涉及特定行业术语,需要关注向量模型是否对相关领域有较好泛化能力。向量维度、模型规模与检索性能之间也需要权衡。
检索返回的文本块数量不能太多也不能太少。检索太少可能导致遗漏关键信息;检索太多则会带入大量噪声,干扰语言模型判断。实际使用中通常需要根据问题类型、分块大小和模型上下文长度进行调整。必要时可设置相似度阈值,过滤掉相关性过低的候选块。
语言模型在获得检索资料后,需要明确知道如何利用这些资料。提示词中应清晰说明“请基于资料回答”“如果资料中没有相关信息,请如实说明”等约束。否则模型可能忽略资料,或仍按照自身记忆作答。
知识库可能包含敏感信息。在设计RAG系统时,需要考虑文档访问权限,确保用户只能检索到其有权查看的内容。同时在将资料送入语言模型时,也要关注数据流向和处理方式,避免敏感信息被不当传递或留存。
RAG系统上线前需要评估检索质量和生成质量。检索环节可以关注召回率、命中率等指标,生成环节可以考察答案是否忠于资料、是否完整清晰。随着知识库更新与用户问题变化,分块方式、向量模型和提示词设计可能都需要持续调整。
RAG是一种把检索与生成紧密结合的技术方法。它通过让语言模型在回答问题前先从外部知识库中查找相关资料,缓解了模型知识陈旧、容易产生幻觉、无法使用私有知识等问题。一个基础的RAG系统包括文档加载、分块、向量化、向量检索和上下文生成等关键流程,这些流程分别解决知识结构化、语义匹配和生成增强等具体任务。
理解RAG的关键,在于理解它并不是让模型“记住”更多知识,而是为模型提供一种“临时查阅”的能力。检索模块负责找到可能相关的资料,生成模块负责基于资料组织表达。这种分工使得系统能够灵活应对知识更新,也更适合需要可追溯、可验证答案的企业级应用场景。对于开发者而言,在设计RAG系统时需要重点关注文档结构、分块方式、向量模型选择、检索数量控制和提示词设计等环节,才能真正发挥检索增强生成的价值。