这些年做知识库类应用的人越来越多,RAG(Retrieval-Augmented Generation,检索增强生成)几乎成了大模型落地最稳的一条路。不管你是想给企业文档做个问答机器人,还是给内部系统接一个能查数据的助手,最终都会落到怎么把知识库“喂”给模型这件事上。市面上有大量所谓“快速搭建”的框架,但真正到生产环境,从切片策略到向量召回,每一步都会坑你一遍。这篇东西就是把我从零开始搭RAG系统的过程、踩过的坑和最终稳定的方案完整梳理一遍,适合已经跑通Hello World、正在纠结“为什么我的RAG效果这么差”的开发者参考。
我默认你已经知道Transformer和Embedding大概是什么,不需要懂数学推导,但至少知道向量不是玄学。下面所有内容都以工程落地为优先级,不讲论文,只讲能跑的东西。
1. RAG的核心链路与设计思路
1.1 RAG到底解决什么问题
大模型的知识截止日期是硬伤,你今天问它昨天的文档它大概率胡说。微调能解决一部分,但成本高、更新慢,而且你没法细粒度控制哪些知识来自哪份文档。RAG的思路非常朴素:不逼模型背知识,而是每次提问时先检索出相关的资料片段,把资料和问题一起塞给模型,让模型“看着资料回答”。
这样做的好处有三个:知识更新不用重训模型,只要重刷向量库;回答可以追溯到原文片段,方便审核和修正;对算力的要求也远低于微调。也正因为这些特性,RAG成为客服问答、企业知识库、法律文书辅助、医疗资料查询等场景的事实标准方案。
但你别把RAG想得太简单。它不是“装个向量数据库就完事”这么轻松,而是一个由数据清洗、切片、向量化、存储、检索、重排、提示词组装、流式输出、引用溯源组成的完整工程链路。任何一个环节偷懒,最终回答质量都会断崖式下跌。
1.2 一条标准的RAG数据流
我习惯把整个RAG系统拆成两条链路来看,这样定位问题会清晰很多:
- 离线索引链路:原始文档 -> 解析 -> 清洗 -> 切片 -> 向量化 -> 入库
- 在线服务链路:用户提问 -> 向量化 -> 检索 -> 重排 -> 组装Prompt -> 生成 -> 返回
离线链路解决的是“知识怎么存进来”,在线链路解决的是“知识怎么被找到和用起来”。两条链路通过向量库和文档库解耦,你可以单独升级其中任意一侧而不影响整体。
很多团队把大量精力花在Prompt调优上,但实际生产数据告诉我:检索质量决定RAG的天花板,Prompt只是把天花板变现的手段。如果检索出来的片段本身不对,再怎么优化Prompt也白搭。所以后面我会重点讲检索侧能怎么抠细节。
1.3 你在哪个阶段,决定了怎么取舍
RAG系统的复杂度没有一个固定标准,完全取决于你的业务要求。我大致把它分成三个段位:
- 入门Demo:几百个PDF,单机向量库,直接用开源框架默认配置,能回答就算成功。
- 可用阶段:几万篇文档,需要处理表格、扫描件、多语言内容,检索要有召回率指标,回答需要引用来源。
- 生产级:百万级文档,多租户隔离,严格的权限控制,毫秒级检索响应,需要混合检索、重排、缓存、监控全部到位。
下面我讲的方案是按“可用阶段到生产级”的标准来展开的。如果你只是做个Demo,可以跳过一部分内容,但建议把切片和检索这两章读完——这两个地方决定了你以后要不要返工。
2. 技术选型:模型、向量库、框架怎么搭配
2.1 Embedding模型不能随便选
Embedding模型负责把文字变成向量,这个向量空间的质量直接决定“相似的东西能不能被聚在一起”。选型时主要看三个指标:语义理解能力、向量维度、中文支持度。
比如中英文混合的文档场景,BGE-M3这类支持多语言且能输出稀疏+稠密混合向量的模型就非常合适。它输出的向量维度不算高(大约1K~2K级别),检索性能好,还能同时提供词汇权重用于混合检索。
实战中我推荐你按这个标准去选Embedding模型:
- 先看你语料的语言构成,纯中文和中外混合的选择完全不同
- 对比模型在MTEB或C-MTEB榜单上的检索任务分数,不要只看总榜
- 测试时直接用你自己的领域数据抽200~500对问答,跑一次召回准确率对比
千万别迷信“模型参数越大越好”。Embedding模型要的是稳定和快,而不是回答能力。你公司内网没有GPU推理服务的话,优先选择CPU可跑的轻量模型,或者买一个托管的Embedding API,省去运维成本。
2.2 向量数据库:选型要看生态,不只是性能
向量数据库是RAG的存储底座。目前常见的开源方案有Chroma、Qdrant、Milvus、Weaviate,还有基于Elasticsearch的向量检索插件。
我的选型建议分场景:
- 原型验证:Chroma或LanceDB最省事,直接嵌进Python进程,零运维
- 中小规模生产:Qdrant表现非常均衡,支持Payload过滤、稀疏向量、分布式部署,文档齐全
- 海量规模或需要复杂过滤:Milvus更合适,但它的部署运维复杂度也更大
- 已有ES的团队:可以考虑直接在ES上加向量字段,减少组件数量
坦白说,功能上这些开源向量库的重合度已经非常高了,差异更多体现在生态和运维。我的习惯是:团队熟悉什么就先用什么,但必须确认三个能力——支持Metadata过滤、支持批量写入、有可观测的检索日志。缺任何一个,后面都会很难受。
2.3 编排框架:LangChain、LlamaIndex还是自己写
框架的选择算是RAG开发里争议最大的话题。我的结论是:初学可以用框架加速理解流程,但生产系统不要被框架绑死。
LangChain的优势是组件全、社区大,但抽象层次多,出问题时排查链路长。LlamaIndex在文档索引和检索这块做得更专,适合知识库场景。不过等你做到重排、混合检索、多路召回的时候,八成会发现自己写更顺手。
我自己现在的做法是:数据处理和加载复用成熟库,但核心检索和Prompt组装直接手写。整个逻辑大概几百行代码,完全可控,出了问题不用去翻框架源码。特别是当你需要加权限过滤、定制排序规则、对接内部日志系统时,手写反而省时间。
提示:不管选不选框架,一定要把“文档处理-Embedding-向量存储-检索-生成”各环节抽象成独立模块。这样你后面换任何组件都只改接口实现,不用重写整个系统。
3. 离线数据加工:切片、清洗与向量化
3.1 数据清洗决定上限
很多人拿到PDF就直接切片入库,这是RAG效果差的头号原因。真实文档里全是页码、页眉、表格错位、多栏排版、乱码字符、脚注干扰。这些噪声会被Embedding模型原封不动地编码进向量里,直接污染检索。
我处理文档的顺序是:
- 先做文本提取,PDF优先尝试高精度解析方案(如OCR层),扫描件必须走OCR
- 去除页眉页脚、页码、目录标记,这部分用规则正则就能完成大部分
- 统一编码格式,处理全角半角、特殊符号、无用换行
- 识别表格结构,表格内容不宜直接用纯文本拼,最好结构化保留再转描述
- 最后才进入切片步骤
有些工具支持“文档解析->结构化输出”的一站式方案,对于复杂格式确实省力,但开源方案也有好处:每一步都能看到中间结果,方便定位问题。我个人强烈推荐在处理流程里加一个“人工抽检”环节——每处理一百个文件,抽三五个打开看看解析结果,比任何指标都管用。
3.2 切片策略:没有万能公式,但有通用套路
切片是RAG里最容易被低估的环节。切得太短,语义不完整;切得太长,向量被无关信息稀释,检索精度下降。我见过太多人直接按固定字符数硬切,然后召回一堆莫名其妙的片段。
常用切片策略有几种:
- 固定长度切片:逻辑简单,但容易切断句子,适合结构单一的纯文本
- 按段落/标题切:保持结构完整,适合有Markdown、Word标题的文档
- 按语义边界切:用句子嵌入相似度检测主题切换,效果最好但计算量大
- 父子切片:小片段用于检索,命中后返回其所属大片段给大模型,兼顾精度和上下文
实践上,我推荐用“结构优先+长度兜底”的组合方式:优先按文档原有段落块切分,段落过长时再往下切成不超过某个长度的片段,同时保证相邻片段之间有重叠。
这里有我踩过坑后的经验值:中文技术文档,切片大小在300~500字左右通常效果最好;需要上下文连贯的场景,重叠量可以设到切片的10%~20%。但记住这只是起点,必须用你自己的数据跑实验调整。
3.3 Embedding批量入库的工程细节
embedding入库看起来只是“循环调用”,实际工程细节很多。
首先,一定不要一条条调API,要批量处理。比如每批次32~64条文本同时向量化,否则几万条文档的索引时间会让你怀疑人生。如果数据量大,建议用异步任务队列来做,失败自动重试,并记录处理进度。
其次,向量库的写入要设计成可重入的。用文档ID作为主键,重复写入直接覆盖。这样数据更新时就不用清库重来,只需要把变更的文档重新处理一遍就行了。
还有一点很多人忽略:Metadata一定要认真设计。来源文件名、章节路径、页面范围、更新时间、权限标签都必须入库。等你要做权限过滤或多文档对比时,没有Metadata就只能把整个库召回再在代码里过滤,性能要差一个数量级。
注意:Embedding模型有最大输入长度限制。切片长度必须小于模型的最大Token数,超出部分会被截断,等于信息直接丢失。所以切片策略要和Embedding模型的最大上下文对齐,别等上线后才发现长片段全部被无声截断。
4. 在线检索:从向量召回到底层优化
4.1 纯向量检索为什么不够用
向量检索擅长语义相似,但它对精确词匹配非常不敏感。比如用户搜索“合同编号A-2024-001”,Embedding模型可能觉得它和“合同编号B-2023-002”很“相似”,但你要的肯定是精确的那个字符串。
同样的问题也出现在专有名词和缩写上:Embedding模型没学过你们公司的内部术语,它会按通用语义去理解,“财务共享中心”它可能编码成“财务+共享+中心”三个词附近的空间,精确匹配反而丢了。
所以生产级RAG几乎都是混合检索:向量召回+BM25关键词召回,两路结果做融合。向量负责“语义相关”,关键词负责“精确匹配”,两者互补之后,召回率能上一个台阶。
4.2 重排:用更精细的模型把好东西挑出来
召回阶段为了召回率,通常会多召回一些候选结果。比如Top 50甚至Top 100。但这些结果里噪声很大,直接喂给大模型不仅浪费上下文窗口,还会增加幻觉风险。
这时候就要上Rerank重排模型。它把“问题和候选文档片段”拼在一起做精细相关性打分,比向量相似度更准。常见方案有bge-reranker这类开源模型,效果显著,成本相对可控。
我的检索链路设计是:
- 向量召回Top 50
- BM25召回Top 50
- 融合去重后取Top 100
- Rerank精排取Top 5
这样比单纯向量检索Top 5的效果要稳定非常多。重排模型的推理成本确实有,但对于知识库问答场景,它换来的是回答准确率的巨大提升,这笔投入非常划算。
4.3 多轮对话的Query改写
RAG系统一旦进入对话场景,就会遇到一个尴尬问题:用户上一轮说“那它的价格呢”,这一轮问“那售后呢?”——如果你直接把“那售后呢”拿去检索,向量库里根本找不到对应的上下文。
解决方案是Query改写:在检索之前,先让大模型结合对话历史,把当前问题改写成一个独立的、包含必要上下文的搜索语句。比如把上面那句改写成“某产品的售后服务政策是什么”。
这一步的成本很低,但对多轮对话体验的提升是质的。我建议把改写后的Query打印到日志里,方便排查“为什么检索出来这么怪”的问题。
还有一个更进阶的做法:把用户问题拆解成多个子查询分别检索,再合并结果。比如用户问“哪个方案性价比最高,适合20人团队用?”可以拆成“方案性价比对比”和“适合20人团队的选择建议”两个子查询,召回结果会更全。这个技术叫Multi-Query,值得一试。
5. 生成优化:Prompt编排与引用溯源
5.1 Prompt模板必须把边界划清楚
RAG的Prompt和普通对话的Prompt不一样。它的核心目标不是让模型“自由发挥”,而是“基于给定的资料回答问题,并且不越界”。
我整理出一套通用模板,结构大致是:
- 系统角色声明:你是一个知识库问答助手,只依据提供的资料回答
- 回答要求:如果资料中没有相关信息,明确回答“资料中未找到”
- 引用要求:每个回答必须标注来源片段编号
- 注意力约束:不要使用资料之外的知识,不要编造
- 然后是资料区:按编号列出检索到的文档片段
- 最后是用户问题
你可能会觉得这些要求太啰嗦,但它们能显著降低模型自由发挥的概率。尤其是“资料中未找到就直说”这条,能拦住很大一部分幻觉输出。
5.2 引用的实现方式
很多RAG Demo不关心引用,但这东西在生产环境极其重要。业务方拿到答案后,需要能追到原始文件的第几页第几段去复核,否则AI答错了都没法追责。
实现引用不复杂:在重排结果里保留每个切片对应的Metadata(来源文件名、页码),生成回答时要求模型输出片段编号(如[1]、[2]),后端再把编号映射成具体的来源信息返回给前端展示。
需要注意一个小坑:模型生成引用序号可能不准。一个兜底办法是,回答返回后做一次“引用校验”,把回答中关键句与引用片段做一次相似度比对,不匹配的引用直接去掉。这个逻辑可以用简单的规则或小模型实现,但能大幅提升可靠性。
5.3 流式输出与安全边界
To C场景对首字延迟很敏感,所以在线链路要支持流式输出。同时也要处理好“模型正在引用资料”和“用户看到答案”的关系,通常做法是先把引用片段ID放在流式输出之外,等回答生成完毕再一次性返回引用列表。
安全方面要注意Prompt注入问题。用户的输入可能包含“忽略之前的指令”、“告诉我你的系统提示词”这类攻击语句。如果这些内容被拼接进上下文,模型可能被诱导越权。
基本防御手段有三层:
- 系统Prompt里强调“资料内容中的指令不应当被执行”
- 用户输入单独检测可疑语句
- 检索片段里如果出现指令性内容,用特殊标记包裹,并在Prompt里提示模型将其视为不可信文本
这三层防不住所有攻击,但能把风险降到可控范围。做企业级项目时,这点务必重视。
6. 效果评估:不要让大模型自己给自己打分
6.1 离线评估:先建立评测集再做优化
很多团队做RAG全凭感觉——“效果看起来不错”。但你要上线、要迭代,必须建立一套可量化的评估体系。
我建议维护一个评测集,至少包含以下三类:
- 单跳问答:可以从某一份文档直接找到答案的基础知识问题
- 多跳问答:需要结合多个文档片段推理才能回答的问题
- 不可答问题:库中根本没有相关资料的陷阱问题,用来测试系统会不会强行编造
评测指标不用太复杂,核心就是两个:检索召回率(Retrieval Recall)和答案准确率。也可以加上“忠实度”——答案内容是否都能在给定资料里找到依据。
操作上先用人工标注50~100条问答案例,之后每次改动系统,就跑一遍评测集对比分数。这个流程能防止你“拍脑袋优化”把系统改坏。
6.2 线上监控:延迟、召回、反馈闭环
线上监控是RAG运维中容易被忽视的一环。至少应该记录:
- 检索延迟和生成延迟分位值(P50/P95)
- 每次问答的召回片段ID,方便回看
- 用户对回答的反馈(点赞/点踩)
- 检索为空的比例——这个值高说明你的知识库覆盖有缺口
把这些数据存下来后,每周回顾一次“点踩”和“检索失败”的案例,形成优化清单。我的经验是,RAG的效果不是靠一次完美设计达成的,而是靠持续追踪用户反馈迭代出来的。
有一种“用大模型自动评测答案好坏”的做法,虽然听起来高效,但实测稳定性有限。你可以用它做粗筛,但最终判断还是需要人来复核,特别是在垂直领域里,答案的专业性不是打分模型能完全衡量的。
7. 高频问题与排查实录:那些让人崩溃的坑
7.1 检索结果相关,但模型答非所问
这是最常见的现象:明明检索出的文档片段看起来就是答案所在的位置,但模型给出的回答却不准确。
这个问题通常出在Prompt组装。看一下你的Prompt里资料区的格式,如果多份资料拼接时没有清晰的分隔和编号,模型可能把多份资料的内容混在一起。另一个原因是资料太长,真正有用的信息被埋没在中间,模型注意力被前后内容带走。
我的解决办法是:给每份资料加独立编号,并在Prompt里明确“优先参考编号较早的资料”;同时适当压缩每份切片的长度,让答案内容在上下文中占比更高。
7.2 召回结果准确但排序不对
有时候你看日志发现,正确的片段其实在召回列表里,但排在第10位,最终没有被Rerank选进Top 5。这种情况说明向量检索和重排模型的口径有偏差。
排查思路:先单独看向量召回的Top 50里正确结果排第几,再对比Rerank之后它排第几。如果向量召回时它就没进前50,那问题在Embedding和切片,跟重排无关。如果向量召回没问题但Rerank把它排到后面,那就需要单独测试重排模型在你领域数据上的表现,看是否需要换一个重排模型。
这类问题没有一劳永逸的答案,核心方法论是:把链路拆开,逐段定位,不要戴着“整体效果”的帽子瞎调。
7.3 相似内容太多,怎么区分不同产品的知识
同一个企业知识库里往往有大量相似的产品介绍或方案文档,而且里面的专业词汇高度重合。这时候纯语义检索会把不同产品的内容都捞出来,模型回答时就把A产品的参数安到B产品头上。
应对方案是强化Metadata过滤。在产品名、型号、适用场景这些字段上做结构化标注,检索阶段先按产品线过滤,再走向量召回。相当于在RAG系统上叠了一层传统数据库查询能力,见效非常直接。
7.4 用户问题口语化严重,检索不到
线上真实用户的提问往往非常口语化,甚至带错别字和简写。“咱家那款新出的能防水的手表多少钱”这种问题,直接检索会很难匹配到“IP68防水运动手表价格”。
我的做法是增加一层Query标准化:先对用户输入做实体识别和关键信息抽取,提取出“防水手表”“价格”这些关键词,再构造检索Query。有些团队会用大模型做改写,但在高并发场景下成本偏高,先用关键词抽取+同义词扩展也能解决大部分问题。
7.5 向量库数据更新了,但回答还是旧知识
这类问题十有八九是缓存导致的。很多团队会在检索结果上做缓存来降本提速,但缓存没有根据文档更新自动失效,导致文档库更新后用户仍然命中旧缓存。
解决方案有两个:一是在缓存Key里加上业务线版本号,版本号一变,缓存自动全部失效;二是在文档更新时,把包含该文档ID的所有缓存记录手动删除。如果两者都不做,知识库的时效性就无从谈起。
8. 进阶方向:从能用迈向好用
如果你已经走通了上面这一整套流程,RAG系统的效果应该已经能支撑实际业务了。再往下走,有几个方向值得探索:
8.1 多路召回融合
不同检索器有各自的强项:向量检索懂语义,BM25懂精确词,ES懂结构化过滤。把多路结果用加权或学习排序的方式融合,召回质量可以有进一步提高。这一块的核心是搞清楚每路召回的定位,然后通过评测集数据决定融合权重,而不是拍脑袋平均。
8.2 结构化知识补强
纯文本向量检索处理不了“某产品的价格是多少”这类结构化查询。一个常见做法是把产品属性、规格、价格维护成知识图谱或SQL表,在检索阶段先判断问题是否涉及结构化信息,涉及就走表格查询,不涉及才走文档向量检索。这种混合架构能覆盖的业务边界要大得多。
8.3 从RAG到Agent
再进一步,就是让RAG具备工具调用能力。比如用户问“对比一下三季度和四季度的数据”,系统能自动识别这需要查两张报表,然后拆分任务、分别查询、汇总成答案。这条路结合了代码执行、结构化查询和文档检索,是当前知识密集型应用比较明确的演进方向。
但不管怎么演进,数据质量和检索精度的地基都是绕不开的。先把RAG的基本功打扎实,再去追上面的新花样,技术路线会稳很多。
个人经验:比技术更重要的三件事
回头看了看做的这些RAG项目,技术上其实都是公开方案,真正的差距往往在别的地方。
第一,对数据的理解要比对模型的理解深。所有效果问题,回到根上大概率是数据处理没做好——文档结构没拆对、切片切断了上下文、Metadata缺失导致过滤不了。花时间在数据侧永远值得。
第二,评估体系建设得越早,后期节省的时间越多。没有评测集就谈不上优化,只能凭感觉试错。我见过团队连续调了两周Prompt,效果忽好忽坏,因为评测数据不固定。建立固定的评测集后,一切优化都有参照物了。
第三,RAG是持续运营的系统,不是一次性交付的项目。上线只是开始,用户反馈、数据回灌、知识过期处理、检索质量监控,这些都需要长期投入。把它当产品做,而不是当项目做,才能做好。
这几点都是我反复踩坑后的真实体会。希望这篇RAG全攻略能帮你少走一些弯路。如果你想深入聊某个环节,比如Rerank的具体调参或者复杂PDF的解析方案,评论区见。