尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
RAG技术演进中段战事:从能检索到检索准的工程调优实战
1. RAG 技术演进的中场战事从“能用”到“好用”的分水岭如果你在过去一年里搭过任何一个基于大模型的问答系统大概率绕不开 RAG 这个词。检索增强生成Retrieval-Augmented Generation说白了就是给大模型外挂一个“资料库”让它回答之前先去翻资料而不是全靠脑子里那点预训练时记住的东西。这个思路最早在 2020 年前后被系统性地提出来但真正让它从论文走进工程实践的是 2023 年之后大模型应用爆发的那一波浪潮。我大概是从前年开始密集接触 RAG 相关项目的从最早的“向量库加个 prompt 模板”的玩具级 demo到后来要处理几十万份文档、上百个字段过滤条件、还要保证响应延迟在几百毫秒以内的生产系统中间踩的坑可以说能写一本小册子。这个系列我打算分上中下三篇来聊上篇讲的是 RAG 的基本盘和早期形态也就是“能跑通”的阶段这一篇“中”我想重点聊聊 RAG 技术演进过程中那个最关键的分水岭——从“能检索到”到“检索得准、生成得好”的过渡阶段。为什么说这个“中段”特别重要因为大部分团队做 RAG第一版 demo 往往一两天就能跑起来但真正上线之后发现效果不行回答要么答非所问要么漏掉关键信息要么把不相关的段落也塞进上下文里导致模型被干扰。这个时候你要做的不是推翻重来而是要在检索和生成这两个环节之间做大量的精细化调优。这一篇就是讲这些调优的思路、方法和实操细节。这篇文章适合谁看如果你已经搭过一个最基础的 RAG 流程知道什么是向量数据库、什么是 embedding、什么是 chunk但效果总是不尽如人意那这篇就是写给你的。如果你还没接触过 RAG建议先去看上篇补一下基础概念不然中篇里很多取舍逻辑你可能会觉得跳跃。2. 检索环节的精细化从“一刀切”到“分层策略”2.1 为什么朴素的向量检索不够用最基础的 RAG 检索就是把文档切成固定长度的 chunk全部做 embedding 存进向量库用户提问时把问题也做 embedding然后算余弦相似度取 top-k 个 chunk 塞给大模型。这个流程跑通没问题但实际效果往往很粗糙。我拿一个实际场景举例。假设你有一个内部技术文档库用户问“XX 接口的超时时间怎么配置”。朴素向量检索可能会返回三段内容一段讲接口鉴权、一段讲超时配置、一段讲错误码。为什么因为这三段里都出现了“接口”这个词embedding 模型在语义空间里把它们拉得比较近。但真正有用的只有第二段第一段和第三段塞进去反而会干扰模型生成。这个问题的根源在于固定长度的 chunk 切分方式天然会破坏文档的语义完整性。一个完整的配置说明可能横跨两个 chunk而一个不相关的段落可能因为恰好包含关键词而被召回。更麻烦的是向量相似度是一个“全局”指标它衡量的是两段文本在语义空间里的整体接近程度但用户的问题往往只关心文档中的某一个具体方面。所以从“中段”开始RAG 的检索环节要做的事情就不再是“找一个向量库、调一个 top-k”那么简单了而是要引入分层检索策略。2.2 分层检索的核心思路与实操拆解所谓分层检索我的理解是不要指望一次向量检索就能搞定所有事情而是把检索拆成多个阶段每个阶段用不同的策略和粒度。第一层粗召回。这一层的目标只有一个——别漏。用向量检索也好用关键词检索也好甚至用全文索引也好先把可能相关的候选集扩大到几十甚至上百条。这一层不追求精度追求的是召回率。我通常会把 top-k 设到 50 甚至 100后面再慢慢筛。第二层精排。拿到粗召回的候选集之后用一个更精细的模型来打分。这里最常用的就是 Cross-Encoder 类的重排序模型。它和向量检索的区别在于向量检索是分别把 query 和 document 编码成向量再算距离而 Cross-Encoder 是把 query 和 document 拼在一起送进模型直接输出一个相关性分数。后者的精度明显更高但计算量也大得多所以只能用在候选集比较小的阶段。第三层过滤与去重。精排之后还要根据业务规则做过滤。比如时间范围过滤、权限过滤、来源可信度过滤。同时要做去重因为相邻 chunk 之间往往有大量重叠内容如果不去重模型会看到大量重复信息既浪费上下文窗口又可能让模型过度关注某个局部。这三层下来最终送给模型的 chunk 可能只有三到五条但每一条都是精挑细选的。我实测下来同样的向量库和同样的生成模型加上分层检索之后回答准确率能从大概六成提升到八成以上。这个提升幅度在 RAG 项目里已经非常可观了。2.3 Chunk 策略的进阶玩法聊完检索分层必须回头说一下 chunk 策略因为这是整个检索环节的地基。固定长度切分是最简单的但也是最粗糙的。进阶的做法有这么几种按语义切分。不是按字符数切而是按段落、按标题层级、按句子边界来切。比如 Markdown 文档可以按标题层级切每个二级标题下的内容作为一个 chunk。这样切出来的 chunk 语义完整性更好但长度不均匀有的可能只有几十个字有的可能上千字。重叠切分。在相邻 chunk 之间保留一定的重叠区域通常是 chunk 长度的 10% 到 20%。这样做的好处是避免一个完整的语义单元被切断。比如一个配置说明横跨两个 chunk重叠之后至少有一个 chunk 包含完整说明。父子文档策略。这个稍微复杂一点把文档切成小块用于检索但检索到之后返回给模型的不是这个小块本身而是它所属的更大的父文档段落。这样做的好处是检索粒度细、定位准但生成时上下文足够完整。我试过在一个技术文档项目里用这个策略效果比单纯的重叠切分还要好一截。混合切分。实际项目里我很少只用一种切分方式通常是组合使用。比如先用标题层级做一级切分再在每段内部按句子边界做二级切分同时保留一定的重叠。这样既保证了语义完整性又控制了单块的长度。注意chunk 长度没有万能值。我见过有人直接抄别人的 512 token 配置结果在自己的文档上效果很差。正确的做法是拿一批真实用户问题做测试对比不同 chunk 长度下的召回效果选一个最适合自己文档特点的值。一般来说技术文档适合短一些的 chunk叙事类文档适合长一些的。3. 生成环节的调优让模型“说人话”且“说实话”3.1 上下文组装的学问检索做完之后下一步就是把检索到的内容组装成 prompt 送给大模型。这一步看起来简单其实有很多细节会影响最终效果。首先是顺序。检索到的多个 chunk 应该按什么顺序排列按相关性分数从高到低还是按文档原始顺序我的经验是如果 chunk 之间有逻辑上的先后关系比如一个流程的步骤一和步骤二那就按原始顺序排如果彼此独立那就按相关性分数排。但有一个例外最相关的 chunk 不要放在最前面也不要放在最后面而是放在中间偏前的位置。因为大模型对上下文的首尾部分注意力更集中中间部分容易被忽略。把最重要的信息放在中间偏前可以平衡注意力和逻辑连贯性。其次是分隔符。不同 chunk 之间要用清晰的分隔符隔开比如用三个短横线或者用 XML 标签包裹。这样做是为了让模型明确知道每个 chunk 的边界在哪里避免它把不同 chunk 的内容混在一起理解。我习惯用类似doc id1.../doc这样的标签实测下来模型对边界的识别更准确。最后是元信息注入。每个 chunk 除了正文内容还可以带上一些元信息比如来源文档标题、更新时间、可信度评分。这些信息可以帮助模型判断内容的时效性和权威性。比如用户问一个最新的配置参数模型看到某个 chunk 的更新时间是两年前另一个是上个月它就应该优先采信后者。3.2 Prompt 模板的设计原则Prompt 模板是 RAG 生成环节的核心。一个好的模板应该做到三件事约束模型只基于给定上下文回答、引导模型引用来源、处理上下文不足的情况。我见过很多失败的 RAG 案例问题都出在 prompt 太随意。比如只写一句“根据以下内容回答问题”模型很可能把上下文和自己的预训练知识混在一起甚至编造出上下文中根本没有的信息。正确的做法是在 prompt 里明确写清楚如果上下文中没有相关信息就回答“根据现有资料无法回答”不要自己发挥。引用来源也很重要。让模型在回答时标注信息来自哪个 chunk一方面方便用户核实另一方面也能倒逼模型更认真地阅读上下文。我通常会在 prompt 里要求模型用[1][2]这样的角标来标注引用然后在展示层把角标渲染成可点击的来源链接。还有一个容易被忽略的点上下文长度控制。不是塞给模型的 chunk 越多越好。我做过对比测试同样的问题塞 10 个 chunk 和塞 3 个 chunk后者的回答准确率反而更高。原因是过多的上下文会稀释关键信息模型在长上下文中容易“迷失”。所以检索阶段宁缺毋滥精排之后只保留最相关的几条就够了。3.3 生成参数的实际影响大模型的生成参数对 RAG 效果也有直接影响。最关键的几个是temperature。这个参数控制输出的随机性。RAG 场景下我通常会把 temperature 设得很低0.1 到 0.3 之间。因为 RAG 要的是准确、忠实的回答不是创意写作。temperature 太高模型容易自由发挥偏离上下文。top_p。和 temperature 类似控制采样范围。RAG 场景下也建议设低一些0.8 到 0.9 之间比较稳妥。max_tokens。控制输出长度。这个要根据业务场景来定。如果是客服问答回答要简短设 200 到 300 就够了如果是技术文档解读可能需要 800 到 1000。frequency_penalty 和 presence_penalty。这两个参数用来抑制重复输出。RAG 场景下有时候模型会反复引用同一段上下文适当调高这两个参数可以缓解。这些参数没有绝对的最优值需要根据你的具体场景做 A/B 测试。我的建议是先把 temperature 和 top_p 固定在一个保守值上然后重点调 max_tokens 和两个 penalty 参数。4. 评估体系的搭建没有度量就没有优化4.1 为什么 RAG 评估这么难RAG 系统的评估比传统检索系统难得多。传统检索系统只看召回率和准确率但 RAG 的最终输出是一段自然语言回答它的好坏很难用一个简单的数值来衡量。一段回答可能事实正确但表述啰嗦可能表述简洁但漏掉了关键细节可能引用了正确来源但推理过程有误。更麻烦的是RAG 的错误可能发生在检索环节也可能发生在生成环节还可能两个环节都有问题。如果不把这两个环节分开评估你根本不知道问题出在哪里。所以从“中段”开始RAG 项目必须建立一套分层的评估体系。4.2 检索环节的评估指标检索环节的评估相对客观核心指标有这么几个指标含义目标值参考RecallK前 K 个结果中包含正确答案的比例粗召回阶段 0.9PrecisionK前 K 个结果中相关结果的比例精排后 0.7MRR第一个相关结果排名的倒数均值越接近 1 越好NDCG考虑排序位置的相关性加权指标越接近 1 越好搭建评估集的方法从真实用户问题中采样一批然后人工标注每个问题对应的正确 chunk。这个标注工作很枯燥但非常值得做。我通常建议至少标注 100 到 200 个问题才能得到比较稳定的评估结果。有了评估集之后每次调整 chunk 策略、换 embedding 模型、改检索参数都可以跑一遍评估看指标是升是降。这样你的优化就不是凭感觉而是有数据支撑的。4.3 生成环节的评估方法生成环节的评估更复杂目前业界常用的方法有这么几种人工评估。最可靠但最贵。让标注人员对回答的准确性、完整性、流畅性打分。我通常用 1 到 5 分的量表每个维度单独打分。模型评估。用一个更强的模型来给回答打分。比如让 GPT-4 来判断回答是否忠实于上下文、是否回答了用户问题。这种方法成本低、速度快但和人工评估的一致性需要校准。自动化指标。比如 ROUGE、BLEU 这些传统指标在 RAG 场景下参考价值有限因为 RAG 的回答往往不是对原文的复述而是综合多段内容后的重新组织。不过有一些专门为 RAG 设计的指标比如 faithfulness忠实度和 answer relevance回答相关性可以用模型来计算。我的实际做法是日常迭代用模型评估快速筛选重要版本发布前用人工评估做最终确认。两者结合既保证了效率又保证了质量。4.4 评估驱动的迭代闭环评估体系建好之后最重要的是把它嵌入到日常迭代流程里。我习惯的做法是每次改动之前先跑一遍基线评估记录当前指标。改动之后再跑一遍评估对比指标变化。如果指标提升保留改动如果下降回滚或者调整。定期比如每周做一次全量评估检查是否有指标退化。这个闭环看起来简单但坚持做下来RAG 系统的效果会稳步提升。我见过太多团队做 RAG 是“改一改、试一试、感觉差不多就行”没有量化反馈优化就变成了玄学。5. 常见问题与排查技巧实录5.1 检索到了正确内容但模型没用好这是最常见的问题之一。检索环节明明返回了包含正确答案的 chunk但模型生成时要么忽略了它要么把它和其他不相关内容混在一起。排查思路检查 prompt 模板是否明确要求模型基于上下文回答。检查 chunk 的排列顺序最重要的内容是否被放在了中间偏前的位置。检查是否有太多不相关的 chunk 干扰了模型注意力尝试减少 top-k。检查 temperature 是否过高导致模型自由发挥。我遇到过一次典型情况检索返回了 8 个 chunk其中只有第 3 个是真正相关的但模型在生成时把第 1 个和第 5 个 chunk 的内容也揉进去了导致回答里出现了错误信息。后来把 top-k 降到 3并且加了重排序问题就解决了。5.2 回答过于笼统或过于细节有时候模型生成的回答太泛没有落到具体细节有时候又太琐碎把上下文中所有细节都罗列出来。这两种情况都和 prompt 设计有关。回答太泛通常是因为 prompt 里没有明确要求“具体”。可以在 prompt 里加一句“请给出具体的配置参数或操作步骤不要只给概括性描述”。回答太琐碎通常是因为上下文里塞了太多细节模型不知道哪些是重点。可以在 prompt 里要求“只回答用户问题直接相关的内容不要罗列无关细节”。5.3 多轮对话中的上下文管理RAG 系统如果支持多轮对话上下文管理会变得更复杂。用户第二轮提问时往往省略了第一轮的一些信息比如第一轮问“XX 接口怎么配置”第二轮问“那超时时间呢”。如果直接把第二轮问题拿去做检索很可能检索不到正确内容因为“那超时时间呢”这个 query 太短、信息量太少。解决办法是查询改写把多轮对话的历史和当前问题一起送给模型让模型生成一个完整的、独立的查询语句再用这个查询去检索。比如上面那个例子改写后的查询可能是“XX 接口的超时时间怎么配置”。这样检索准确率会大幅提升。5.4 常见问题速查表问题现象可能原因排查方向回答答非所问检索结果不相关检查 chunk 策略、embedding 模型、top-k回答遗漏关键信息相关 chunk 未被召回提高召回数量、增加关键词检索兜底回答包含错误信息模型自由发挥降低 temperature、强化 prompt 约束回答过于笼统prompt 缺少具体性要求修改 prompt 模板多轮对话效果差查询信息不完整引入查询改写响应延迟高检索或生成环节耗时分别计时定位瓶颈实操心得排查 RAG 问题时一定要把检索结果和生成结果分开看。我习惯在调试模式下把检索到的 chunk 和最终回答并排展示这样一眼就能看出是检索的问题还是生成的问题。很多团队把这两步混在一起调效率很低。6. 工具选型与架构取舍的一些经验6.1 向量数据库怎么选向量数据库的选择主要看几个维度数据规模、查询延迟要求、过滤条件复杂度、运维成本。小规模场景几万到几十万条向量用 FAISS 或者 SQLite 加向量扩展就够了部署简单不需要额外运维。中等规模百万到千万级可以考虑 Milvus、Qdrant 这类专门的向量数据库支持分布式和复杂的过滤条件。大规模亿级以上基本就要上分布式方案了同时要考虑索引类型和分片策略。我个人的经验是不要一上来就追求“大而全”的方案。很多项目的数据量其实并不大用轻量级方案反而更稳定、更好维护。等到数据量真的上来了再迁移也不迟。6.2 Embedding 模型的选择Embedding 模型直接决定了检索质量。选择时主要看语言支持、领域适配、维度大小、推理速度。通用场景下一些开源的 multilingual 模型表现已经不错。但如果你的文档是特定领域的比如法律、医疗、技术文档通用模型可能不够。这时候可以考虑用领域数据做微调或者选用在相关领域预训练过的模型。维度大小也是一个取舍点。高维度比如 1024 或 1536通常效果更好但存储和计算成本也更高。低维度比如 256 或 384成本低但可能损失一些精度。我的建议是先用高维度跑通如果成本压力大再考虑降维。6.3 重排序模型的部署重排序模型是提升精度的关键但它的推理成本比向量检索高得多。部署时要注意重排序模型通常只处理几十到几百个候选不要把它用在粗召回阶段。可以用 GPU 加速也可以用 ONNX 或 TensorRT 做推理优化。如果延迟要求很严格可以考虑用蒸馏后的小模型牺牲一点精度换速度。我试过在一个延迟要求 500 毫秒以内的项目里把重排序模型从 BERT-base 换成蒸馏后的小模型精度只掉了不到两个百分点但延迟降了一半以上。这个取舍是值得的。7. 中段之后下一步往哪走写到这里RAG 技术演进中段的核心内容基本覆盖了。从检索分层到生成调优从评估体系到问题排查这些都是在“能跑通”之后必须面对的工程问题。我自己的体会是RAG 项目里最花时间的从来不是搭第一版 demo而是后面这些精细化的调优工作。一个 RAG 系统从六十分做到八十分可能只需要两周但从八十分做到九十分可能需要两个月。这个系列的下篇我打算聊一聊 RAG 的进阶形态比如多模态 RAG、Agentic RAG、以及和微调的结合。那些内容更偏前沿探索适合已经在中段把基础打扎实的团队去尝试。最后分享一个小技巧如果你现在正在做 RAG 调优不妨先停下来花半天时间搭一个最小化的评估集。不用多五十个问题就够。有了这个评估集你后面所有的优化都会变得有方向。我踩过的最大的坑就是在没有评估集的情况下盲目调参改了半天不知道是变好了还是变坏了。这个教训希望你不要重复。
RELATED

相关推荐

AIStore免费AI公开课-智能体篇(七):DeepSeek Harness上架AIStore,DeepSeek官方智能体,开箱即用

AIStore免费AI公开课-智能体篇(七):DeepSeek Harness上架AIStore,DeepSeek官方智能体,开箱即用

AI Store当前最火的AI产品是【口袋专家AI】——AI版微信,让AI微信中的智能体专家帮你做PPT、做短剧、做图片,完成工作和生活中的所有事。 目录 一、引言 二、认识网页工作台 三、实战:创建并运行预算脚本 3.1 发出有边界的请求 3.2 等待…

📅 2026/10/13 12:54:16
Ghidra 11.0.2 逆向工程实战:反编译精修与脚本自动化提效

Ghidra 11.0.2 逆向工程实战:反编译精修与脚本自动化提效

简介:Ghidra 11.0.2 是一款面向软件逆向工程与安全分析领域的开源框架,适用于在 Linux 等平台上对编译后代码进行反汇编、反编译与脚本化分析的安全研究人员、CTF 选手及二进制分析学习者。资源包共收录约 2000 个文件,整体约 393.79MB&#…

📅 2026/10/13 12:54:16
137B编码模型PC端落地:推理优化与Agent权限防线设计

137B编码模型PC端落地:推理优化与Agent权限防线设计

把137B这个量级的编码模型搬到PC上跑,放在两年前几乎是想都不敢想的事。当时大家还在为7B、13B模型怎么塞进消费级显卡发愁,现在画风突变,头部厂商直接把百亿参数级别的编码大模型下放到个人电脑,还兼顾Agent形态的工具调用能力。…

📅 2026/10/13 12:54:16
MORE NEWS

更多资讯

📰

C语言网页爬虫实战:从socket到Windows独立exe

简介:面向C语言学习者的网页爬虫项目包,内含网络请求库实现的爬虫源码、可直接运行的视窗系统可执行程序、命令行传输工具、根证书文件以及自动构建脚本,压缩包约1.08MB,共5个文件。项目完整演示了如何用C语言完成网址解析、请求发…

📰

Python示例拆解:从推导式到装饰器,把代码变成真能力

很多人学Python,最后都卡在同一个地方:语法都认识,代码不会写。市面上的教程从变量讲到函数、从列表讲到字典,每章都看懂了,合上书打开编辑器,面对一个空白的.py文件还是不知道第一行该敲什么。我早年带新人…

📰

多任务学习实战指南:任务设计、参数架构与损失平衡

1. 多任务学习不是“一鱼两吃”,而是让模型学会举一反三多任务学习(Multi-Task Learning,MTL)这个词最近在技术社区里频繁出现,但很多人一听到就下意识觉得:“哦,就是让一个模型同时干几件事呗&…

📰

ponytail浏览器脚本插件实战:从脚本注入到数据抓取与页面改造

1. 从“ponytail”这个词说起:它到底是什么第一次看到“ponytail”这个词,大多数人脑子里浮现的是发型——马尾辫。但在插件圈子里,ponytail 指的是一款浏览器端的轻量级脚本管理与页面增强工具。它的定位很明确:不追求大而全&…

📰

汉诺塔递归实现:从原理到Python代码与复杂度分析

1. 递归思想解读:汉诺塔为什么天生适合递归很多人第一次接触汉诺塔问题,第一反应往往是“我能不能模拟每一根柱子上的盘子状态,然后用循环硬写?”坦白讲,如果你真的尝试过用循环去实现汉诺塔的移动过程,十有…

📰

TensorRT工业部署实战:从Mnist示例解剖INT8校准与跨平台断点

1. 为什么一个Mnist示例值得单独写十八篇?——从“能跑通”到“真落地”的断层真相很多人看到“TensorRT Mnist示例”这几个字,第一反应是:这不就是教科书级的Hello World吗?模型小、数据简单、GPU显存占用不到200MB,连…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬