很多人第一次听到 RAG,以为是个能直接下载的软件,装完公司资料就能问答;结果资料丢进去,答出来的还是瞎编。问题通常不在模型,而在你没搞清它其实是两条流水线拼起来的:一条把资料切碎存好,一条按问题去捞再交给模型写。这篇按零件讲一遍,读完你能判断自己卡在哪一环。
很多人第一次听到 RAG 这个词,脑子里第一反应是「有没有现成软件,下载装完把公司资料一丢就能问答」。真去试了才发现,资料是丢进去了,答出来的东西还是一本正经地胡说。这时候多数人开始怀疑模型不行,想换个更强的模型试试。但问题往往不在模型,而在于你没意识到 RAG 根本不是一坨可以整体替换的东西,它是两条流水线拼起来的:一条专门把资料切碎存好,另一条负责按你的问题去捞,再把捞到的东西交给模型写答案。任何一条线的零件坏了,最终回答都会崩。
这篇就按零件给你讲一遍,不聊抽象概念,只讲每一步在干什么、需要什么、哪一步最容易踩坑。读完你至少能做一件事:拿到一个答不准的 RAG 系统时,判断出问题大概率卡在哪一环,而不是盲目换模型或者重新灌数据。适合完全没接触过 RAG、但准备自己搭一个内部知识库的人看。如果你已经在跑系统,也能当排查清单用。
先说人话:RAG 到底替模型干了什么
模型的脑子里只有它训练时见过的东西,你公司内部的文档、合同、产品手册,它天生不知道,也不会因为你说「我们公司是这样」就真记住。RAG 的做法很朴素:每次你提问的时候,临时去你的资料堆里翻出几段相关的,塞进这次提问的上下文里,让模型照着这几段写。所以它不改模型本身,改的是每次问的时候喂进去什么。资料更新了,不用重新训练,重新入库就行。
- 先按你的问题去资料堆里捞出相关片段,再把片段和问题一起丢给模型让它照着写
- 模型负责组织语言、理解问题,资料负责提供事实,两边缺一不可
- 资料更新只要重跑入库,不用动模型,这是它比微调省事的地方
- 需要模型形成新语感或固定格式习惯的任务,RAG 帮不上,那属于另一条路,别硬套
两个阶段、两套零件:离线入库 vs 在线问答
把 RAG 拆成两个阶段看,很多困惑就解开了。离线入库阶段是提前做好的:把文档解析成文本、清洗、切成小块、每块转成向量、存进向量库。这一步跑一次能用很久,但资料一变就得重跑对应部分。在线问答阶段是每次提问时实时跑的:把用户的问题也转成向量、去库里检索、重排、拼成提示词、调模型生成答案。两条线是解耦的。
| 阶段 | 主要动作 | 出问题的表现 |
|---|---|---|
| 离线入库 | 解析、清洗、切块、向量化、写入向量库 | 答案完全不着边,问什么都不沾,像没读过资料 |
| 在线问答 | 问题向量化、检索、重排、拼提示词、生成 | 答案沾点边但答错,或引用了不相关的段落 |
| 判断方法 | 先看命中的片段对不对 | 片段对但答错是提示词问题,片段不对是检索或入库问题 |
关键判断标准:入库做得糙,在线怎么调都救不回来。很多人一上来就调提示词、换模型,其实底下的块早就切坏了。所以拿到一个效果差的系统,先别动在线那端,先去把入库的产物翻出来看。
组成部分清点:一个能跑的 RAG 至少要有这几样
下面这几样是绕不开的。你可以把它当成采购清单,搭之前先确定每一样用什么,别做到一半才发现缺零件。
- 文档解析与清洗
- 把 PDF、网页、表格变成干净的纯文本,扫描件还得先过 OCR,这一步脏后面全脏
- 切分器
- 决定每块多大、按什么断句,切得好检索才准,具体参数去站内相关页面看建议
- 嵌入模型
- 把文字变成一串数字,选型看中英文支持、维度与成本,可到 /embeddings 对照当时的资料
- 向量库
- 存这些数字并支持相似度查询,选型看数据规模与运维成本,目录在 /stacks/vector-dbs
- 生成模型
- 最后写答案的那一环,选型和价格思路见 /models
除了这些,通常还会加一个重排模块和一层权限过滤,前者提升检索精度,后者决定谁能看到哪些资料。新手可以先不加,跑通基础流程后再补。
检索这一环:为什么「捞得准」比「模型强」更要紧
生成那一步现在的模型普遍够用,真正拉开差距的是你能不能把正确的资料捞出来。一个常见误区是「相似度高就等于有用」,实际上问法和原文表述差得远的时候,纯靠向量相似度经常捞不到。比如你问「报销上限多少」,原文写的是「单笔费用不得超过」,字面差得远,向量也可能匹配偏。
- 纯向量检索怕表述差异,加一路关键词检索补一脚,两条结果合并往往更稳
- 重排的作用是先粗捞一批再精排,把真正相关的顶上来,别一上来就把它当可选项砍掉
- 块太大噪声多、块太小丢上下文,这是最常见的调参点,没有万能值,只能拿真实问题试
- 如果连人工翻资料都找不到答案,别指望检索能找出来,先补资料再谈调优
什么情况下这套不适用:如果你的资料本身就是结构化的表格数据,比如一堆订单记录,那用数据库查询比检索靠谱得多,别硬塞进向量库。
答案是从哪来的:把生成这一步说透
检索捞出片段之后,还差最后一步:把片段和问题拼成一段提示词交给模型。这一步看着简单,其实是答案跑偏的高发区。最常见的毛病是没约束住模型,它看到资料不全就自己脑补,答得又快又自信。所以提示词里必须明确写「只根据下面资料回答,资料里没有就说不知道」。
- 要求模型给出引用出处,方便你回查,也让用户在答案不准时能自己判断
- 同一份资料喂进去,不同的排版和分段对结果影响很大,格式也是提示词的一部分,参考 /prompt-structured
- 资料要放在问题前面还是后面,不同模型偏好不一样,值得拿真实问题各试一轮
- 开放式写作、需要模型自由发挥的任务不适合硬加引用约束,反而写不好
答不准时,按这个顺序排查
这是最容易省事也最容易浪费钱的一节。很多人遇到答不准第一反应是换个更贵的模型,结果钱花了问题还在。正确的顺序是从底层往上查,每一步都留证据。
- 第一步:查语料资料是不是本来就缺、是不是过期、是不是有重复的多份互相打架。把命中的原文找出来,人工确认它到底对不对。
- 第二步:查切分把命中的片段原样打出来看,块被切断在半句话中间是常见病,补上重叠或换个切法再试。
- 第三步:查检索拿同一个问题换关键词、加过滤条件试,看是不是压根没捞到正确的块。这一步能区分是检索问题还是入库问题。
- 第四步:查提示词和模型前三条都干净了再换模型或改提示词,顺序反了纯属浪费钱。
新手怎么起步:先做小再做好
别一上来把整个共享盘喂进去,那只会让你在几千个没用的块里找不到问题。务实做法是挑一个主题、几十份文档,先把全流程跑通,确认效果再扩量。验收标准别用「感觉不错」,准备一组真实问题。
- 选一个窄主题比如只做「产品售后政策」这一个主题,文档控制在几十份以内,跑通再说。
- 准备验收问题集列 20 个你平时真会问的问题,改一次配置就跑一遍,看答对几个,作为唯一标准。
- 每步留中间结果切分后的块、检索命中的块、最终拼的提示词都存下来,出问题能一眼定位。
- 先跑通再加量流程稳定后再逐步加资料、加主题,技术栈组件可对照 /stacks 里的图谱挑。
RAG 管不了什么:先把期待摆正
最后说清楚它做不到的事,免得你带着错误期待去搭。它不会让模型变聪明,只是把资料递到嘴边,推理能力还是模型自己的事。资料本身有错,它会忠实地把错误答出来,甚至因为有了「依据」而答得更自信。语料治理是长期活,躲不掉。
| 场景 | RAG 能不能帮上 | 原因 |
|---|---|---|
| 内部文档问答 | 能 | 资料固定、问题具体,正是它擅长的 |
| 强实时数据查询 | 不能 | 每分钟变的库存该走接口查询,别塞知识库 |
| 开放式创意写作 | 不该 | 硬加引用约束反而限制发挥 |
| 跨权限资料问答 | 要看设计 | 得在检索层做过滤,不能指望模型自觉 |
常见问题
RAG 和微调到底有什么区别,我该选哪个?
简单说,RAG 是给模型临时翻资料,资料改了立刻生效;微调是让它把某种风格或格式练进骨子里,改一次要重训。你的痛点是「模型不知道我们的业务」,优先 RAG;痛点是「它答得对但语气不对」,才考虑微调。两者的分界线站内有专门文章对比,可以先看一眼再决定。
没有向量数据库能做 RAG 吗?
能。资料量小的时候,用关键词检索甚至在提示词里塞全文都能跑通,很多人卡在工具选型上其实还没到需要向量库的规模。等你的文档多到塞不进上下文、或者检索明显变慢变差,再上向量库也不迟。站内 /stacks/vector-dbs 有目录可以先了解。
为什么我把资料喂进去了,它还是瞎编?
大多数情况是检索没捞到正确片段,模型手上没料又不敢说不知道,就开始编。先把命中的片段打出来看,如果片段不对,问题在切分或检索;如果片段对了它还是编,那才轮到改提示词。按这个顺序查,比反复换模型快得多。
需要多少资料才值得搭 RAG?
没有统一门槛,看两件事:一是资料量是不是已经超过你能手动贴进对话的程度,二是同样的问题会不会被反复问。一个 5 人小团队十几份规范文档,问答又重复,就值得搭。反过来,一次性查一份资料,直接贴进对话更省事。
RAG 能保证答案一定正确吗?
不能。它能提高答案有据可依的概率,但检索会漏、资料会有错、模型仍可能理解偏。稳妥的做法是要求答案带出处,让人能一键回查原文,再配合定期抽查。把它当成一个查得快的助手,而不是权威结论来源。