
1. 为什么“检索增强”成了大模型落地的必选项大模型刚火起来那阵子我身边不少做应用的朋友都有个朴素的想法模型参数够大、训练数据够多问它什么它就该知道什么。结果真上手做业务系统才发现模型对自家公司内部的文档、产品手册、客服话术、历史工单几乎一无所知问它一个上周刚更新的价格政策它能一本正经地编出一个完全不存在的数字。这个现象在圈子里有个很形象的说法叫“幻觉”说白了就是模型在不知道答案的时候倾向于用最像答案的语言把空填上而不是老老实实说“我不知道”。RAG也就是检索增强生成正是冲着这个痛点来的。它的核心思路其实一点都不玄乎既然模型脑子里没装这些私有知识那就在回答问题之前先去外部知识库里把相关资料捞出来塞进模型的上下文里让它“看着材料答题”。这就像开卷考试和闭卷考试的区别——闭卷考的是模型预训练时记住的东西开卷考的是它临场阅读和归纳的能力。而绝大多数企业场景需要的恰恰是开卷考。我之所以想系统聊这个话题是因为RAG看起来简单真做起来坑非常多。很多人第一次搭RAG就是“文档切一切、向量存一存、问题搜一搜、答案拼一拼”跑个demo效果惊艳一上真实业务就原形毕露检索回来的东西驴唇不对马嘴或者明明检索对了模型却答偏了再或者文档一更新整个库就得重建。这些问题背后涉及文档切分策略、向量模型选型、检索召回与重排、上下文组装、生成约束等一整套工程细节。这篇文章我会把这些环节拆开讲透既讲清楚每一步“为什么这么做”也给出可以直接抄作业的参数和代码适合正在做RAG落地、或者被RAG效果折磨过的开发者参考。2. RAG的完整链路拆解从一份PDF到一句靠谱的回答2.1 离线索引阶段文档是怎么变成“可检索知识”的RAG的链路分成两段一段是离线的索引构建一段是在线的查询生成。很多人只盯着在线那一段调优其实离线阶段的质量直接决定了天花板。索引阶段干的事是把各种格式的原始文档PDF、Word、网页、数据库记录转成一段段文本再转成向量存进向量数据库。这里面第一个关键动作是文档解析。PDF是最麻烦的尤其是那种扫描件或者排版复杂的报告直接抽文字经常抽出乱码或者顺序错乱。我的经验是能用结构化格式Markdown、HTML、JSON就别用PDF如果非要用PDF优先选带文本层的扫描件走OCR并且一定要保留标题层级信息因为标题对后续切分和检索权重影响很大。第二个动作是文本切分也就是chunking。这是最容易被低估的一步。切得太碎一段话被拦腰截断语义不完整检索出来模型也读不懂切得太大一个chunk里混了好几个主题向量表示被稀释检索精度下降。业界常见的做法是固定长度加重叠比如每段500个token相邻段重叠50到100个token防止关键信息正好卡在边界上被切断。但固定长度切分有个明显缺陷它不管语义边界。更好的做法是按语义或结构切分比如按Markdown的标题层级切一级标题下的内容作为一个父块二级标题下的作为子块检索时用子块匹配、返回时带上父块上下文。这种“父子块”策略在实际项目里效果提升很明显因为它兼顾了检索精度和上下文完整性。2.2 向量化选对嵌入模型比调参更重要文本切好之后要转成向量。这一步用的是嵌入模型embedding model。嵌入模型的质量直接决定检索的召回率我的观点是在RAG里嵌入模型的选择比大模型的选择还关键。因为大模型再强你喂给它的资料是错的它也答不对。选嵌入模型要看几个维度。第一是语言支持中文场景一定要选中文语料训练充分的模型很多英文为主的模型在中文语义相似度上表现很差。第二是维度维度高表达能力更强但存储和计算成本也高常见的有768维、1024维、1536维一般1024维是个不错的平衡点。第三是最大输入长度如果你的chunk比较长模型支持的长度要够否则会被截断。这里有个实操细节查询和文档必须用同一个嵌入模型。我见过有人索引时用一个模型查询时图省事换了另一个结果向量空间都不一致检索结果完全是随机的。另外有些嵌入模型对查询和文档有专门的指令前缀比如查询前加“query:”文档前加“passage:”用之前一定要看模型文档加不加前缀效果差很多。2.3 向量库与检索相似度搜索只是起点向量存进向量数据库之后查询时把用户问题也转成向量做相似度搜索返回最相近的top-k个chunk。这一步听起来简单但有几个参数需要认真对待。相似度度量常见的有余弦相似度和内积。余弦相似度只看方向不看长度适合大多数文本场景内积对向量长度敏感如果向量做过归一化两者等价。选哪个取决于你的嵌入模型是怎么训练的一般模型文档会说明推荐用哪种。top-k的选择是个权衡。k太小可能漏掉关键资料k太大噪声变多还会挤占大模型的上下文窗口。我的经验是先用一个中等值比如5到10然后结合重排来精筛。这里就要提到**重排rerank**了。向量检索是“粗筛”它基于语义相似度快速从海量文档里捞出候选重排是“精筛”用一个更精细的交叉编码器模型把问题和每个候选chunk拼在一起打分精度更高但速度慢所以只对粗筛出来的少量候选做。加了重排之后检索质量通常有明显提升这是很多RAG系统效果上不去的关键补丁。2.4 生成阶段怎么让模型“照着材料说话”检索回来的资料要组装进提示词连同用户问题一起发给大模型。这一步的提示词设计非常讲究。核心原则是明确告诉模型只能用给定资料回答资料里没有就说不知道不要自己发挥。同时要给出引用要求让模型在答案里标注信息来自哪段资料方便溯源。上下文组装还有个技巧叫上下文压缩。检索回来的chunk里往往有很多和问题无关的句子全塞进去既浪费token又干扰模型。可以用一个小模型或者规则把每个chunk里真正相关的句子抽出来再拼给大模型。另外chunk的排序也有讲究把最相关的放在最前面或最后面因为大模型对上下文首尾的信息更敏感这是所谓的“迷失在中间”现象。3. 检索召回不准先别急着换模型查这五个地方3.1 切分粒度是不是和问题粒度对不上检索不准最常见的原因是chunk的粒度和用户问题的粒度不匹配。用户问的是一个很具体的小问题比如“某产品的退货期限是几天”但你的chunk是整节产品政策几百字混在一起向量表示被稀释相似度算出来就不高。反过来用户问的是一个宏观问题你的chunk却是一句话检索出来的碎片拼不成完整答案。解决办法是多粒度索引。同一份文档既切成大块也切成小块小块用于精确匹配大块用于提供上下文。检索时先用小块的向量去匹配命中后把对应的大块返回给模型。这样既保证了匹配精度又保证了上下文完整。这个策略我在多个项目里验证过对问答类场景提升尤其明显。3.2 嵌入模型是不是没针对你的领域微调通用嵌入模型是在海量通用语料上训练的对日常语言理解很好但遇到专业术语密集的领域比如医疗、法律、工业设备手册它的语义空间可能没覆盖好。举个例子用户问“设备报E05错误怎么处理”文档里写的是“故障代码E05对应过载保护触发”通用模型可能觉得这两句相似度一般因为它们用词差异大。这种情况下领域微调嵌入模型是值得投入的。用领域内的问答对或者相似句对做对比学习训练让模型学会把“报错”和“故障代码”、“怎么处理”和“对应措施”拉到相近的向量位置。如果微调成本太高退而求其次可以用混合检索把向量检索和关键词检索比如BM25结合起来关键词检索能兜住那些术语精确匹配的情况两者结果融合后重排效果通常比单用向量好。3.3 查询本身是不是需要改写用户的提问往往很口语、很模糊甚至带错别字直接拿去做向量检索效果不好。这时候需要查询改写。常见做法有几种一是用大模型把口语化问题改写成更规范的检索式二是做查询扩展把一个问题拆成多个子问题分别检索再合并三是做假设文档嵌入让模型先“假装”生成一个答案再用这个答案去检索因为答案的措辞往往和文档更接近。我实测下来多查询扩展在复杂问题上效果最稳。比如用户问“新员工入职要办哪些手续”可以扩展成“入职流程”“新员工报到材料”“入职需要提交的证件”几个查询分别检索后去重合并召回率比单查询高不少。代价是多几次检索调用延迟会上升需要根据业务对延迟的容忍度来权衡。3.4 重排模型是不是被忽略了前面提过重排这里再强调一次因为太多人跳过这一步。向量检索的相似度是“粗粒度”的它把问题和文档分别编码成向量再算距离问题和文档之间的交互信息丢失了。重排模型是把问题和文档拼在一起过一遍能捕捉到细粒度的匹配关系比如否定、条件、数量这些向量检索容易忽略的东西。选重排模型时同样优先选支持中文的。重排的top-k一般设成粗筛的2到3倍比如粗筛召回20个重排后取前5个给大模型。重排模型比嵌入模型大推理慢所以候选数量不能太多否则延迟吃不消。3.5 元数据过滤是不是没用上很多文档自带丰富的元数据比如时间、部门、文档类型、版本号。用户问“最新的报销政策”如果你不按时间过滤可能检索出一堆旧版本模型看到互相矛盾的内容就懵了。元数据过滤是在向量检索之前或之后加一层结构化筛选把不相关的文档先排除掉能大幅提升精度。实操上可以在索引时把元数据一起存进向量库检索时带上过滤条件。比如按时间倒序取最新的或者按部门限定范围。这一层看似简单但在企业知识库场景里往往是效果提升的捷径因为很多错误答案不是语义匹配错了而是匹配到了过期或不适用的文档。4. 生成答案跑偏提示词、上下文与模型的三方博弈4.1 提示词里必须写死的几条约束生成阶段最怕的就是模型“自由发挥”。我见过模型明明检索到了正确资料却因为资料里有一句无关的旧信息就把旧信息当答案输出。要压住这种行为提示词里必须写死几条约束。第一条限定知识来源明确告诉模型“只根据以下资料回答不要使用你自己的知识”。第二条允许说不知道告诉模型“如果资料中没有相关信息直接回答‘根据现有资料无法回答’不要编造”。第三条要求引用让模型在每句话后面标注来源编号这样既方便溯源也能倒逼它基于资料说话。第四条格式约束如果需要结构化输出把格式要求写清楚比如用JSON或者固定的小标题。这几条约束写进去之后幻觉率会明显下降。但要注意约束太多太严模型可能变得过于保守明明资料里有答案却不敢答。所以约束的措辞要平衡既要限制发挥又不能让它畏手畏脚。4.2 上下文塞太多反而更差很多人有个误区觉得检索回来的资料越多越好恨不得把top-20全塞进去。实际上上下文过长会带来几个问题一是噪声干扰无关内容多了模型注意力被分散二是中间迷失前面提过模型对长上下文中间部分的信息利用效率低三是成本上升token多了推理费用和延迟都涨。我的做法是精挑细选。粗筛召回一批重排精筛出最相关的几个再做上下文压缩把每个chunk里真正相关的句子抽出来。最终给模型的上下文控制在合理长度内比如2000到4000个token具体看模型窗口和问题复杂度。宁可给模型少而精的资料也不要给多而杂的。4.3 模型选型不是越大越好生成模型的选择要结合场景。如果任务简单比如从资料里抽取事实性答案一个小一点、快一点的模型就够了成本低延迟低。如果任务复杂需要多步推理、综合多份资料那就得上能力更强的模型。另外指令遵循能力比单纯的参数规模更重要因为RAG场景高度依赖模型严格遵守提示词约束。还有一个实操点温度参数。RAG场景一般把温度调低比如0.1到0.3让输出更确定、更贴近资料。温度高了模型容易发散增加幻觉风险。当然如果业务需要一些创造性的表达可以适当调高但要配合更强的约束。4.4 引用溯源让答案可验证引用溯源不只是为了好看它是RAG系统可信度的基石。用户看到答案旁边标着来源可以点进去核对这大大降低了误信错误答案的风险。实现上可以在提示词里要求模型输出引用编号然后在后处理阶段把编号映射回原始文档的链接或位置。更严格的做法是答案级校验用另一个模型或者规则检查答案里的每句话是否真的能在引用的资料里找到依据。这一步会增加成本但在高准确性要求的场景比如客服、医疗咨询是值得的。我一般会先做引用如果业务反馈还有错误再上校验。5. 上线之后RAG系统的持续运营与迭代5.1 文档更新了索引怎么同步RAG系统不是搭完就一劳永逸的知识库会更新文档会增删改。如果每次更新都全量重建索引成本高、耗时长。合理的做法是增量索引文档新增时只对新文档做解析、切分、向量化、入库文档修改时先删掉旧版本对应的向量再插入新版本文档删除时同步删掉向量。要实现增量索引时得给每个chunk打上文档ID和版本号更新时按ID操作。向量数据库一般支持按元数据删除用这个能力就能做到精准更新。另外更新最好做成异步任务别阻塞在线查询同时要注意更新期间的一致性避免用户查到半新半旧的内容。5.2 怎么知道系统答得好不好上线之后得有评估机制否则你不知道改动是变好了还是变坏了。评估分两层检索层看召回率和准确率也就是该召回的资料有没有召回召回的资料有多少是相关的生成层看答案的忠实度和相关性忠实度指答案是否忠于资料、有没有编造相关性指答案是否切题。人工评估最准但成本高可以先用自动评估做日常监控。检索层可以用标注好的问答对算指标生成层可以用大模型当裁判让它对比答案和资料打分。再配合用户反馈比如点赞点踩、追问率综合判断系统健康度。我习惯建一个小规模的黄金测试集每次改动前后都跑一遍确保没有回退。5.3 成本和延迟怎么压RAG的延迟主要花在检索和生成两段。检索段向量搜索本身很快慢的是重排和多次查询扩展生成段慢的是大模型推理尤其是上下文长的时候。压延迟的思路有几个一是缓存高频问题的检索结果和答案缓存起来命中直接返回二是并行多个查询扩展并行检索重排和生成也可以流水线化三是模型分级简单问题走小模型复杂问题才走大模型。成本方面嵌入和重排的调用量比生成大但单价低生成是大头。控制上下文长度、减少不必要的检索调用、用更小的生成模型都能降成本。我的经验是先保证效果再在效果可接受的前提下逐步优化成本和延迟别一上来就为了省钱牺牲质量那样用户不买账。5.4 几个我踩过的坑和对应经验第一个坑是chunk重叠设太大。一开始怕切断信息重叠设了200个token结果索引膨胀检索时经常召回一堆高度相似的重复内容浪费上下文。后来把重叠降到50到100配合语义切分效果好很多。第二个坑是忽略文档的时效性。有次用户问最新政策系统返回了旧版本因为旧版本在向量空间里和问题更接近。后来加了时间元数据过滤默认只检索最近一年的文档问题解决。第三个坑是提示词里的资料编号和实际顺序对不上。检索结果经过重排后顺序变了但提示词里的编号没同步更新导致模型引用错乱。这个bug很隐蔽排查了半天才发现后来在组装上下文时统一重新编号杜绝了这个问题。第四个坑是用同一个嵌入模型处理所有语言。项目里有中英文混合文档一开始用英文模型中文检索效果很差。后来换成多语言模型或者按语言分库用不同模型才解决。6. 写在最后的一点个人体会RAG这个方向技术迭代很快新的嵌入模型、重排模型、向量库层出不穷但底层逻辑是稳定的把对的知识在对的时机喂给模型并约束它别乱说。我见过太多团队在模型选型上纠结很久却忽略了切分和检索这些更基础、更影响效果的环节。实际上一个切分合理、检索精准的RAG系统配一个中等能力的生成模型效果往往好过一个切分粗糙、检索拉胯的系统配顶级模型。如果你正准备做RAG我的建议是先跑通最小闭环然后拿真实业务问题去测重点看检索回来的资料对不对。检索对了生成基本不会太差检索错了再怎么调提示词都是治标不治本。把精力优先投在文档解析、切分策略、嵌入模型和重排上这几块的投入产出比最高。至于那些花哨的Agent、多跳推理等基础检索稳了再考虑也不迟。