这几年做大模型应用的人,几乎绕不开一个词:RAG。哪怕你只是用大模型做点文档问答,也会被反复建议"上RAG吧"。但真到动手的时候,很多人其实没搞清楚一件事——RAG 和大模型到底是什么关系?RAG不是某个具体的模型,也不是一个开箱即用的软件,而是一种把外部知识"接"进大模型生成流程的架构思路。这篇文章我结合自己实际做过的项目,把RAG和大模型的关系掰开揉碎讲清楚,从它解决的痛点、完整工作链路,到和微调、长上下文的边界,再到落地时踩过的坑,适合所有刚开始接触RAG、或者已经跑通Demo但不知道如何优化的朋友。哪怕你目前只是听说这个名词、还没写过一行相关代码,跟着这条思路走完,也能建立起一套完整的心智模型。
1. RAG到底在补大模型的什么短板
1.1 大模型的知识不是"不会",而是"被冻结了"
很多人都犯过一个认知错误:觉得大模型什么都知道,问不出来说明自己prompt写得不好。实际上,大模型的知识全部固化在它的参数里,训练结束的那一刻,它的"世界观"就定格了。之后发生的新闻、新出的政策、内部文档、客户提供的那份300页PDF,它统统不知道。
我经常用一个类比解释这件事:大模型像一个记忆力极好但毕业后就再也不看书的学霸。你问他课本上的内容,他能倒背如流;你问他课本出版之后才发生的事,他只能靠脑补。RAG解决的就是这个"毕业后再也不看书"的问题——每次回答前,临时塞给他几页相关的参考资料,让他现翻书再答题。
所以RAG的第一个核心价值非常朴素:为大模型提供训练语料之外的最新信息、私有信息、领域信息。你不需要重新训练它,也不需要微调它,只要在提问时把相关资料找出来、拼进去,它就能基于这些资料作答。这也是为什么"RAG知识库"这种说法会流行起来——本质上就是为大模型配了一个可以随时查阅的外部资料库。
1.2 幻觉的根源不是模型太笨,而是没有"查证"环节
关于大模型幻觉,业内有句很扎心的话:"幻觉不是bug,是特性。"因为大模型的生成机制本质是逐字预测下一个token,它在解码时并不会去核对某个事实到底存不存在。当知识模糊、提示词信息不足时,它就会用概率上"最顺畅"的内容把坑填上——这就是一本正经胡说八道的来源。
RAG解决幻觉的思路,不是让模型变得更聪明,而是在生成之前强行插入一个证据环节。你先把相关资料检索出来,作为明确的上下文给到模型,模型在生成时就有了锚点。它不再需要"猜"答案,而是可以"引用"答案。
但这里要泼一盆冷水:RAG只能显著降低幻觉,不能彻底消灭幻觉。如果检索回来的片段本身就是错的,或者多个片段之间互相矛盾,模型依然会给出错误的综合结论。所以你在设计RAG系统时,永远要把"检索质量"放在第一位,而不是指望大模型自己聪明到能从坏材料里推出好答案。
1.3 RAG是一条流水线,大模型只是最后一环
理解RAG和大模型的关系,最关键的认知转变是:RAG不是一个模型,而是一套检索-增强-生成的流水线架构。完整链路包括检索器、知识库、生成器三部分:
- 知识库:把文档切成片段,用向量/倒排等方式存起来。
- 检索器:根据用户问题找出最相关的若干片段。
- 生成器:大模型出场,基于检索到的片段和用户问题,生成最终回答。
大模型卷积在这条流水线的末端,它负责"读材料"和"写答案",并不负责"找材料"。很多人在项目里遇到问题,第一反应是换更大更强的模型,但实际瓶颈往往出在检索环节。你检索不到正确的资料,再强的模型也只能给你编一个。
记住这句话:RAG的天花板由检索质量决定,大模型只是把检索结果的上限兑现出来。
2. RAG的完整工作链路拆解
2.1 索引阶段:从原始文档到向量库
RAG的第一道工序,是把散乱的原始文档变成计算机能快速检索的格式。这个阶段有四个步骤,每一步都有讲究。
文档加载。把PDF、Word、Markdown、网页等不同格式的文档解析成纯文本。这一步看着简单,实际最容易翻车:扫描版PDF是图片不是文字,需要OCR;表格转成文本后语义会丢失;PPT里的文字可能藏在形状里。我早期做过一个项目,解析某客户的PDF时,所有章节标题都丢了,检索效果惨不忍睹——后来发现是解析器把标题当成页眉过滤掉了,换了个解析策略才解决。所以文档加载这一步,宁可多花时间验证,也不要盲目信任默认配置。
文本拆解(Chunking)。这是工程上最被低估的环节。你会把长文档切成若干小段,每段作为一个独立的检索单元。切大了,语义混杂,检索不精准;切小了,上下文不完整,生成时信息不够。常见的做法是按固定长度切(比如256~512个token),更好的做法是按文档结构切——比如Markdown标题、段落边界、PDF的章节标记。现在也有专门做语义切分的工具,比如LangChain的RecursiveCharacterTextSplitter,它允许你按多个层级的分隔符依次回退,尽量让语义完整的段落不被切断。
向量化。每个文本片段经过Embedding模型转换成一串向量。这一步决定了检索的语义基础:相似的文本在向量空间里距离更近。选Embedding模型时要注意语言匹配度,中文场景我一般推荐用中英双语模型,比如BGE系列,而不是纯英文模型。原因是很多技术资料里中英文混写,纯英文模型对中文的语义理解会打折扣。
存储。向量写进向量数据库,比如Milvus、Qdrant、Chroma、pgvector,同时保留原文和元数据(来源、页码等),方便后面溯源。很多初学者在这里纠结选什么库,其实早期验证用Chroma这种轻量的就够了,等数据量超过百万级再上Milvus这类分布式方案也不迟。
2.2 检索阶段:从问题到候选片段
用户提问后,系统先把问题也转成向量,然后在向量库里做相似度搜索,找出最接近的Top-K个片段。这一步有两个容易被忽略的细节。
Top-K的取值范围。K设小了,召回不全,正确答案可能根本不在候选里;K设大了,噪声多,干扰模型判断。经验值一般是4~8个片段,具体要根据你的文档粒度和问题复杂度调。有些系统还会做多路召回:一路走向量语义检索,一路走关键词精确匹配(BM25),再把两路结果合并去重。这种hybrid检索在很多场景下比单路要好,因为向量检索擅长理解语义,关键词检索擅长匹配精确术语(比如产品型号、人名、编号)。
重排序(Rerank)。向量检索的第一轮召回,返回的是"向量空间里距离近"的结果,但距离近不等于"就是最想要的"。尤其当知识库里有大量相似内容时,粗排结果往往把正确答案埋在第5、第6位。这时就需要一个重排序模型对候选片段做精排——它会把用户问题和每个候选片段同时输入一个交叉编码器,逐对计算相关度分数。我在自己的项目里测过:加了Rerank之后,不少问题的命中率能提升二三十个百分点。这是RAG优化里投入产出比最高的一步,没有之一。
2.3 生成阶段:把证据拼给大模型看
检索完成后,把命中的片段按相关度排序,连同用户问题一起组装进Prompt,交给大模型生成答案。这个阶段的Prompt设计有几个要点。
明确材料的边界。我会在Prompt里明确告诉模型:以下是从知识库检索到的资料,请只依据这些资料回答,不要使用内部知识脑补。如果资料不足以回答,请直接说不知道。这句话能大幅减少模型在不确定时强答的行为。
保留引用来源。在最终答案后附上引用出处,既方便用户校验,也反向约束模型——当它知道每个句子都可能被追溯时,回答会更谨慎。实现方式是在检索片段里保留文档ID、标题、页码等元数据,生成时要求模型在答完后再输出参考来源列表。
处理好"检索不到"的情况。如果所有片段的相似度分数都很低,说明知识库里可能没有用户要的信息。这时候强行把不相关内容塞进Prompt,反而会诱导模型胡编。比较好的做法是让系统走兜底逻辑:回复"知识库中没有找到相关信息,请换个问法或联系我们补充资料"。这个兜底逻辑能极大提升用户体验,也会显著降低你的系统"睁眼说瞎话"的概率。
3. RAG、微调与长上下文:边界与配合
3.1 RAG和微调解决的是两码事,别搞混
每次谈到RAG,总有人问:那我是不是直接微调大模型更好?这是个高频误区。RAG和微调看起来都能让模型"懂更多",但机制完全不同。
微调是改变模型本身的参数,让它习得某种固定的能力或风格。比如你想让模型用更强的领域术语回答,想让它在输出格式上永远遵循某个模板,或者想让它学会使用某个工具调用格式——这些是微调的主场。它的特点是"内化",效果稳定,但每次更新知识都要重新训练,成本高、周期长。
RAG则是把知识放在模型之外,在生成时临时"查阅"。它的特点是实时、可控、可解释。知识库当天更新,当天生效;你还可以控制到底给模型看哪些资料,甚至精细到给不同用户过滤不同文档。这是微调做不到的。
所以两者的关系不是二选一,而是互补。我的参考判断标准是:如果知识是容易变化的、来源分散的,用RAG;如果能力是稳定的、需要固化到模型行为里的,用微调。最常见的落地形态是两者结合——先微调让模型学会领域内的表达风格和输出格式,再挂RAG提供实时知识。
3.2 长上下文把RAG逼到墙角了吗
自从大模型进入百万token上下文时代,一种声音越来越大:"既然上下文窗口这么大,我把整本手册都塞进去不就行了,还要RAG干嘛?"这种想法表面上说得通,实际操作会撞上三堵墙。
成本墙。每多塞一个token,都要参与注意力计算,prompt越长,生成阶段的算力开销越贵。一个百万token的Prompt,光解析和编码可能就比生成答案慢好几倍、贵好几倍。对于日请求量大的应用,这个成本差异很快会变成不可忽视的账单。
精度墙。大模型对长上下文的注意力分配并不均匀。业界早就有研究指出"Lost in the Middle"现象——模型对长文开头和结尾的内容记忆较好,中间的内容容易被忽略。你塞一万页资料进去,模型很可能漏掉最关键的信息,而这恰恰可能是用户最需要的那句。
更新墙。上下文内容每次都要实时拼接,如果知识库在持续变化,你得每次重新组装完整资料,又有延迟,又容易出错。RAG的优势是把"全局查阅"变成"按需取用",只把最相关的几段喂给模型,既省钱又快,还更准确。
所以长上下文不会淘汰RAG,反而衬托出RAG的定位:RAG是给大模型配的资料员,长上下文则是把整个图书馆搬进来,资料员只需要找出最该看的那几页。
3.3 三种路线的选型对照
我把自己做项目时常用的决策表整理在下面,方便对照参考:
| 决策维度 | RAG | 微调 | 长上下文全量塞入 |
|---|---|---|---|
| 知识更新频率 | 实时更新,成本低 | 每次都要重新训练 | 实时,但组装成本高 |
| 事实准确性 | 高,基于证据生成 | 中,知识固化在参数里 | 高,但要解决注意力失焦 |
| 输出风格/格式控制 | 弱,只能靠Prompt引导 | 强,直接改变行为 | 弱,靠Prompt,易被长文干扰 |
| 单次推理成本 | 低(只检索关键片段) | 正常 | 高(全量上下文参与计算) |
| 可解释性 | 强,能溯源引用 | 弱,黑盒 | 中,能追溯到原文 |
| 最适合的场景 | 知识问答、客服助手、企业内部文档检索 | 领域写作风格、工具调用、特殊输出格式 | 实验性场景、单份长文档精读 |
这张表不是绝对的,但能帮你快速判断一个需求该走哪条路。我遇到过不少团队上来就想微调,问清楚需求后发现他们要的其实是"一个能实时查询内部制度文件的问答系统"——那不用微调,一个RAG就够了。
4. RAG落地的瓶颈与实战避坑
4.1 Chunk切分策略:直接影响检索,却最容易被忽视
跑通RAG Demo很容易,但想让效果稳定就很难,其中chunk切分是第一个分水岭。我见过最常见的错误是:拿到文档不管三七二十一,固定切512个token。结果遇到表格和代码片段时,语义被切得四分五裂,检索质量直线下降。
我的实操经验有三条。第一,优先利用文档结构。如果源文档有Markdown标题或PDF目录,尽量按结构切分,一个章节、一个节作为一个chunk,因为它们在语义上天然完整。第二,不要死磕统一长度。chunk之间的token数可以波动,短到几十、长到几百都正常,关键是语义边界不被打断。第三,加重叠窗口。切分时让相邻chunk之间保留10%左右的重叠,减少边际信息被切断的概率。比如第一个chunk包含第1~100句,第二个chunk从第90句开始,这样跨边界的信息不会被完全丢掉。
另外,如果你处理的文档类型复杂,可以关注一下本地的RAG文本拆解工具。LangChain的splitter、LlamaIndex的NodeParser、以及一些专用的文档解析服务(比如Unstructured)都能做chunk前预处理。核心原则是:切分逻辑要在理解文档结构的基础上设计,而不是无脑按字符数切。
4.2 Embedding模型选型:中英文场景各有一本账
Embedding模型是整个RAG的"语义地基",它选错了,后面所有环节都白搭。我在中文项目里踩过坑:早期用某个英文为主的Embedding模型,效果奇差,"手机坏了"和"设备故障"这类语义相近的表述,向量距离隔了十万八千里。
现在中文场景比较稳的选择有两类:一是开源本地模型,比如BGE系列(BAAI/bge-large-zh-v1.5、bge-m3),支持中英双语,可本地部署,数据不出内网;二是商业API,比如OpenAI的text-embedding-3系列,省运维但数据要外传。如果对数据合规有要求,比如企业内部文档,基本只能走本地部署方案。
选型时有几个要点:先评测后选型,用你自己的领域数据做一个小的检索测试集,比一比哪个模型在"准确召回率"上表现好;维度不是越高越好,768维和1024维在实际检索效果上差距未必明显,但存储开销和检索延迟会有差异;留意是否有领域Instruct版本,有些模型出了专门的领域微调版本(比如医疗、法律),按需选择能省很多事。
4.3 重排序:效果提升最猛的一步
我在前面提过Rerank,这里再展开讲。为什么向量检索粗排之后还需要一层精排?
因为粗排用的是"双塔架构"——Query和Document分别编码成向量,再算余弦相似度。这种方案为了效率牺牲了精度:两个文本之间的细粒度交互信息(比如哪个词在哪个上下文里更重要)在分别编码时已经丢失。而Rerank用的是交叉编码器,它把Query和Document拼在一起同时喂给模型做综合判断,精度高得多,缺点是慢。所以标准的工业级做法是两段式——先用向量检索快速捞出Top-50,再用Rerank精确挑出Top-5。
本地部署可以选bge-reranker-v2-m3,也可以调用商业Rerank API(比如Cohere的Rerank)。这个环节不挑大模型,它发生在检索阶段,与生成模型无关。但它的收益却体现在最终回答质量上:Top-5候选精准了,大模型生成时就少了很多干扰信息,幻觉率明显下降。
4.4 多模态答案:知识库到底能不能存图片
"RAG知识库能存储图片吗"这个问题经常被问到。答案是:能,但要看你说的"存"是什么意思。
如果你只是把图片文件作为附件扔进知识库,那没有任何意义——纯文本检索器无法理解图片内容。常见的正确做法有两种。
第一种是图片转文本,先用多模态大模型(比如具备视觉能力的GPT-4V、Qwen-VL等)对图片做描述,生成一段文字说明,再把这说明连同图片的路径一起存入知识库。检索时命中描述文本,返回图片链接。这种方式实现简单,效果可控,适合"图配文"的场景,比如产品说明书里有大量截图。
第二种是多模态向量检索,使用支持图文统一编码的模型(比如多模态Embedding模型或CLIP类模型),将图片不经描述直接映射成向量,用户用文字或图片都能检索。这种方式更"正宗",但工程复杂度高,需要专门的向量模型和存储方案,目前在生产环境用得还不多。
对大多数团队来说,我建议先从第一种方案开始,成本低、见效快。而且注意:图片里的文字(截图、表格、发票)有时候比图片本身更重要,这类场景建议优先走OCR提取文本,再把提取结果作为chunk入库,检索效果甚至比多模态模型描述更好。
4.5 本地部署与框架选型:从小白可复制的路径开始
聊到最后,不少读者可能想立刻动手试一把。给你一条零基础也能复制的路径。
第一步:跑通本地模型。用Ollama,拉一个7B~14B的中文模型(比如Qwen系列),再加上一个Embedding模型(比如bge-m3),在你自己的机器上把模型的API跑起来。Ollama的安装和使用都很简单,一条命令就能拉模型,不需要懂CUDA配置,实测对新手非常友好。
第二步:用RAG框架串流程。推荐从Dify或FastGPT这类可视化平台开始。它们内置了完整的知识库管理、检索、Rerank编排,你只需要上传文档、配置模型API,就能搭出一个能用的RAG问答系统。Dify本身支持接入Ollama本地模型,数据可以不外传,适合企业私有化部署场景。
第三步:进一步优化。如果线上需要高并发,模型推理可以用vLLM部署,它能大幅提高吞吐和降低显存占用,而且提供OpenAI兼容API,RAG框架对接起来很顺。注意vLLM对显存要求不低,小团队先用Ollama+Dify验证业务价值,再考虑上vLLM扩容量。
我个人做项目时还有一个习惯:把整个流水线的每个环节都留一个"手动调试入口"。比如检索出来的Top-K片段,可以随时导出查看——是chunk切坏了、Embedding不匹配,还是Rerank把正确结果排在后面了,每一步都看得见,就不会出现"效果差但不知道差在哪"的黑盒状态。
RAG和大模型的这套组合,说到底是把大模型的"表达能力"和外部知识的"事实性"接在了一起。它们不是竞争关系,而是各自承担了不同职责:大模型负责理解和生成,RAG负责查证和供给信息。把这条主线的每个环节吃透,很多困惑都会迎刃而解。对于刚上手的团队,我的建议是先别急着追求花哨的功能,把文档加载、切分、检索、重排序这四段链路逐一用真实数据测一遍,该追根查底的地方绝不跳过,这个基础打得越扎实,后面迭代就越轻松。