AI Agent知识管道RAG:原理、实现与工程踩坑 大家都知道一个只会闲聊的 AI Agent 是没有太大价值的。要想让 Agent 真正帮我们干活它必须能获取到准确、及时、可验证的外部知识。这一篇我要聊的就是 AI Agent 的知识获取管道也就是RAGRetrieval-Augmented Generation检索增强生成。这是我对 Agent 系列整理的第四篇前几篇讲了 Agent 的基本架构、规划能力、工具调用这一篇集中解决一个核心问题Agent 的知识从哪里来尤其是面对私有文档、海量文本、实时更新的数据时怎么让模型知道它原本不知道的事情。我会从原理、实现链路、踩坑经验三个层面展开适合已经跑通 Agent Hello World、准备把 Agent 接入真实业务数据的读者。我自己在搭建 Agent 的过程中最先遇到的就是知识割裂问题模型本身很强但一问到我们团队内部的接口文档、项目规范、历史决策记录它就完全哑火。后来我意识到不是模型不行是根本没给它接上知识管道。这篇就当作我的一次完整复盘RAG 基础该补的细节我会一次性写透。1. 知识割裂是 Agent 落地的第一道坎先弄清楚 RAG 在解决什么问题我们先从根上想一个事一个基于大语言模型的 Agent它天生知道的只有训练数据里的知识。训练数据再多也覆盖不了你们公司的私有文档覆盖不了昨天刚发生的线上故障记录覆盖不了某个特定业务系统里的实时字典。参数量再大的模型也会在这三类问题上表现得像个刚入职的新人。这就是 Agent 落地时一定会撞上的墙——模型的知识边界不等于业务需要的知识边界。1.1 三种知识缺口的典型形态我归纳了一下实际业务里 Agent 面临的知识缺口大致有三种形态私有知识封闭公司内部的项目方案、接口文档、客户反馈、规章制度。这些内容从来不会出现在大模型的预训练语料里Agent 想答也答不出来。时间维度滞后模型训练数据是有截止日期的。哪怕是最新的模型对一周前发布的政策、三天前更新的产品价格、昨天刚出的竞品动态都一无所知。上下文窗口受限即便文档可以被塞进上下文但 Agent 单次对话的上下文窗口是有限的。一个几百页的 PDF不可能全量进入模型视野强行塞进去成本先爆掉后续响应速度也会拖垮整个交互体验。这三种形态统一指向一个答案Agent 需要一套机制在每次被提问的时候动态地把与当前问题最相关的外部知识抽取出来注入到生成过程中。这就是 RAG 的核心价值。1.2 RAG 在 Agent 架构中的真实位置很多人以为 RAG 只是一个检索文档再加到 prompt 里的小技巧实际远不止。在 AI Agent 的完整架构里RAG 属于知识层和 Agent 的记忆层、工具层并列专门负责供给稳定的外部事实。我画过一张非常朴素的逻辑图来理解这几层的关系但这里我们不用图表用一段描述就能说清楚Agent 接收用户问题后先经过意图识别和任务规划如果规划结果判断需要外部知识就会走 RAG 管道——先对问题做查询改写再去检索知识库拿到候选文档片段最后把片段和原始问题一起交给大模型生成答案。整个过程对用户是透明的用户感知到的只是这个 Agent 好像什么都知道。这套机制是 Agent 通往真实业务场景的必要基础设施没有它Agent 就是个花架子。1.3 为什么不能直接微调模型解决有读者会问既然模型不知道私有知识为什么不直接微调一个新模型我的看法是微调和 RAG 解决的不是一个问题。微调适合改变模型的行为风格和固定的技能模式比如让模型学会特定的输出格式、特定的语气、特定的工具调用习惯。但微调不适合承载高频更新的事实性知识原因很简单微调一次成本高、周期长昨天改的文档今天微调模型明天才能上线时效性完全跟不上微调后的模型对具体事实的掌握仍然不可控它可能记住某一段文档内容也可能记住出一个幻觉版本多个业务的私有知识全部压进一个模型里隔离性、权限控制都变得很难做。RAG 恰好是反过来的思路知识不往模型参数里塞而是放在外部的文档库里使用时临时检索。文档更新检索结果就更新成本低、速度快、权限可以在检索层精细控制。理解了这个差异你就能明白为什么主流 Agent 架构里RAG 几乎是标配。2. 离线管道把纯文本变成可检索的向量索引核心就三步RAG 的完整链路可以分为离线建库和在线检索两段。离线这一段的目标很纯粹把一堆文档PDF、Markdown、Word、HTML、数据库里的文本字段转化为一种适合快速检索的结构化形式。其中最核心的数据结构就是向量索引。很多初学者一上来就被各种框架绕晕我建议先把手写的三步走通文档加载与清洗、文本切分、向量化与建索引。2.1 文档加载数据清洗比你想的重要文档加载这一步听起来没技术含量实际坑最多。我用一个真实案例解释有一次我把一个团队的运维手册导进来文本里大量含表格、代码块、加粗标记、折叠块直接用现成解析器扒出来的 Markdown上下文全是乱掉的表格分隔符和重复的锚点链接。把这些垃圾片段向量化之后检索出来的内容自然也是垃圾。因此文档加载阶段必须要做三件事解析格式PDF 用 PyMuPDF 或 pdfplumber 抽取文本Word 文档用 python-docxHTML 先转纯文本再清洗标签。不要迷信任何单一工具所有解析器都会在复杂版式上出错务必抽查样本。去噪去掉页眉页脚、重复导航、脚本残留标签、阅读原文之类的营销尾巴这些内容会污染向量空间。保留元数据原始文件路径、页码、章节标题、更新时间都要保留这些内容本身可以被向量化也可以作为检索后的展示信息后面做引用溯源全靠它。如果你想先跑通流程用现成的框架会快很多。LangChain 里的DirectoryLoader、LlamaIndex 里的SimpleDirectoryReader都能快速读取整个目录但请记住框架只解决格式读取不解决清洗问题。我个人的习惯是写一个十几行的清洗函数把无意义的空白行、重复字符串、异常编码全部过滤一遍这一步能明显提升后续检索命中率。2.2 文本切分chunk 大小直接决定检索精度文本切分可能是 RAG 里性价比最高的环节——它代码量最少但对最终效果的影响极大。切分的本质是决定检索的最小单位用户检索时我们召回的不是整篇文档而是其中一个片段这个片段的大小和边界直接影响后续生成的上下文质量。切分策略常见的有三种固定长度切分按字符数或 token 数硬切比如每 500 个 token 一段相邻段之间留 50 个 token 的重叠区间。这是最朴素的做法实现简单但会无脑切断语义完整的段落和列表在代码文档上尤其灾难。递归字符切分按优先级依次尝试按段落标记\n\n、换行符、句号、空格逐层切分尽量保住语义边界。LangChain 的RecursiveCharacterTextSplitter就是这个思路也是我日常用得最多的方式。语义切分利用 embedding 模型计算相邻句子的语义相似度在相似度明显下降的地方断开。这种方法切出来的 chunk 质量最高但计算成本也高。LlamaIndex 的SemanticSplitterNodeParser能实现前期探索可用生产环境要评估性能。关于 chunk 大小的经验值我实测下来面向一般技术文档的场景chunk 大小在 300~500 token 之间重叠区间 50~100 token效果比较稳。太小了检索结果太碎模型难以理解完整上下文太大了检索结果包含太多无关内容不仅浪费窗口还会稀释相关性。这里给出一段我常用的 LangChain 切分配置你可以直接抄from langchain.text_splitter import RecursiveCharacterTextSplitter splitter RecursiveCharacterTextSplitter( chunk_size400, chunk_overlap80, separators[\n\n, \n, 。, , , , , ], ) chunks splitter.split_text(clean_text)有一点必须强调切分参数是超参数不是正确答案。不同文档类型有不同最优值。代码类文档我倾向用更小的 chunk配合代码语义感知的切分器法律合同这类长段落文本反而适合更大的 chunk。一定要在自己的数据上做评测而不是抄别人的参数。2.3 向量化与索引Embedding 选型的门道文本切好之后下一步就是把每个 chunk 转换成一个向量。这里核心是选 embedding 模型。市面上的选择很多OpenAI 的text-embedding-3-small/text-embedding-3-large质量稳定但数据要出境开源的BAAI/bge-large-zh-v1.5、m3e-base在中文场景表现不错能本地部署还有一些新的国产商用接口不限并发。我在中文技术文档场景实测下来bge 系列中文表现不输甚至超过同尺寸的通用模型关键的是可以私有化部署数据不用出境。如果你做的是纯中文的私有知识库优先考虑本地部署的 embedding 模型既安全又能省后续接口费用。向量化完成后需要一个向量数据库做索引和检索。这一步选型的核心指标有三个检索质量、写入速度、生态成熟度。我整理了一个参考表格方案适合场景优点注意事项FAISS本地原型、单机 demo部署简单、检索性能高、无需额外服务不支持服务化数据量大了需额外做持久化方案Chroma单机小项目、快速验证轻量、API 友好分布式能力弱不适合大规模生产Milvus生产级大规模检索分布式、支持多种索引、生态完善部署运维成本稍高Qdrant生产级中等规模Rust 编写、性能好、过滤能力丰富需要独立部署pgvector已有 PostgreSQL 的团队直接在原库中做向量字段不用引入新基础设施检索量极大时性能不如专业向量库我自己早期直接用了 FAISS 本地跑通整个链路好处是完全不依赖外部服务适合学习和调试。后来要给团队做共享知识库改成了 Milvus支持并发查询和权限过滤稳定性和可维护性都上一个台阶。我的建议是学习阶段别纠结选型先拿 FAISS 把链路跑通再评估是否需要迁移到正式向量库。3. 查询阶段的检索设计召回率、相关性、排序的三角平衡离线管道建好之后RAG 的在线部分——给一个问题找回最相关的文档片段——正式登场。这一段的成败决定生成质量的上限。我一直认为RAG 的功夫主要花在检索端而不是生成端。检索出来的东西不对后面 prompt 写得再花哨也没用。3.1 最基本的检索流程向量相似度计算在线检索的第一步是用同一个 embedding 模型把用户的问题也转成一个向量。然后在向量数据库里找到与这个查询向量最相似的若干个文档向量按相似度排序返回 Top-K 条结果。这里涉及的相似度度量通常有三种余弦相似度衡量两个向量在方向上的重合程度对向量的模长不敏感是最常用的度量方式。点积相似度在向量已归一化的情况下点积和余弦相似度等价但点积对模长敏感更适合某些特殊 embedding 模型的打分。欧氏距离衡量多维空间里的绝对距离数值越小越相似很多向量库默认转换成相似度打分时会取负。实际操作里大部分向量数据库默认用余弦相似度一般情况下不用额外调整。但要注意相似度分数本身不能跨模型比较也不能绝对化理解为置信度。不同 embedding 模型产出的分数分布差异很大有的模型相似度 0.6 就算高有的模型 0.8 还很普通。你需要在自己的数据上做校准别被分数绝对值误导。3.2 多层检索策略从裸向量到混合召回只用向量检索的 RAG在复杂业务场景下会暴露两个问题精确词条匹配失效向量检索对语义相关但用词完全不同的文本表现好但对商品编号、订单号、型号 ID这类必须精确匹配的查询反而可能出错。向量空间里ABC-123和ABC-124的距离可能非常近但它们是两个完全不同的商品。关键词漏召回有些文档里出现某个专业缩写时embedding 有可能把包含该缩写但语义侧重点不同的文档排在前面导致真正关键的精确片段没被召回。解决方案是引入混合检索Hybrid Search同时使用稀疏检索关键词匹配如 BM25和稠密检索向量相似度将两者的结果做融合。BM25 擅长精确词匹配向量检索擅长语义泛化融合之后能覆盖的场景远多于单一检索。我用一个实际例子说明有个知识库里存了一批银行产品的介绍文档用户拿利率最低的三年期定存产品来问向量检索会把定存产品利率比较的段落排在前面但如果某个段落确实提到了三年期利率 2.6%却没出现定存也没出现最低BM25 可能完全召不回它。反而 BM25 能精准匹配三年期和利率这两个词。两者融合后模型既能看到精确匹配的文档又能看到语义相关的泛化文档生成质量自然更好。在实现融合时最常用的算法是RRFReciprocal Rank Fusion倒数排名融合对多种检索结果取排名按公式score Σ 1/(k rank)分配得分。k一般取 60。这种方法只依赖排名不依赖原始相似度分数规避了不同检索器分数尺度不一致的问题。还有个关键技巧融合前对多种检索结果做去重同一文档既被语义检索召回又被关键词检索召回时得分会叠加这正是我们想要的效果。3.3 召回之后的精排Rerank 的价值Top-K 召回只是粗筛真正决定最终生成质量的是粗筛之后的精排Rerank。向量检索的目标是召回可能相关的文档但向量相似度高不等于确实能回答当前问题。用一个独立的 rerank 模型把召回结果逐条和原始问题一起打分可以得到比向量相似度更精准的相关性排序。Rerank 模型和 embedding 模型的核心区别在于embedding 模型需要把 query 和 document 分别编码成向量再用向量距离衡量相似度这本质上是双塔结构query 和 document 没有交互限制了它的细粒度建模能力rerank 模型通常用交叉编码器结构把 query 和 document 拼接起来一起过模型可以更细腻地捕捉交互信息所以精度更高但代价是延迟更高、算力消耗更大。常见的开源 rerank 模型有bge-reranker-v2-m3、mmarco系列也有一些商业 API。架构上是把重排环节放在检索之后、生成之前向量 DB 先粗召回 50~100 条再用 rerank 模型精排到 5~10 条进入生成阶段。这一步对最终答案质量的提升非常明显可以说是我做 RAG 过程中投入产出比最高的单个环节。3.4 Top-K 参数不是越大越好Top-K 到底取多少这是每个 RAG 新手都会问的问题。我的答案是取决于你的生成模型、检索质量和任务类型。如果一个问题只需要一个明确事实支撑K 取 3~5 就够了如果问题是需要多角度综合分析K 可以放到 8~10。但 K 一定不能太大因为生成模型的上下文窗口有限塞太多片段会显著增加幻觉风险排在后面的片段本来就是矮子里拔高个相关性差的内容进入上下文会对输出产生负面干扰每次生成携带的 token 增多接口延迟和成本同步上升。我见过有些同学把 Top-K 设成 20、30 的检索库又不是特别干净结果模型被大量半相关文本带偏。请记住RAG 是宁缺毋滥的架构给模型的上下文宁可少而精不要多而杂。你要做的是不断测试 K 值找到检索结果开始明显下降的拐点。4. 生成阶段把检索结果组装成上下文这一步比想象中有讲究检索做完了拿到了 Top-K 个文档片段但拿到和用好之间还有一道坎。生成阶段的本质是把检索到的知识片段和用户的原始问题一起通过 prompt 组织成一个让模型易于理解和遵守的上下文。这个组装过程有一些反直觉的细节很多人直接拼接就完事效果差一半。4.1 上下文组织顺序与去重第一步是给检索结果排序和去重。很多初阶代码直接把检索结果按相似度顺序拼接这是一个典型的错误。原因在于大模型对上下文不同位置的注意力不完全相同通常对开头和结尾的注意力更强中间位置的容易遗忘——这是很多研究都证实过的现象业界形象地称为lost in the middle。因此把最重要的片段放在 prompt 的开头和结尾把次要内容放中间比单纯按相似度排序效果更好。具体实现时可以先按得分排序然后把得分最高的片段安排在最前方得分第二高的片段安排在末尾其余片段按得分递减填在中间。看起来反直觉实际测试下来效果有明显提升。另外同一个信息可能在多个片段中重复出现直接拼接会浪费 token。如果你在离线切分时做了重叠窗口那么重复内容几乎必然存在。生成前用文档指纹如 MinHash 或简单哈希做一次模糊去重能显著精简上下文这个细节在生产环境里很值得做。4.2 引用溯源让 Agent 说话有出处如果你做的是企业级 Agent生成阶段必须考虑告诉我它从哪来。这一方面是为了用户信任另一方面也是排查错误答案的必要手段。实现方式并不复杂给每个 chunk 在切分时分配一个全局唯一的文档 ID进入生成 prompt 时以特殊标记的形式把片段来源挂在每个 chunk 后面模型在生成答案时只要你在 prompt 里明确指示它引用部分必须注明来源编号它就能给出类似 [1][2] 的标记你在后处理阶段把编号替换成对应的文档路径和页码即可。我早期偷懒没做引用溯源结果一条回答里混了三个不同版本的项目资料用户指出矛盾后我根本没法定位问题出在哪一份文档。后来加上引用标记再配合全文搜索定位错误答案的成本从小时级降到了分钟级。所以我的建议是引用溯源不是锦上添花是 RAG 生产环境的第一步。4.3 兜底策略检索结果不可用的时候该怎么办RAG 一个经常被忽视的问题是如果检索结果本就与问题无关怎么办很多初阶实现会把检索结果无条件塞进 prompt即使检索到的片段跟问题是两回事模型仍然被迫基于无关内容生成答案幻觉率急剧上升。解决这个问题需要在 prompt 里加一个关键约束我常用的一种写法是指令以下是从知识库检索到的相关信息用 [1][2] 标记了编号。 要求 1. 优先依据这些信息回答问题 2. 如果这些信息与问题无关或不足以回答问题请直接回答知识库中没有相关信息不要尝试编造 3. 如果信息之间存在矛盾请指出矛盾并列出所有相关依据不要自行选择一个可能的正确答案。这一条约束的处理要点在于不要再让模型在信息不足时发挥而是让它明确选择承认不知道。很多 Agent 的体验崩坏不是因为检索不行而是因为模型在信息不足时选择了硬编。加上兜底约束后用户体验虽然偶尔会被不知道打断但至少不会被编造的错误信息误导。在知识管理场景里可靠的不知道比看似聪明的编造珍贵得多。5. Agent 形态下的 RAG 演进从单轮问答到多轮对话再到 Agentic RAG前面讲的 RAG本质上还是单轮检索、单轮生成的经典链路。但真正做 AI Agent 的同学很快会发现Agent 的实际交互是多轮对话的用户会追问、澄清、跳转主题Agent 也可能在规划过程中多次调用检索工具。如果每一轮都独立做一次 RAG完全抛弃上文语境效果会非常糟糕。5.1 多轮对话中的查询改写多轮对话中用户的第二句话通常是「这个方案的成本是多少」这种带省略的指代表达。如果不做任何处理直接把这句话拿去检索知识库检索到的自然是对不上号的文档。解法是引入查询改写Query Rewriting在进入检索前先让大模型结合对话历史把当前问题改写成一句完整、独立、可检索的问句。比如对话历史是「你们产品的部署架构是怎样的」用户追问「容器化支持吗」改写后的独立查询就应该是「你们的部署架构是否支持容器化部署」。用大模型做这一步最简单的方法是在检索前加一轮改写调用虽然增加了一次 LLM 调用延迟但换来的是检索质量的大幅提升。如果你的 Agent 框架里本来就有对话管理模块把查询改写挂在那里是最自然的做法。5.2 多轮追问中的上下文继承第二代多轮 RAG 会遇到的问题是第一轮检索到 A 文档第二轮的检索完全不基于第一轮的结果重新从整个知识库里搜。但很多用户追问的内容恰恰基于第一轮给出的答案。例如用户先问「性能指标有哪些」Agent 回答了一串指标用户接着问「第一个指标具体怎么计算」如果第二轮还做全局检索很可能找不到相关片段。更合理的做法是第二轮检索首先在第一轮已召回的文档范围内做局部检索同时铺开做全局语义检索补充候选。这种局部优先 全局兜底的策略在多轮场景下实测效果比单纯全局检索好很多。实现上你可以在 Agent 状态里维护一个当前对话已引用的文档集每次新检索的时候把该文档集作为过滤条件之一。向量数据库一般支持类似doc_ids IN [...]的预过滤配合共享的语义检索就能实现两路召回。5.3 Agentic RAG当检索变成工具调用再进一步RAG 不只是 Agent 的一项知识供给机制它本身也可以被封装成 Agent 可以按需调用的工具。这就是 Agentic RAG 的状态Agent 根据用户问题的性质自主决定是否需要调用检索工具、以什么方式调用、对检索结果做何种二次加工。举个例子用户问「对比一下我们上季度和本季度的故障率变化」固定管道式 RAG 只会拿你预设的检索方式去查而 Agentic RAG 的 Agent 会发现这个问题需要查两份不同时间段的数据于是它会先调用一次按时间过滤的检索再调用一次按指标名过滤的检索最后把两次结果汇总生成答案。这种自主规划检索步骤的能力正是从检索增强的聊天机器人走向真正的 Agent的关键一步。在工程实现上你可以在 Agent 的工具列表中加入search_knowledge_base工具参数包括查询语句、过滤条件、返回条数。Agent 的规划模块会根据意图决定调用时机。这一层变化说起来简单实际涉及 Agent 的可信度控制、检索结果校验、多工具协同状态管理等复杂问题我打算在系列后面的篇章详细展开。5.4 与记忆、图谱的结合RAG 的无限联结最后补充一个更进阶的方向RAG 不是唯一的知识获取手段它还可以和知识图谱GraphRAG 与本体的结合、长期记忆相互配合。知识图谱适合表达实体之间的多跳关系比如「A 部门的服务器是否支持 B 系统的部署」这类需要沿关系链推理的问题纯向量检索很难回答到位。长期记忆则解决同一个用户在多次会话中反复提到的事实例如用户的偏好这些信息没必要每次重新检索而是应该沉淀在 Agent 的记忆模块里。我的观点是RAG 是整个 Agent 知识管道的底座但它不是全部。真正成熟的系统应该是 RAG 处理非结构化文档图谱处理结构化关系记忆处理个性化信息三种方案组合使用。6. 检索质量评测没有指标的 RAG 优化都是自我感动很多团队做 RAG说效果不行就埋头调参却从没定义过什么是效果。我在这个项目上最大的教训是没有评测就没有优化方向。你可以凭直觉调整 chunk 大小、修改 prompt但这些调整到底是改良还是劣化没有量化指标你根本无法判断。6.1 核心评测指标召回命中率与排序质量最关键的指标是召回命中率Hit Rate给定 N 个标准问题每个问题有一个或多个标准答案文档系统返回 Top-K 结果中有没有包含标准文档。例如构造 50 个评测问题系统返回 Top-5 中能正确命中的比例达到 80%说明召回端基本合格。另一个常用指标是MRRMean Reciprocal Rank平均倒数排名衡量标准答案在排序中出现的位置越靠前越好。如果标准答案经常出现在第 2、3 位虽然 Top-5 命中率还行但生成端拿到的最佳上下文质量仍受影响。除此之外还有一个容易被忽视的答案正确性指标召回命中了就一定能生成正确回答吗不一定。评测时不能只看检索命中还要让大模型基于检索结果生成答案再人工或模型打分判断答案是否正确。这个过程称为端到端评测。我自己的习惯是先建立 30~100 个标准问题的评测集然后每次改动参数都跑一遍 Hit Rate 和端到端正确率再对比前后变化。没有这个过程你说好像变好了大概率是心理作用。6.2 典型问题定位Hit Rate 上不去时从哪些环节下手当你发现 Hit Rate 一直不理想时我建议按以下优先级排查数据清洗问题文档解析出的文本乱码、重复、缺失大量关键内容先修数据不要调模型。chunk 切分问题关键信息被拦腰切断、跨段语义丢失。尝试增大 chunk、增加重叠或者改用语义切分。查询问题原问题本身过短或指代不明。先做查询改写再检索这一步对 Hit Rate 的影响往往巨大。embedding 模型不匹配换一个更强或更适配领域的中文 embedding 模型对比 Hit Rate 差异。检索策略单一从向量检索切换到「向量检索 BM25 RRF 融合」。Rerank 缺失召回效果不错但 Top-5 顺序乱接入 rerank 后相关片段前置能显著改进生成质量。6.3 一组实测参数参考下面是我在一份约 200 页的中文技术手册上跑过的参数组合供直接参考注意这只是一个样例你的数据需要自己的评测来决定最终参数参数取值说明chunk_size400 token技术文档段落中位数约在 350~450 之间chunk_overlap80 token保证跨段上下文不完全断裂embedding 模型bge-large-zh-v1.5中文长尾实体表现稳定索引类型HNSWM16, efConstruction200单机百万级向量以内无压力召回方式向量检索 BM25 混合RRF k60兼顾语义与精确词匹配粗召回 Top-K50rerank 前的候选数量精排后 Top-K5进入生成阶段的最终文档数rerank 模型bge-reranker-v2-m3交叉编码器精度提升明显相似度阈值不设硬阈值依赖 rerank 排序硬阈值在不同模型上不可迁移这套参数跑出来的结果是100 个评测问题上 Hit RateTop-5超过 92%MRR 超过 0.85。作为对比只使用纯向量检索、不做融合、不做 rerank 时Hit Rate 大约在 78% 左右。差距完全来自检索链路的逐步叠加优化。注意我用的是Top-5 92%不是最终生成正确率 92%。生成阶段还要考虑 prompt 质量和兜底策略端到端正确率通常比检索命中率低 5~10 个百分点。如果你发现检索命中率很高但生成答案依然出错问题大概率出在 prompt 组装和后处理上别在检索端盲目调参。6.4 我的建议把评测集当成项目资产最后分享一个我自己的操作习惯我会为每个知识库维护一个独立的评测集包含问题、标准答案、答案出处文档、检索结果记录四列。每次修改 RAG 任何环节之前先跑一遍旧版本的评测结果作为基线改完之后再跑一遍新版本对比差异。这个方法虽然前期花时间但长期看它让我避免了无数次的我觉得改好了。RAG 做的越深我越发现这个系统的每一个环节——数据清洗、切分、向量化、检索融合、精排、prompt 组装——都像一个独立的水龙头任何一环漏水最终出来的水都不干净。先把评测习惯建起来后面的优化才算有方向。这一篇把 RAG 基础链路完整拆完了下一篇我打算基于这套管道往上叠一层 Agent 的规划与工具调用把检索增强升级成自主获取知识。