1. 从"大模型胡说八道"说起:RAG到底在解决什么问题
但凡真正把大模型接入过业务系统的人,大概率都经历过这样一个阶段:模型在演示环境里对答如流,一旦上线面对真实用户提问,就开始一本正经地编造事实。问它某份内部文档里的具体条款,它能给你编出一条根本不存在的规则,语气还特别笃定。这个现象在业内叫"幻觉",它不是模型坏了,而是大模型的工作机制决定的——它本质上是在做"下一个词的概率预测",而不是在查数据库。
我最早接触RAG这个概念的时候,也走过一段弯路。当时第一反应是"那我直接把文档内容塞进提示词不就行了",结果发现文档一长,模型要么开始忽略中间部分的内容,要么直接超出上下文长度限制。后来才明白,RAG(Retrieval-Augmented Generation,检索增强生成)要解决的核心矛盾,就是大模型的参数化知识是静态的、模糊的、有截止日期的,而真实业务需要的知识是动态的、精确的、私有的。
打个比方,大模型像一个博览群书但记性不太靠谱的专家,你问他问题,他能聊得头头是道,但具体到"我们公司上个月那份合同第三页写了什么",他只能靠猜。RAG做的事情,就是给这位专家配一个随叫随到的资料员:你提问的时候,资料员先去档案室把最相关的几页资料找出来,递给专家,专家再基于这几页真实资料来回答。这样既保留了大模型的语言组织和推理能力,又把事实依据锚定在了真实文档上。
这套思路的价值在于,它绕开了两个成本极高的方案:一是重新训练或微调模型(贵、慢、每次知识更新都要重来),二是把全部知识硬塞进上下文(受长度限制、贵、效果随长度衰减)。RAG用"检索"这个外挂,让知识更新变成了"更新文档库"这么一件低成本的事。
那么这套教程适合谁看?我的判断是三类人:第一类是想把大模型落地到具体业务、但被幻觉问题卡住的开发者;第二类是手里有一堆文档资料、想让它们"活起来"可被问答的产品或运营同学;第三类是想系统理解RAG全链路、而不是只会调一个API的进阶学习者。接下来我会按照"原理—构建—检索—评估"这条主线,把每个环节里真正会踩的坑和背后的逻辑讲透。
2. RAG的功能原理:拆开看它到底由哪几块拼成
2.1 检索与生成的分工:为什么不能只做其中一半
很多人对RAG的理解停留在"先搜再答",但真正决定效果的是这两步的分工边界。检索模块负责"从海量文档里找出和问题最相关的片段",生成模块负责"把这些片段组织成通顺、准确的回答"。这两件事的能力要求完全不同:检索要的是召回率和排序精度,生成要的是语言组织和指令遵循。
如果只做检索不做生成,用户拿到的是几段原文,还得自己读、自己拼,体验很差;如果只做生成不做检索,就是前面说的幻觉问题。所以RAG的本质是一个"流水线",任何一环掉链子,最终答案都会崩。我见过不少项目,检索出来的内容其实是对的,但生成阶段模型没用好这些内容,答案依然跑偏;也见过检索阶段就找错了文档,后面生成再强也救不回来。
理解这个分工,对后面调优特别重要。当你发现答案不对时,第一件事不是去改提示词,而是先确认:检索出来的片段到底对不对。这个判断顺序能帮你省下大量瞎调的时间。
2.2 向量化:把"意思"变成可以计算距离的数字
RAG能实现"按意思搜索"而不是"按关键词搜索",靠的是向量化(Embedding)。简单说,就是把一段文本映射成一个高维空间里的点,语义相近的文本,它们的点距离就近。比如"如何申请退款"和"退款流程是什么",字面上没几个字重合,但向量距离会很近。
这里有个容易被忽略的细节:向量化模型和生成模型是两回事。你可以用A模型做向量化,用B模型做生成,它们各自独立选型。向量化模型决定了"检索的语义理解能力",生成模型决定了"回答的表达能力"。很多新手会以为用了某个大模型,检索也就自动变强了,其实不是。
向量的维度通常从几百到几千不等。维度越高,能表达的语义细节越多,但存储和计算成本也越高。实际选型时不是越高越好,要看你的文档规模和检索精度要求。我一般建议先用主流的中等维度模型跑通,再根据评估结果决定要不要换。
2.3 向量数据库:为什么不能用普通数据库存向量
向量检索的核心操作是"找和查询向量最接近的K个向量",这叫近似最近邻搜索(ANN)。普通关系型数据库擅长的是精确匹配和范围查询,做这种高维向量的相似度计算效率极低。向量数据库(如Milvus、Qdrant、Chroma、FAISS等)专门为这类操作做了索引优化,能在海量向量里快速找到近邻。
选向量数据库时,我关注三个维度:规模(几万条还是上亿条)、部署方式(本地嵌入式还是独立服务)、过滤能力(能不能在向量检索的同时按元数据过滤)。小规模场景用Chroma或FAISS这种轻量的就够了,规模上来之后再考虑独立部署的方案。别一上来就上重型方案,运维成本会让你怀疑人生。
2.4 完整链路串讲:一次问答背后发生了什么
把上面几块拼起来,一次完整的RAG问答大致经历这些步骤:
- 用户提出问题;
- 用向量化模型把问题转成查询向量;
- 向量数据库检索出最相关的N个文档片段;
- 把这些片段和原始问题一起组装成提示词;
- 生成模型基于提示词产出回答;
- 返回给用户。
看起来简单,但每一步都有大量可调参数和隐藏陷阱。比如第3步取几个片段(Top-K)?取太多会引入噪声、稀释重点,取太少可能漏掉关键信息。第4步怎么组织提示词?片段之间怎么分隔?要不要加"如果资料里没有就说不知道"这类约束?这些细节直接决定最终效果。后面几章我会逐个展开。
3. 构建一个能用的RAG系统:从文档到可检索知识库
3.1 文档加载与清洗:垃圾进必然垃圾出
构建RAG的第一步不是写代码,而是搞清楚你手里有什么文档。PDF、Word、Markdown、网页、数据库记录,格式五花八门。加载环节最常见的坑是PDF解析:扫描版PDF需要OCR,双栏排版的PDF解析出来顺序会乱,表格会被拆得七零八落。我踩过最深的坑是一份双栏学术PDF,解析出来的文本左右栏交错,检索出来的片段语义完全错乱。
清洗环节要做的事包括:去掉页眉页脚、去掉重复的导航文字、修复断行、统一标点。这些看起来琐碎,但对检索质量影响巨大。一份没清洗干净的文档,向量化之后会引入大量噪声,检索时这些噪声片段可能挤掉真正有用的内容。
提示:文档清洗没有一劳永逸的方案,建议针对每一类文档源单独写清洗规则,并且保留原始文档和处理后文档的对照,方便排查问题。
3.2 分块策略:切得好不好,直接决定检索准不准
分块(Chunking)是RAG里最被低估、也最影响效果的环节。为什么要分块?因为整篇文档太长,向量化后会丢失细节,而且检索时你希望返回的是"精确的相关片段"而不是"一整篇文档"。
分块的核心矛盾是:块太大,语义被稀释,检索不精准;块太小,上下文不完整,生成时信息不足。常见的分块方式有几种:
| 分块方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 固定长度切分 | 结构松散的文本 | 实现简单 | 容易切断语义 |
| 按段落/标题切分 | 结构化文档 | 语义完整 | 块大小不均 |
| 递归字符切分 | 通用场景 | 兼顾结构与长度 | 需要调参 |
| 语义分块 | 高精度要求 | 语义边界准 | 计算成本高 |
我个人的经验是,递归字符切分是性价比最高的起点:先按段落切,段落太长再按句子切,同时设置一个最大长度上限(比如500-1000字符)和一个重叠区间(比如50-100字符)。重叠区间的存在是为了防止关键信息正好落在切分边界上被割裂。
这里有个反直觉的点:分块不是越细越好。我试过把块切得很小(200字符),结果检索出来的片段虽然精准,但生成时因为上下文太少,模型经常答不完整。后来把块调到500-800字符,配合适度的重叠,效果明显更稳。
3.3 向量化与入库:批量处理的工程细节
分块完成后,就要把每个块向量化并存入向量数据库。这一步的工程细节不少:
- 批量处理:不要一条一条调向量化接口,要批量提交,否则速度慢且容易触发限流;
- 失败重试:网络抖动、接口超时是常态,要有重试机制;
- 元数据绑定:每个向量块要绑定来源文档、页码、章节等元数据,方便后续过滤和溯源;
- 增量更新:文档更新时,要能定位到对应的旧向量并替换,而不是全量重建。
元数据这块特别值得强调。很多新手只存向量和原文,结果用户问"这份资料是哪来的",你答不上来。把来源信息绑上去,不仅能做引用溯源,还能在检索时按来源过滤,比如"只在某类文档里搜"。
3.4 提示词组装:把检索结果"喂"给模型的正确姿势
检索出片段后,怎么组装提示词是最后一道关卡。一个常见的模板结构是这样的:
你是一个严谨的问答助手。请仅根据下面提供的资料回答问题。 如果资料中没有相关信息,请明确说明"资料中未提及",不要编造。 资料: [片段1] [片段2] [片段3] 问题:{用户问题}这个模板里有几个关键设计:角色设定让模型进入状态,**"仅根据资料"约束它不要自由发挥,"没有就说不知道"**是防幻觉的兜底。我实测下来,加上这句兜底之后,模型编造答案的概率明显下降。
片段之间要有清晰的分隔符,并且最好标注来源,这样模型在回答时能引用。另外,片段的顺序也有讲究:把最相关的放前面,因为模型对开头内容的注意力通常更强。
4. 检索环节的调优:让"找得准"成为常态
4.1 纯向量检索的局限:它并不是万能的
向量检索擅长语义匹配,但有几个明显短板。第一,对精确匹配不敏感:用户问一个具体的编号、型号、人名,向量检索可能找不准,因为它关注的是整体语义而不是字面精确度。第二,对否定和细节区分弱:"支持A功能"和"不支持A功能"向量距离可能很近。第三,领域术语:如果向量化模型没见过你所在领域的专业术语,语义理解会打折扣。
认识到这些局限很重要,因为它决定了你不能只靠一种检索方式。
4.2 混合检索:向量加关键词,取长补短
混合检索的思路是把向量检索和关键词检索(如BM25)结合起来,各取所长。向量负责语义召回,关键词负责精确召回,最后把两路结果融合排序。融合的常见方法是倒数排名融合(RRF),它不依赖两路分数的绝对大小,只看排名,鲁棒性比较好。
我实测下来,混合检索在"既有语义问题又有精确查询"的混合场景里,召回率比纯向量检索有明显提升。代价是实现复杂度上升,需要维护两套索引。所以我的建议是:先用纯向量跑通,评估发现召回不足时再上混合检索,不要一开始就过度设计。
4.3 重排序:在召回之后再做一次精挑细选
检索流程通常是"先召回一大批,再精排取前几"。召回阶段追求的是"不漏",所以Top-K会取大一些(比如20-50);但直接把这几十个片段全喂给生成模型,噪声太多。这时候就需要重排序(Rerank):用一个更精细的模型对这几十个候选重新打分排序,取最相关的几个(比如3-5个)给生成模型。
重排序模型通常比向量化模型更重、更慢,但精度更高。它和向量检索的关系,有点像"海选"和"决赛":海选要广,决赛要准。加了重排序之后,我观察到生成答案的准确率有比较明显的提升,尤其是当文档库里有大量相似内容时。
4.4 查询改写:用户问得不好,你得帮他问好
用户的提问往往很口语、很模糊,甚至带着错别字。直接拿这种问题去检索,效果自然差。查询改写就是在检索前对用户问题做一次加工,常见手段包括:
- 同义扩展:把口语化表达转成更规范的表述;
- 多查询生成:让模型基于原问题生成几个不同角度的查询,分别检索后合并结果;
- 指代消解:多轮对话里,"它""这个"指代的是什么,要还原清楚。
多查询生成是我用得比较多的一招。比如用户问"这个怎么退",模型可以生成"退款流程""退货申请方式""如何办理退款"几个查询,分别检索后合并,召回率会好很多。代价是检索次数增加,延迟上升,需要权衡。
5. 检索评估:怎么知道你的RAG到底行不行
5.1 为什么"感觉还行"是最危险的评估方式
我见过太多项目,上线前靠几个人手动问几个问题,觉得"答得还不错"就上线了。结果真实用户一用,各种奇葩问题冒出来,效果一塌糊涂。手动抽查的样本量太小,覆盖不了真实问题的分布,而且抽查的人往往知道答案、会不自觉地往对的方向引导。
科学的评估需要一套测试集:一批有代表性的问题,配上标准答案或标准来源。测试集要覆盖不同类型的问题——事实型、推理型、多跳型、无法回答型。特别是"无法回答型"问题,专门用来测模型会不会硬编。
5.2 检索质量的核心指标:命中率与排序质量
检索环节的评估,核心看两个维度:找没找到和排得对不对。
- 命中率(Recall@K):标准答案所在的片段有没有出现在前K个结果里;
- 排序质量(MRR、NDCG):正确片段排得越靠前越好。
这两个指标要分开看。如果命中率低,说明召回有问题,要调分块、换向量模型、上混合检索;如果命中率高但排序差,说明重排序环节需要优化。把问题定位到具体环节,才能对症下药。
5.3 生成质量的评估:忠实度比流畅度更重要
生成环节的评估,很多人只看"答案读起来顺不顺",这是本末倒置。RAG场景下,**忠实度(Faithfulness)**才是第一位的:答案里的每一句话,是不是都能在检索到的资料里找到依据?有没有编造?
评估忠实度的常见做法是"逐句核对":把答案拆成句子,逐句判断是否有资料支撑。这个工作可以人工做,也可以用模型辅助做。除了忠实度,还要看答案相关性(有没有答到点上)和完整性(该说的有没有说全)。
5.4 端到端评估与持续迭代:评估不是一次性工作
把检索和生成合起来看,就是端到端评估:用户拿到最终答案,满不满意。这一步最好用真实用户反馈来驱动,比如点赞点踩、追问率、人工标注。
评估不是上线前做一次就完事,而是要持续做。因为文档库在变、用户在变、模型也可能升级。我一般会维护一个"回归测试集",每次改动(换模型、调分块、改提示词)都跑一遍,确保没有把之前好的case改坏。这个习惯帮我避免了好几次"修了一个bug引入三个新bug"的惨剧。
6. 那些文档里不会写的实战经验
6.1 分块大小没有标准答案,只有适合你的答案
网上到处是"分块建议500字符""重叠建议10%"这类说法,但这些都是经验值,不是定律。真正靠谱的做法是:用你的评估集去测。同一份文档,切成300、500、800三种粒度,分别跑评估,看哪个命中率和忠实度最好。我做过这个对比实验,结论是不同文档类型的最优分块差异很大——技术文档适合小一点,叙述性文档适合大一点。
6.2 别忽视"无法回答"这个场景的设计
很多RAG系统最大的问题不是答错,而是该说不知道的时候硬答。用户问一个文档库里根本没有的问题,模型为了"显得有用",编一个答案出来,这比直接说"不知道"危害大得多。所以在提示词里、在评估集里,都要专门为"无法回答"设计。我甚至会在检索后加一道判断:如果最高相似度低于某个阈值,直接返回"未找到相关资料",不进入生成环节。
6.3 向量模型换了,整个库都要重建
这是个容易被忽略的运维细节:向量化模型一旦更换,之前入库的所有向量都失效了,因为不同模型生成的向量空间不兼容。所以换向量模型不是改一行配置的事,而是要全量重新向量化。做技术选型时要把这个成本考虑进去,别频繁换。
6.4 延迟和成本是绕不开的现实约束
RAG链路长,每一步都有延迟:向量化、检索、重排序、生成。用户等超过几秒就会不耐烦。优化延迟的手段包括:缓存高频问题的结果、并行化检索和重排序、用更轻量的模型做召回。成本方面,向量化调用和生成调用都是按量计费的,文档库越大、查询越频繁,成本越高。这些现实约束会反过来影响你的技术选型,比如是否值得上重排序、Top-K取多大。
6.5 从Demo到生产,中间隔着的是工程化
跑通一个Demo可能一个下午就够了,但要让它在生产环境稳定运行,需要补的东西很多:错误处理、限流、监控、日志、灰度发布、A/B测试。我见过太多"Demo很惊艳、上线就崩"的案例。建议在Demo阶段就把日志和监控埋好,记录每次检索的结果和生成的答案,这样出问题时才有据可查。
7. 关于RAG学习路径的一点个人体会
如果让我给刚入门的人排一个学习顺序,我会建议:先理解"检索+生成"这个基本框架,然后动手跑通一个最小可用的Demo(哪怕只有几十个文档),接着重点啃分块和评估这两块——它们是最影响效果、也最容易被跳过的。向量数据库和重排序这些,等基础跑通了再逐步加。
RAG这个方向变化很快,新工具、新方法层出不穷,但底层的那套逻辑——怎么把知识准确地找出来、怎么让模型忠实地用起来——是相对稳定的。把这条主线吃透,工具换了一茬你也能快速上手。我自己从最早的手搓检索到现在用各种框架,最大的感受就是:框架会过时,但对检索质量和生成忠实度的判断力不会过时。这套判断力,只能靠一次次实测和评估慢慢养出来。