
关于 RAG估计大家和我都会思考过一个问题召回不准是不是换个更强的向量模型就好了还有更干脆的直接说这些调来调去的活儿没意义等模型更新就行。这个直觉我太熟了因为我自己第一次排查召回问题时走的就是这条路。那是个金融保险公司的 RAG 问答系统5000 份文档条款、产品说明、理赔规则混在一起。第一版上线后我们拿内部标注的 200 条测试问句跑了一遍top_k 取 20平均每次召回里只有 4.8 条真正相关命中率 24%烂得很坦率。我当时的第一反应就是换模型embedding 从 bge-large-zh-v1.5 换成 bge-m3理由听起来很充分后者在 C-MTEB 检索任务上分数更高还支持稠密加稀疏的混合表示。全量向量重跑了一晚上阈值重新调了一天结果 4.8 条变成 5.1 条。一周时间换来 0.3 条。后来沿着整条链路从头查才发现真正的问题一个都不在模型上。最后召回质量做到 top20 平均 14 条以上相关靠的是五个比换模型便宜得多的环节。模型自始至终就没再换过。所以这篇想把顺序掰过来RAG 召回不准排查要从最便宜的环节往最贵的环节走换 embedding 排在整条链路的最后一位。九成人的顺序正好是反的。九成人的排查顺序和实测有效的顺序正好是反的为什么换模型几乎总是白费先把这个判断立住召回烂到 20 条里只有 5 条相关这种程度基本不可能是模型的锅。主流中文 embedding 模型之间的差距在榜单上是几个点的事。C-MTEB 检索任务里排名前后的模型分差通常在个位数百分比。而你的系统命中率只有 24%离能用还差着 40 多个点。几个点的模型差距填不上 40 个点的窟窿。窟窿这么大一定是链路上有环节在成规模地漏水。而换模型偏偏又是所有动作里最贵的5000 份文档全量重新向量化、检索阈值重调、测试集重跑我们当时折腾了一周。这就是为什么它该放最后代价最大预期收益最小。公平起见也说清楚什么时候换模型是对的链路各层都查过、命中率已经爬到七成往上、badcase 集中在语义确实很近但模型分不开的细粒度区分上这时候换个在你的领域上表现更好的模型或者干脆做领域微调才是对症的。换句话说换模型是精修手段不是抢救手段。抢救阶段用精修手段就是我那浪费掉的一周。反过来下面这五层每一层都比换模型便宜而且每一层我都实打实踩到了坑。五层排查阶梯从便宜查到贵命中一路爬排查之前先搭一把尺子五层排查讲究一个前提每动一层你得知道这层到底有没有用。没有测试集排查就是玄学改完全凭感觉说好像准了点。我们的做法很土但很管用。从线上真实提问里抽了 200 条问句人工给每条标注出应该被召回的文档块存成一份固定的测试集。之后每改动一层就把 200 条全量跑一遍看 top20 里平均命中几条标注块。前面提到的 4.8、8.9、12.6 这些数字全是这份测试集上跑出来的同一把尺子量到底。标注 200 条花了两个人一天半这笔投入后来证明是全项目回报率最高的一笔。它还有个副作用标注过程本身就会暴露问题标到第 30 条你就会发现这问题文档里根本没答案这类问题占了我们 200 条里的 17 条属于知识库覆盖缺口检索链路调破天也解决不了得单独走补文档的流程。尺子搭好再开始从最便宜的一层查起。第一层数据清洗最便宜也最容易被跳过拿到文档直接向量化入库是我见过最普遍的做法。没人先打开原始数据看一眼。我们那批保险文档扒开看问题一堆每页带页眉页脚正文里夹着表格转换失败的乱码每份文档尾部挂一串相关产品推荐还有同一段免责声明一字不差地出现在 37 份文档里。重复文本对向量检索是主动投毒。那段出现 37 次的免责声明会把这 37 份文档在向量空间里拽得彼此很近用户随便问点什么它们都以高相似度的姿态挤进召回。页眉页脚这些高频模板文本会把每份文档的语义重心往同一个方向拉文档之间的区分度直接被抹平。发现这些问题不需要什么高级手段。重复文本用最笨的办法就能抓把所有块做个哈希去重统计出现次数排前面的一眼就能看出是模板文本我们没上 SimHash 这类近似去重精确匹配加人工过一遍 top100 高频块就够用了毕竟入库是离线动作慢一点没关系。乱码块用一个简单规则筛非中文字符占比超过四成的块单独拉出来人工看。清洗规则最后落成一个入库前的预处理脚本剥页眉页脚、去掉出现超过 5 次的重复段落、丢弃乱码块。光这一步200 条测试问句的 top20 平均相关数从 4.8 涨到 8.9。代价是这个脚本从此要跟着文档格式一起维护新来一批格式不同的文档规则就要检查一轮这是笔持续的小成本不是一次性的。一行检索代码没改一个模型没动命中率快翻倍了。这也是我最想让你记住的第一句话召回的上限在文档入库那一刻就定下了大半。重复声明怎么把向量空间搅浑第二层切分最容易翻车的一刀数据干净了第二个查切分。我第一版图省事固定 512 token 一刀切。这种切法按字数下刀不看语义翻车方式很固定一个完整的逻辑单元被劈成两半。给一个完整的 badcase。文档里第七条 免责条款的标题和它对应的九种免责情形隔了 600 多 token被切进了两个不同的块。用户问哪些情况不赔向量检索召回了带免责条款四个字的标题块模型拿着这半截内容回答根据条款本产品设有免责情形具体以合同为准。看着像回答了实际什么都没说。错的根源不在检索也不在生成在切分那一刀劈错了位置。固定切分还有个更隐蔽的坑块的长度和 embedding 模型的输入上限不匹配。我们当时用的 bge-large-zh-v1.5输入上限 512 tokenbge-m3 放宽到了 8192但截断的坑逻辑相同你切 512 的块看起来正好但加上标题前缀和特殊 token 之后实际会超超出的部分被静默截断块尾的内容根本没参与编码。也就是说有些内容不是没被召回是从来就没进过向量空间。这个问题不看模型文档、不查编码长度从检索结果上是完全看不出来的。后来改成按结构切保险文档条款编号规整按条款边界切块超过 400 token 的长条款再做二次切分留出前缀余量避开截断块间留 50 token 重叠防止边界句被切断。改完之后 top20 平均相关数从 8.9 涨到 12.6召回半句话这类 case 基本清零。代价也要说清楚切分逻辑从原来的 5 行变成了 80 多行而且这套规则绑定文档格式后来接了一批格式混乱的老合同扫描件规则基本重写。结构化切分是拿工程量换质量文档格式越统一越划算格式散的场景要自己掂量。固定 512 一刀切把免责条款劈成两半第三层元数据被扔掉的免费信息前两层处理文本本身第三层查一个更隐蔽的问题入库时只留了正文把结构化信息全扔了。一份保险文档不只有正文它天然带着险种、产品线、文档类型、生效状态这些字段。这些信息不参与向量化没关系但检索时不用它们就是浪费。用户明确在问重疾险检索却在全库 5000 份文档里做相似度匹配意外险、医疗险的内容全都有资格来竞争 top20 的位置。我们的做法是入库时把这些字段存成元数据检索时先做一道过滤再算向量相似度。Milvus 2.4 里有两条路标量字段过滤灵活随便组合条件但过滤发生在向量检索过程中条件复杂时有性能开销partition 物理隔离检索时只扫对应分区快但 partition 数量有上限字段组合一多就不够分。我们按险种建了 partition就六个很稳定产品线和生效状态这些多变的字段走标量过滤两层配合。范围先从 5000 份缩到几百份再做向量召回top20 平均相关数从 12.6 到了 14 条往上。这层的成本几乎可以忽略因为字段本来就在源系统里躺着入库时顺手带上就行。它被跳过的原因通常不是难是入库脚本是照着纯文本向量化的教程抄的教程里没有就没人想起来加。元数据还有一个绕不开的用途权限。A 部门的员工不该搜到 B 部门的机密条款这件事靠向量相似度是拦不住的必须在检索层用元数据做硬过滤。之前那篇写 RAG 权限的文章评论区吵了 80 多条银行的读者说得很直接敏感库从物理上就要隔离。方向是一致的权限过滤要发生在召回之前而不是召回之后再筛。元数据两道门先缩范围再算相似度第四层查询改写用户不会按你的文档说话前三层都在收拾文档这一头第四层掉头看用户那一头。文档写的是等待期内确诊重大疾病的给付规则用户问的是刚买没多久就查出大病能赔吗。两句话说的是同一件事字面上几乎不重合。拿用户原话直接做向量检索就是在赌模型能跨过这道口语鸿沟。再给一个我们真实踩过的 badcase。用户问重疾险等待期出险怎么赔召回回来的 top5 全是意外险条款。扒下来发现两个原因叠加出险这个词在意外险文档里的出现密度远高于重疾险文档向量表示也被这种共现结构带偏意外险的块在相似度上集体压过了重疾险。系统最后拿意外险的等待期规则回答了重疾险的问题用户看不出来这比不回答更危险。解法是在查询侧做改写用一次 LLM 调用把口语问题规整成贴近文档表述的检索词。提示词里给了十来个口语说法到条款用语的对照示例让模型照着改比如把查出大病规整成确诊重大疾病把不赔规整成免责情形。对复合问题再多做一步拆成子问题分别检索结果用 RRF 融合排序后取并集。我们在 200 条测试问句里挑出 60 条明显口语化的单独测改写后这个子集的命中率从 31% 提到 58%。代价照例要写每次查询多一跳 LLM 调用P95 延迟涨了 300ms 左右还多一份调用成本。对内部知识库这种延迟不敏感的场景无所谓对话式产品就要掂量是全量改写还是只对识别出的口语查询改写。出险badcase口语一词把检索带进意外险第五层重排序最后一道精修不是万能药网上很多文章把 rerank 当成召回不准的万能解一不准就让你加。我的态度相反它是这条链路里最后才该上的东西而且不少场景根本不值得上。它的机制决定了它的位置rerank 用的是交叉编码模型查询和候选文本拼在一起过一遍模型算相关分比向量检索那种各自编码再算距离的方式看得细能捕捉到词序和否定这类双塔模型糊掉的信号所以准。但它只作用在粗召回出来的那批候选上。也就是说它只能在相关内容已经被召回进候选的前提下起作用。前面几层没做好相关内容压根不在这 20 条里rerank 排得再准也是在垃圾里排序。我们最后用 bge-reranker-v2-m3 对 top20 做精排取 top5答案引用的准确性确实又抬了一截。但延迟也很诚实单次查询 P95 从 210ms 涨到 380ms 左右候选数翻倍延迟还会继续涨。一条明确的边界文档量小于 1000或者用户查询本来就规范比如内部系统按模板提问rerank 大概率是白加复杂度和延迟前面四层做扎实就够了。把复杂度花在用不上的地方是另一种形式的浪费。Rerank 的账它很准但排在最后怎么把排查顺序讲清楚如果要在一分多钟里把这套东西讲给别人听我会这么讲。先立顺序20 秒RAG 召回不准按成本从低到高排查数据清洗、切分、元数据、查询改写最后才是 rerank 和换模型。理由一句话便宜的环节漏水漏得最凶贵的动作收益反而最小。再给证据40 秒挑两个数字讲。一是换模型的教训bge-large 换 bge-m3一周时间命中数从 4.8 到 5.1几乎没动二是清洗加切分的收益同样的测试集从 4.8 到 12.6一个模型没换。再补那个出险badcase说明有些问题出在用户查询侧模型再强也救不了。最后收边界20 秒rerank 只在候选里排序救不了没被召回的内容小文档量、规范查询的场景不用上。一句话收尾模型是这条链上最后才动的零件。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】