最近这一两年,大模型的热度大家都有目共睹。但只要你真正把它用到业务里,大概率会遇到同一个尴尬场面:模型回答得头头是道,仔细一查,关键数据、引用来源、专有名词全是编的。业内管这个叫“幻觉”,说白了就是一本正经地胡说八道。RAG(Retrieval-Augmented Generation,检索增强生成)就是目前应对这个问题最主流、也最接地气的方案。
这篇内容我从头到尾讲清楚 RAG:它到底干了什么事、为什么能缓解幻觉、一个生产可用的 RAG 系统由哪些部件组成、怎么在本地把它跑起来,以及你大概率会踩到的坑。文章面向的是想真正上手 RAG 的开发者、AI 应用工程师和产品技术负责人,不管你是第一次听说这个词,还是已经调过几个 demo,应该都能从中拿到点能直接用的东西。
1. 大模型为什么总在胡说八道:先搞懂幻觉从哪里来
1.1 预测下一个词的本质决定了它没有“查证”能力
很多人会把大模型想象成一个“什么都知道的超级大脑”,这个印象其实是有偏差的。你用的 GPT、Claude、文心、通义、DeepSeek,本质都是在一个巨大的语料库上训练出来的概率模型,它们的核心任务只有一个:根据你给的上下文,预测下一个最可能出现的 token(你可以粗略理解为“词”)。
这套机制带来的结果就是,模型在回答问题时,并不是先去数据库里“查”一个正确答案,而是根据它见过的所有文本的统计规律,把“最像话”的一串词语拼出来。在常见问题上,这种方式非常高效,因为训练语料里已经有了大量高质量答案,模型能“背”出来。可一旦遇到下面几种情况,它就绷不住了:
- 训练数据里根本没覆盖到的冷门知识,或者覆盖得很少。
- 事实发生的时间晚于训练截止日期(比如你问它上个月的行业数据)。
- 答案高度依赖企业内部文档、个人笔记、私域资料等非公开信息。
- 问题描述含糊、有歧义,模型只能靠“猜”补全。
在这些场景下,模型不会说“我不知道”,它最擅长的是接着你的话头编一个听起来合理的答案。这就是幻觉的根源:模型没有“知之为知之,不知为不知”的能力,它的训练目标里根本没有“承认无知”这个选项。
1.2 “投喂”上下文的朴素解法,为什么不能直接用
既然模型不知道答案,那我们把答案塞给它不就行了?这个思路完全正确,也是 RAG 的核心,但直接“塞”是有技术门槛的。
最朴素的做法是把整份资料塞进 Prompt。问题来了:大模型的输入长度是有限的。早期模型 4K、8K token 的上下文窗口,根本放不下几百页的文档。即便现在很多模型支持 128K、200K 甚至更长的上下文,直接把全量资料塞进去,也会出现两个新问题:
一是成本暴涨。token 越大,每次调用花的钱越多,长上下文的推理速度也会显著下降。二是“迷失在中间”。大量实验和工程经验都表明,当上下文变得很长时,模型对中间部分内容的注意力会明显减弱,你辛苦塞进去的关键信息反而被淹没了。
所以 RAG 的思路不是“全塞”,而是“先查再塞”:先根据用户问题,从知识库里检索出最相关的几个片段,再把这几段作为上下文交给大模型组织答案。整个过程就像一个配备专职助理的专家:助理先去档案室找资料,专家只需要读助理挑出来的两三页,就能给出靠谱回答。
1.3 RAG 到底解决的是什么问题
RAG 不是让模型“变聪明”,而是给模型配了一个“外部硬盘”和“检索员”。它解决的问题可以拆成三点:
- 知识时效性:知识库可以随时更新,今天改完文档,明天模型回答就是新内容,不需要重新训练。
- 领域知识私有化:企业内部知识、个人文档不需要暴露给模型训练,只在检索时被临时引用,数据和答案可控可溯。
- 抑制幻觉:模型不再凭空编造,而是基于检索到的证据来生成,回答可以被追溯到具体的文档来源。
尤其最后一点,对于企业级应用来说几乎是刚需。金融、医疗、法律、政务这些行业,回答必须有出处、可追责、能审查。模型“自由发挥”的后果,轻则闹笑话,重则产生决策风险,这也是为什么 RAG 近两年成了企业落地大模型最主流的技术栈之一。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RAG 核心三板斧:索引、检索、生成
RAG 的完整流程可以拆成两条链路。一条是写操作:把文档拆碎、向量化、建索引,我们叫“离线索引”。另一条是读操作:用户提问后,把问题向量化、检索、重排、交给模型生成,叫“在线查询”。
2.1 离线阶段:文档加载、切分、向量化、入库
离线阶段的目标,是把“一堆乱七八糟的原始文档”变成“一个方便快速检索的知识库”。这里面的关键动作我拆开说。
文档加载相对简单,现在主流的框架 LangChain、LlamaIndex 都内置了几十种 Loader,PDF、Word、Markdown、网页、数据库、Notion、飞书都能接。但接进来之后才是重头戏:文本切分(Chunking)。
切分是 RAG 效果好坏的第一道分水岭。为什么一定要切?因为向量检索的粒度问题。一段 5000 字的文章,如果整体向量化,它表达的主题可能是“农业物联网系统的整体架构”,但用户问的是“智能灌溉的传感器阈值设置”,这段文字的平均语义向量就会把细节信息稀释掉。反过来说,如果切得太碎,比如一句话一个 chunk,语义不完整,检索出来也是断章取义。
通用的切分策略是按固定长度 + 重叠窗口来切。比如 chunk_size = 500 字符,overlap = 50 字符,让相邻片段之间保留一定重叠,避免关键信息刚好被截断。更聪明的做法是按文档本身的语义结构来切,比如 Markdown 标题、段落、代码块、表格这些天然分隔符。生产项目中我建议优先结合两者:先按结构切,结构不明确的再用长度切。
切完之后是向量化(Embedding),也就是把每个文本片段用模型转成一串浮点数向量。这一步的核心诉求是:语义相近的文本,向量在空间里的距离也要近。以前做搜索靠关键词匹配,现在做语义检索靠向量距离,这也是 RAG 和传统全文检索最本质的区别。
最后一步是写入向量数据库。这里的选择比较多,常见的有:
- 轻量级:Chroma、FAISS、LanceDB,适合个人项目和快速原型。
- 服务级:Milvus、Qdrant、Weaviate、Elasticsearch 8.x,适合生产环境。
- 云原生:Pinecone、阿里云向量检索服务等,适合不想自己运维的团队。
选择没有绝对优劣,主要看
