大语言模型技术指南:RAG 为什么能补知识盲区?检索、切块、重排与生成参数详解
前一篇我们已经把 Function Calling、Tool Use 和 Agent 的边界拆开了。
如果说工具调用解决的是"大模型如何与外部能力交互",那 RAG 解决的就是另一个更高频的问题:
模型明明很强,但一旦遇到私有知识、最新信息、专业文档或者长篇业务资料,它还是会答错、答旧、答得像是"半懂不懂"。
这不是模型突然变笨了。
而是因为参数化模型天然有几个边界:
- 训练数据不是实时更新的
- 模型参数不是企业私有知识库
- 长文档即使塞进上下文,也会有成本、长度和注意力稀释问题
- 单靠微调,并不能高效覆盖高频变化的业务知识
所以很多团队最后都会走到 RAG。
但一提到 RAG,很多讨论又容易过于简化,好像它只是"先检索一下,再把资料塞给模型"。
真正上线之后,问题马上就来了:
- 为什么明明做了向量检索,回答还是不准?
- chunk size 到底设多大?overlap 要不要开?
- embedding 模型到底怎么选?维度越大越好吗?
- top-k 是越大越稳,还是越大越乱?
- reranker 值不值得加?
- 检索到了很多材料,怎么拼进上下文才不浪费 token?
- 生成阶段 temperature、max tokens、system prompt 又该怎么配?
这篇就把 RAG 按工程链路拆开讲清楚。
我会重点讲四件事:
- RAG 到底在补什么,不要把它理解成"外挂知识库"这么简单
- 检索链路怎么设计:切块、embedding、召回、重排分别负责什么
- 关键参数怎么调:chunk size、overlap、top-k、embedding dim、max context 等
- 生产部署里最容易踩的坑:召回准但回答差、检索多但上下文乱、成本高但收益低
如果你正在做知识库问答、企业文档助手、客服问答、论文检索、代码知识助手,RAG 基本绕不过去。
一、先说结论:RAG 不是让模型"记住更多",而是让模型在回答前先"看资料"
很多人第一次接触 RAG,会把它理解成一种"给模型扩容知识"的方法。
这个说法不算全错,但不够精确。
RAG 更准确的本质是:
不要强迫模型把所有知识都压在参数里,而是在回答时先从外部知识库里找相关材料,再基于材料生成答案。
所以它不是直接修改模型参数,而是在推理阶段增加了一个"先查再答"的过程。
这和微调的思路不一样。
- 微调是把某类能力或风格写进模型参数
- RAG 是把外部知识在推理时动态注入上下文
因此两者擅长解决的问题也不同。
1)RAG 更适合"知识经常变、内容很多、要求可追溯"的任务
典型场景包括:
- 企业内部规章、产品文档、接口文档
- 法律条款、医疗指南、论文资料
- FAQ、客服知识库、售后手册
- 代码仓库文档、架构说明、变更记录
- 每天都在更新的数据、公告和报告
这类问题的共同点是:
- 知识更新频繁
- 原始文档比较长
- 需要引用原文依据
- 不适合每次改一点内容就重新微调模型
RAG 在这里的优势非常直接:
知识和模型解耦。
你更新知识库,不一定需要改模型;你换模型,知识库也不需要重建一遍业务逻辑。
2)RAG 不是万能补丁,它补的是"外部知识访问",不是所有能力缺陷
要避免另一个常见误区:
不是模型答不好,就都靠 RAG 补。
RAG 擅长解决的是:
- 知识新旧问题
- 私有数据访问问题
- 长文档定位问题
- 证据可追溯问题
但它不天然解决:
- 复杂逻辑推理弱
- 多跳规划不稳定
- 工具执行错误
- 输出格式不稳定
- 幻觉完全消失
如果底模太弱、提示设计太差、问题本身需要执行 SQL 或调用 API,单靠 RAG 也救不了。
一句话说:
RAG 是给模型补"资料",不是给模型补"智商"。
二、一个完整 RAG 系统通常不是一段检索,而是四段链路
很多 demo 会把 RAG 画成两步:
- 检索
- 生成
但在真实工程里,至少应该拆成四层:
- 数据入库层:文档清洗、切块、元数据抽取、向量化、建立索引
- 召回层:根据用户问题检索候选片段
- 重排层:从候选片段中筛出最相关的一小批
- 生成层:把片段组织进 prompt,让模型基于证据回答
只要其中一层做得粗糙,最后回答质量就会明显掉。
1)数据入库层决定"知识能不能被找出来"
入库不是把 PDF 扔进去就结束了。
至少要处理这些问题:
- 文档结构能不能保留标题层级
- 表格、代码块、公式、图片说明是否丢失
- 文本里有没有大量页眉页脚、目录、重复水印
- 不同文档是否带上来源、时间、部门、版本号等元数据
如果原始文本很脏,后面检索再高级也很难救回来。
2)召回层解决"从海量材料里先粗筛出可能相关的内容"
召回阶段通常追求的是:
宁可先多找一些候选,也不要一开始就把关键证据漏掉。
所以这里更看重 recall,而不是最终排序绝对精准。
常见做法包括:
- 稀疏检索:BM25、关键词倒排
- 稠密检索:embedding 向量相似度搜索
- 混合检索:关键词召回 + 向量召回并集或加权
很多业务里,混合检索往往比单一向量检索更稳。
因为关键词检索对精确术语、编号、错误码、产品型号特别有效;而向量检索更擅长语义近似和表达改写。
3)重排层解决"候选很多,但真正最该看的只有少数几段"
召回出来的前 20 段、前 50 段,往往并不能直接丢给模型。
原因很简单:
- token 成本太高
- 噪声太多会冲淡关键信息
- 相似片段过多会让上下文变得冗余
所以通常还需要 reranker。
reranker 会基于"query + 文档片段"的相关性做更细排序。
它和 embedding 检索的差别在于:
- embedding 更像粗召回,追求快和覆盖
- reranker 更像精排,追求前几名真的相关
在高质量问答系统里,reranker 经常是最划算的增益模块之一。
4)生成层解决"怎么把证据变成答案"
即使检索完全正确,生成层也可能把答案做坏。
常见原因包括:
- prompt 没要求"仅基于给定材料回答"
- 没要求引用来源
- 上下文拼接顺序混乱
- 模型看到太多无关材料后开始自由发挥
- temperature 太高导致证据约束变弱
所以 RAG 的最后一公里,不是"把检索结果喂给模型"这么简单,而是:
如何设计一个让模型优先尊重证据、而不是优先发挥语言流畅性的生成环境。
三、切块为什么是 RAG 的基本功:chunk 切得不对,后面全是补救
很多 RAG 系统效果不好,根因不是模型不行,而是 chunk 策略太粗糙。
因为检索的基本单位,不是整本手册,而是你切出来的片段。
片段切得差,会出现两类问题:
- 该在一起的信息被拆散,召回后不完整
- 不该在一起的信息被混在一块,召回后噪声太大
1)chunk size 不是越大越好,也不是越小越好
chunk 太小的问题:
- 上下文不完整
- 指代丢失
- 一个结论和它的条件、表格、备注被拆开
- 模型读到证据时缺背景
chunk 太大的问题:
- 噪声增多
- 一个片段包含多个主题
- 检索命中后会把很多不相关文字一起带进来
- embedding 表示被平均化,区分度下降
工程上常见的起点配置大概是:
- 通用中文文档:300~800 tokens
- FAQ 或短说明文:150~400 tokens
- 技术手册、论文段落:400~1000 tokens
- 代码与接口文档:更适合按函数、类、章节做结构化切分,而不是纯固定长度切块
这不是绝对数值,但可以作为第一轮实验基线。
2)overlap 的意义,是避免关键信息刚好被切断
很多信息天然跨段落存在。
比如:
- 定义在上一段,约束在下一段
- 标题在前一段,细节在后一段
- 一个表格说明和表格主体被切开
这时 overlap 就很重要。
常见经验值:
- 10%~20% 的重叠比例是比较常见的起点
- 太小,补不上边界信息
- 太大,会造成库里片段高度重复,增加召回冗余
如果你的文档结构很规整,overlap 可以适当小;如果文档是 PDF 转文本、段落边界不稳定,overlap 往往要更保守一点。
3)比固定长度更重要的,是结构感知切块
高质量 RAG 系统通常不会只按字符数或 token 数硬切。
更好的策略通常是:
- 先按标题层级切
- 再按段落边界切
- 超长段再做二次切分
- 表格、代码块、列表尽量保持整体
- 给每个 chunk 带上父标题、章节路径、来源链接等元数据
因为用户问问题时,真正需要的往往不只是某几句话,而是:
这段话属于哪一章、哪一节、哪份文档、哪个版本。
这些结构信息对后续重排和生成都很有价值。
四、embedding 到底在做什么:它不是"理解一切",而是把语义映射到可检索空间
embedding 的作用可以简单理解成:
把文本变成向量,让语义相近的内容在向量空间里也更靠近。
这样用户问题也转成向量之后,就可以做近邻搜索。
1)embedding 模型选择,先看领域匹配,再看成本和延迟
很多人会先问:维度越大是不是越强?
不一定。
更关键的通常是:
- 这个 embedding 模型是否适合你的语言
- 是否适合你的领域术语
- 对长文本片段表现如何
- 推理成本和吞吐能不能接受
比如中文、代码、法律、医学文档,对 embedding 模型的偏好往往不同。
如果业务里术语密度很高,领域适配通常比单纯追求"大维度"更重要。
2)embedding dim 会影响精度、存储和检索效率
embedding 维度越高,通常意味着:
- 向量索引更占空间
- 检索内存和带宽压力更大
- 建库和更新成本更高
有时也可能带来更强表达力,但不一定线性提升。
所以不要把维度当成唯一指标。
更合理的思路是:
- 在同一批评测集上比较 Recall@k、MRR、nDCG
- 同时观察建库时间、查询延迟、内存占用
- 选择"效果---成本"更平衡的一组
3)query 和 document 是否使用同一套编码方式,也会影响效果
有些 embedding 方案针对 query 和文档会用不同模板或前缀。
如果编码方式没对齐,检索质量会明显下降。
所以落地时要非常确认:
- 入库文本和查询文本是否用了同一套预处理
- 是否添加了推荐的 instruction/prefix
- 中英文标点、空白、代码格式是否被过度清洗
RAG 很多时候不是"模型不行",而是 preprocessing 把语义搞坏了。
五、top-k、混合检索、reranker:召回参数到底怎么调
检索参数最常见的误区,是一味追求"多拿一点总没错"。
其实未必。
1)top-k 不是越大越好
top-k 太小的问题是:
- 真正证据可能没进候选集
- 多跳问题缺少补充背景
top-k 太大的问题是:
- 噪声越来越多
- reranker 成本上升
- 生成时上下文选择更困难
- 模型更容易被次相关内容带偏
工程上常见起点:
- 仅检索不重排:top-k = 3~8
- 检索后带 reranker:召回可先放到 20~50 ,再精排出 3~8 段进入生成
也就是说:
- 粗召回可以稍大
- 最终喂给模型的证据数量要克制
2)混合检索对真实业务通常更稳
尤其在这些场景里:
- 用户会问产品名、接口名、错误码、文档编号
- query 中有精确短语
- 业务术语拼写很固定
如果只做向量检索,模型可能找到"语义接近但不是那一条"的内容。
所以一个常见稳妥方案是:
- BM25/关键词检索召回一批
- embedding 检索再召回一批
- 两边做并集、加权或融合排序
这通常比"纯向量一把梭"更抗业务噪声。
3)reranker 特别适合解决"召回看似都相关,但优先级不对"
很多系统的失败,不是完全没召回,而是最关键的一段没有排到前面。
比如用户问:
"退款规则里,课程开通后还能不能退?"
召回结果可能都和退款有关,但真正关键的是那一段包含"开通后不可退 / 某条件下可退"的条款。
这种时候 reranker 往往能明显提升首条命中率。
如果你只能优先加一个模块,我通常会建议优先验证:
混合检索 + reranker 能不能把前 3 条命中率显著抬起来。
六、上下文怎么拼,比"检索到什么"还更影响最终答案
很多团队做到检索准确率还不错,但用户仍然觉得回答一般。
原因往往出在 context packing。
1)不要把所有召回结果机械拼接
常见错误是:
- 直接按相似度从高到低把 10 段全文拼进去
- 不去重
- 不按来源组织
- 不管是否相互矛盾
这样做的问题是:
- prompt 很长
- 重复信息很多
- 不同文档互相打架
- 真正关键的句子反而埋在里面
更合理的做法通常包括:
- 相邻 chunk 合并,减少碎片感
- 重复内容去重
- 同文档片段优先聚合
- 把高可信来源放前面
- 如果有时间维度,优先最新版本
2)生成 prompt 要明确"答案必须以证据为边界"
RAG prompt 里最关键的不是"请你回答下面问题",而是约束边界。
例如应该明确要求:
- 仅根据提供资料回答
- 如果资料不足,明确说不知道或信息不足
- 优先引用原文关键表述
- 给出来源标题或编号
- 避免使用模型自身未验证知识补洞
因为一旦约束不清,模型就会把"检索证据"和"自己脑补"混在一起。
3)max context 不是越塞满越值钱
上下文窗口很大,不等于就应该尽量塞满。
上下文越长,往往意味着:
- prefill 成本更高
- 延迟更大
- 证据密度下降
- 模型注意力分散
在很多任务里,高密度的 3~6 段有效证据,比十几段松散材料效果更好。
所以 context packing 的目标不是"塞满窗口",而是"提高证据密度"。
七、生成参数怎么配:RAG 任务里要优先稳,不要优先花哨
RAG 不是创意写作。
它更像基于证据的受限生成。
因此生成参数通常要比普通对话更保守。
1)temperature 通常建议偏低
常见经验:
- 事实型问答:0.0~0.3
- 证据总结、报告抽取:0.1~0.4
- 如果需要更自然的表述,但仍基于资料:0.3~0.5
temperature 太高时,模型会更愿意"补充得更像人话",但这也意味着更容易脱离证据。
2)max tokens 要和回答任务匹配
太短会截断答案。
太长则会让模型在核心答案说完后继续扩写,增加幻觉风险。
可以按任务拆:
- FAQ 类:200~500 tokens
- 文档问答解释类:400~1000 tokens
- 长摘要或多点归纳:800~1500 tokens
重点不是固定数字,而是不要无上限放任生成。
3)system prompt 最好明确处理"不知道"的策略
高质量 RAG 系统的一个标志,不是它什么都能答,而是:
资料不足时,它能老老实实承认不足。
所以 system prompt 通常应该明确:
- 未找到证据时,不要猜
- 证据冲突时,指出冲突来源
- 如果问题超出资料范围,直接说明范围限制
这类约束会显著降低"看起来很完整、其实不靠谱"的回答。
八、RAG 上线后最常见的四类问题
1)检索指标不错,但用户答案满意度还是低
这通常说明问题不在召回,而在生成。
要检查:
- prompt 是否鼓励模型自由发挥
- context 是否冗余太大
- 最终送入模型的片段是否顺序混乱
- 是否缺少来源引用与边界约束
2)召回总是差一点,但不是完全错
这通常说明需要看:
- chunk 是否切坏了
- embedding 是否不适合领域
- 是否应该加关键词检索
- 是否需要 reranker
- query 是否需要重写或扩展
很多时候,问题并不在模型,而在召回链路过于单薄。
3)成本和延迟太高
RAG 很容易出现"每个问题都查很多、拼很多、排很多"。
要优化时,优先看:
- top-k 是否过大
- reranker 是否对所有请求都启用
- 是否可以先做轻量召回,再按置信度决定是否进入精排
- chunk 是否太碎导致候选数暴涨
- 是否可以缓存热门 query 或热门文档向量
RAG 不是模块越多越好,而是链路越合理越好。
4)回答引用了资料,但还是答偏
这通常是因为"检索相关"不等于"回答可用"。
比如召回来的片段确实谈的是同一个主题,但并不是回答该问题所需的那一段。
所以评测不能只看是否召回到相关文档,还要看:
- 关键证据是否在前几名
- 最终答案是否真的用到了关键证据
- 来源引用是否对应答案结论
九、评测 RAG,不能只看大模型主观觉得"像对的"
RAG 系统特别容易被 demo 幻觉欺骗。
因为很多回答读起来很流畅,但不代表真的建立在正确证据上。
更稳的评测思路通常至少分三层:
1)检索层评测
看召回质量:
- Recall@k
- Precision@k
- MRR
- nDCG
- 关键证据是否进入候选集
2)重排层评测
看最关键证据能否排到前面:
- top-1 / top-3 命中率
- reranker 前后排序变化
- 首条证据是否可直接支持答案
3)生成层评测
看回答是否真的忠于资料:
- 是否引用正确来源
- 是否出现资料中没有的结论
- 资料不足时是否会拒答
- 用户问题中的关键点是否被完整覆盖
如果业务足够重要,最好自己做一小套标注集。
别只依赖"问几个样例感觉还行"。
十、什么时候该用 RAG,什么时候不该强上
适合用 RAG 的情况:
- 知识量大,更新频繁
- 文档是主要信息来源
- 需要可追溯证据
- 业务问答高度依赖私有资料
- 不希望频繁微调模型
不适合只靠 RAG 的情况:
- 任务本质是执行,不是问答
- 问题依赖实时数据库操作或业务动作
- 需要复杂工作流编排
- 输出需要严格结构化或调用外部系统
这类场景通常应该是:
- RAG 负责找资料
- Tool Use 负责执行动作
- Agent 负责多步协调
也就是说,RAG 不是所有系统的终点,它更像知识访问层。
十一、落地建议:如果你现在要做一个企业知识助手,我会建议这样起步
先不要一上来就堆最复杂的架构。
更稳的第一版路线通常是:
- 先把文档清洗做好:标题、段落、表格、元数据别丢
- 先做结构感知切块:不要只按固定长度硬切
- 先上混合检索:关键词 + 向量,一般比纯向量更稳
- 再加 reranker:重点优化前 3 条证据命中率
- 生成参数保守一些:低 temperature,强来源约束
- 做小规模人工评测集:别只看 demo 手感
- 按延迟和成本逐步优化:不要一开始就把链路搞得过度复杂
如果你把这七步做扎实,第一版 RAG 的可用性通常已经会比"直接把 PDF 塞进大模型"高一个层级。
十二、最后总结
RAG 之所以重要,不是因为它让模型突然拥有了无限知识。
而是因为它提供了一种更符合工程现实的知识使用方式:
- 模型负责理解问题和组织答案
- 检索系统负责找到相关材料
- 重排系统负责把关键证据排到前面
- prompt 与生成参数负责约束模型忠于证据
所以一个好用的 RAG 系统,本质上不是"模型更会背书",而是:
模型在回答之前,真的先看了对的资料,并且只在证据边界内回答。