
每一个做 Agent 的人迟早都会撞上同一个问题模型的知识截止日期、训练语料的覆盖范围根本撑不起一个真正能落地的业务场景。想让 Agent 干活儿先得解决它的“吃饭问题”。这也是我把“知识获取管道”单独拿出来写一篇的原因——在 AI Agent 的整个架构里外部知识怎么进来、怎么存、怎么被检索、怎么在生成时才用得出来从头到尾是一条完整的管道而 RAG 就是这条管道的地基。这篇是“走进 AI Agent”系列的第四篇。如果你想从零开始搭一个自己的 Agent或者已经在用 LangChain、Spring AI 这类框架但总觉得回答还是“一本正经地胡说八道”那这篇文章应该能帮你把最基础、也最容易出问题的那一环理清楚。我会直接从管道设计的角度出发讲清楚 RAG 到底是什么、什么时候必须用、什么时候别硬用再把索引、检索、生成这一段段拆开附上我自己实测过的参数和踩过的坑。尽量做到看完之后你能直接上手去改自己的知识库而不是只记住几个名词。1. RAG 在 Agent 架构里的真正定位先说结论RAG 在 Agent 里不是一个“插件”而是“知识获取管道”的默认实现。很多初学者把 RAG 理解成“让模型翻文档”这个理解太窄了。Agent 是一个会规划、会调用工具、会自我纠错的系统它需要的不只是“答案”而是“依据”。RAG 提供的恰恰是这个“依据”的获取通道。1.1 为什么 Agent 不能靠“记忆力”过日子大语言模型的参数里确实装着海量知识但这里有两个硬伤。第一知识是静态的。模型训练完成那一刻它的知识就冻结了。你今天让它处理一份昨天才发布的技术文档它不可能知道你让它回答某一个产品线内部的规格参数它更不可能知道因为训练语料里根本没有这些私有内容。第二知识是概率性的。模型给出的回答本质上是“按概率预测下一个 token”它不是在做数据库查询。所以我见过很多团队把 Agent 当知识库问答用问它“上个月的订单总额是多少”它给你编一个数字出来看起来有模有样实际上完全是幻觉。这个问题不是靠换个大模型能解决的模型再大也改变不了“没学过就是没学过”这个事实。RAG 解决的就是这个“记忆儿不够用”的问题。它的做法非常朴素既然模型不知道那就先让它“查”到查完之后再带着答案去生成。1.2 把“知识获取”当成一条管道来设计我在实际项目里习惯把 Agent 的知识处理画成一条单行道从数据源出发一直通到最终输出输入文档或数据 → 清洗 → 切分 → 向量化 → 存储 → 检索 → 重排 → 上下文注入 → 模型生成。每一段之间是联动的。检索效果不好一半的原因在“切分向量化”这一段就埋下了上下文注入做得太粗暴检索做得再好也会被模型自己带偏。这就是为什么我强调“管道”而不是“功能”——你得把整条链路放在一起调而不是单独调某一个环节。当然这条管道在实际项目里会有很多变体。比如结构化的数据SQL 表、CSV更适合直接通过写代码查询而不是走向量检索图片类的知识要做视觉索引知识图谱类的信息需要走 GraphRAG。但不管怎么变RAG 的核心闭环是不变的先检索后生成。1.3 RAG 与 Agent 的三种协作模式我参与过的项目里RAG 和 Agent 的关系大致有三种你可以根据自己的场景来套。一种是“问答增强”模式也是最常见的。用户问一个问题系统先把它转成检索 query从知识库中找到相关片段拼进 prompt再让模型回答。这种模式适合文档问答、客服问答、产品说明书问答。它的特点是流程固定不需要 Agent 做太多规划LangChain 里一个 chain 就能搞定。第二种是“工具调用”模式。Agent 在规划阶段就意识到自己缺知识于是主动调用一个“知识库搜索”工具。这里的 Agent 是主RAG 是工具模型决定什么时候查、查几次、查完怎么用。这种模式灵活很多适合复杂任务比如“对比这几个方案的区别”Agent 可能需要查四五次知识库才能凑齐对比所需的材料。第三种是“记忆管理”模式也叫 Agentic RAG 的进阶玩法。Agent 把每次会话的关键结论、用户偏好、中间推理信息写回知识库下次任务开始时通过检索把相关的“过往记忆”重新拉出来。这个模式我后面会单独展开它其实是 RAG 和 Agent 结合最妙的一种应用场景。2. 认知纠偏RAG 不是“把文档喂给模型”这个误解在项目沟通里太常见了。产品经理、甚至部分刚入行的工程师以为 RAG 就是把一堆文档丢给模型然后模型就会“学会”这些文档。这是根本性的错误。模型不会因为你在 prompt 里塞了几篇文档就“学进去”。它只是“看过”了这些内容在生成回答时参考了这些内容。这就像你考试时带了一本参考书进考场——你不一定会用但你翻得到的部分确实能帮到你。RAG 把参考书变成了一个“可快速定位的索引”让模型知道该翻哪一页而不是把整本书重背一遍。这个区分决定了你在系统设计上的很多决策。比如是否需要微调不必。因为微调是把知识“写进”参数里成本高、更新难、还有可能让模型学歪。而 RAG 不改变模型权重知识以文本形式存放在外部数据库里随时可以增删改查这是它最大的工程优势。2.1 什么时候 RAG 帮不上忙说完了 RAG 能做什么也得说说它解决不了什么。如果知识是高密度的数值逻辑比如“毛利率 (收入 - 成本) / 收入”这个查询和计算逻辑是稳定、精确的那应该写代码而不是问 RAG。RAG 擅长的是“非结构化文本的语义召回”不擅长“结构化数据的精确运算”。如果知识是长期动态变化的比如股票价格、天气数据RAG 需要频繁同步同步不及时就会给旧数据。这类场景更适合用 API 实时拉取而不是先入库再检索。还有一种是“需要深度推理”的咨询类问题比如“结合我们公司的情况分析进入新市场的风险”。RAG 可以给你素材但最终的判断还得靠模型本身的推理能力。RAG 与模型之间不是替代关系而是分工关系。2.2 我的选型决策清单我做技术选型时会按下面这个清单来判断要不要引入 RAG知识是否属于“半结构化/非结构化文本”是 → RAG 合适。知识是否频繁更新是 → RAG 有优势但要考虑同步频率。是否需要引用溯源用户要看到回答的依据是 → RAG 天然支持可以在元数据里记录出处。查询条件是否需要精确匹配是 → 优先考虑数据库/代码逻辑而非 RAG。单条知识的体量是否超过模型上下文窗口是 → RAG 几乎必选。把这几个问题过一遍基本上就知道该不该上 RAG 了。不要为了技术热度去用 RAG合适的场景才能发挥它的价值。3. 知识管道的三段式拆解索引、检索、生成现在进入这篇文章最核心的部分。我把 RAG 的完整流程分成三段来拆解——索引Indexing、检索Retrieval、生成Generation。每一段都有它自己的关键参数、技术选型和避坑点。你会发现真正决定 RAG 效果的往往不是“最后让模型读了什么”而是前两段做得好不好。3.1 索引阶段从原始文档到可检索的向量库索引阶段的目标只有一个让原始文本变成“可以快速查的格式”。这个阶段通常包含清洗、切分、嵌入Embedding、入库四个步骤。清洗这一步常常被忽略但我见过太多翻车案例都是因为没做清洗。比如PDF 解析出来的文档里全是页眉页脚、特殊符号、乱码分行这些问题会把检索效果拉到惨不忍睹。你用 unstructured 或者 PyMuPDF 这类工具解析 PDF 后一定要做过一轮规则清洗去掉连续空行、合并断行、移除页眉页脚里的重复信息、处理表格内容。清洗规范不是一次性的我建议每个知识域都维护一份自己的清洗规则清单。切分Chunking是最关键、也最容易被低估的一步。很多人的默认做法是“按字符数切”比如每 500 个字切一段。但这是偷懒的做法。更好的做法是“按语义边界切”——段落、标题、列表项甚至在 Markdown 里按标题层级切。为什么因为检索的粒度决定了生成的效果。切得太小单段信息不完整模型拿到手看不懂切得太大单段信息冗余检索的精准度会下降还会占用模型上下文空间。我在中文场景下常用的参数是这样的参数建议取值说明chunk_size400800 字符中文场景比英文小一些因为信息密度高chunk_overlap50150 字符交叉部分能减少切分造成的信息断裂切分单位优先按 Markdown 标题、段落语义完整性优先于字符长度嵌入Embedding是把文本变成向量的过程。选模型这块我的建议很直接中文场景优先选择针对中文优化的模型比如 BGE、M3E 系列如果预算充裕也可以直接用 OpenAI 的 text-embedding-3-large。要注意的是不同嵌入模型的输出维度不同一旦选了最好不要中途换否则向量库要全部重算一遍。入库这一步就是把向量和原始文本、元数据一起写入向量数据库。元数据是很关键的设计点每条 chunk 最好记录原始文件路径、页码、标题、时间戳这些信息。后续要做过滤、溯源、权限控制全靠元数据。我在生产环境里用 MySQL pgvector 的组合或者直接用 Milvus看团队熟悉度来定。3.2 检索阶段召回、过滤与重排检索阶段的本质是“从向量库里找出最相关的 Top-K 条记录”。这个“最相关”的定义直接决定了效果。第一步是 query 转换。用户问的问题跟存储的文本往往是不同表达方式的。比如用户问“怎么降低退货率”知识库里可能写的是“退货原因分析与对策”。直接在原始 query 上做向量检索效果往往一般。我常用的做法是让大模型先对 user query 做“改写/扩展”——生成几个更匹配知识库的检索子问题再用这些子问题去向量库查询。LangChain 里的 Multi-Query Retriever 就是这个思路。第二步是向量检索本身。这里有一个很经典的纠结点用稀疏检索如 BM25还是稠密检索向量搜索我的经验是关键词精确匹配多的场景比如型号、编号、产品名用 BM25 效果很好语义相近但表达不同的场景用向量搜索更准。既然两者不是非此即彼我建议直接上 hybrid search——把 BM25 和向量检索的结果做加权合并或者用 RRFReciprocal Rank Fusion做融合。这个做法在大部分开源向量库里都已经内置支持了成本很低效果提升却非常明显。第三步是重排Rerank。召回 20 条之后直接用 cross-encoder 模型对“query chunk”拼接起来打一个精细的相关性分数再按这个分数取 Top 5 给模型用。Cross-encoder 的效果远好于单纯向量相似度但计算成本更高所以只用来对召回后的少量候选做重排是性价比很高的策略。这个策略用熟了之后你会发现它比换一个更大的嵌入模型还要管用。重排之后还有一个经常被忽略的环节过滤。如果知识库是分域管理的比如有产品 A 的知识域和产品 B 的知识域就应该在检索时提前通过元数据过滤掉无关领域。直接搜全库再重排容易让检索结果“串台”生成出来的答案就更不可控。3.3 生成阶段不只是一个“把结果塞进 prompt”的过程生成阶段往往被认为最简单——把检索到的文本拼进去让模型回答。但做久了你会发现这个环节才是 RAG 效果分水岭的出现地。第一个问题是上下文的“拥挤”。如果检索到的 5 个 chunk 总共 3000 字你的模型上下文窗口是 8000 字那提问指令、历史对话、角色设定还有很多空间。但如果知识库一次塞了十几篇文档动辄两三万字模型很容易“迷路”。所以高质量生成的前提是管好上下文窗口的分配。我通常会做一个“context 预算”的规划用户指令 20%、历史对话 30%、检索结果 40%、其他 10%按这个预算来决定到底放多少 chunk、每条 chunk 多长。第二个问题是“指令明确性”。模型需要知道哪些内容来自知识库、哪些内容需要它自己发挥。我会在 system prompt 里明确规定“请优先基于以下知识库内容回答。如果知识库内容不足以回答问题请明确说不知道不要编造。” 不要小看这句话它对幻觉的抑制效果非常明显。第三个问题也是我最在意的——引用溯源。生产环境的 Agent回答必须可解释。我在传给模型的 prompt 里会给每个知识库 chunk 加上一个 ID然后要求模型在回答中引用 [1]、[2] 这样的编号。后处理阶段再把 ID 还原成文件名、页码、URL展示给用户。这一步做得好用户对系统的信任度会完全不一样。4. 从“检索”走向“主动获取”Agentic RAG 的关键升级前面讲的 RAG 流程本质上还是“一问一答”的模式用户发起问题系统查一次然后生成。这在很多场景里够用了但如果你想让 Agent 处理更复杂的任务这种被动的 RAG 就不够用了。于是我必须提一下 Agentic RAG——这个热词不是炒作它确实是 RAG 和 Agent 结合的下一站。4.1 从单次检索到多轮规划经典 RAG 的局限非常明显它假设“一次查询就能找到所有答案”。但现实中的问题往往需要多步求证。举个例子用户问“今年我们哪种产品退货率最高原因是什么” 这是一个两步问题。第一步Agent 需要先查结构化数据找出哪种产品退货率最高第二步拿着这个产品名去知识库检索与退货原因相关的文本。如果你用单次 RAG根本没法完成这种“先查 A再用 A 的结果查 B”的链路。而 Agentic RAG 的核心能力就是允许 Agent 自主规划检索步骤查什么、用什么工具查、查完结果怎么用。我实现这一类 Agentic RAG 时最简单的方式是把“知识库检索”抽象成一个 tool交给 Agent 调用。Agent 的任务规划能力会自己决定调用多少次这个 tool。这不是高深技巧只需要在 LangChain 或类似的框架里定义好 tool 的结构然后让模型在选择工具时看到清晰的描述。4.2 记忆型 RAG让 Agent 越用越聪明Agentic RAG 另一个吸引我的玩法是“写记忆”。很多 Agent 做的东西是一次性的任务结束痕迹清空下次还得重来。但实际业务里知识是累积的。用户偏好的表达方式、常见问题的解决路径、团队内部术语的定义这些都可以沉淀。我设计过一个方案Agent 每次完成一轮任务后会执行一个“复盘”操作把本次任务的问题、解决步骤、关键结论生成一条摘要写入一个“经验知识库”。下次有类似任务时Agent 会先检索这个经验知识库找到之前的解法再决定是复用还是调整。这就是把 RAG 的“知识获取”从静态文档扩展到动态经验上Agent 会给人“越用越聪明”的感觉。这个思路的工程化并不复杂。你只需要给 Agent 增加一个“写知识库”的 tool并在系统提示词里明确告诉她“当遇到可以复用的知识时请记录到知识库。” 但要注意写入的知识一定要做质量把关否则垃圾进垃圾出用几天知识库就废了。5. 实战中的排查技巧与效果度量理论知识聊完了最后这一节全是干货。我在真正落地 RAG 项目时频繁被问到的问题就那么几个命中率不高怎么办幻觉怎么压召回评估怎么做这几件事完全可以标准化处理不必每次都凭感觉调。5.1 命中率的度量别光看“答得好不好”检索质量不是直接看模型回答好不好。模型会“答得好”可能是因为它自己就会不一定因为你检索得准。所以我把度量拆成两层检索层和质量层。检索层的指标常用两个Hit Rate命中率和 MRRMean Reciprocal Rank。Hit Rate 指的是对于一组评估问题正确答案对应的 chunk 是否出现在召回结果中。MRR 衡量的是正确 chunk 排在第几位——排得越靠前MRR 越高。这两个指标只关注检索系统本身不看模型。我建议每个知识库项目一开始就建立一个 “评估问题集”50100 条真实的用户问题每条问题标注对应的正确 chunk 或答案。之后每次调参都在这个问题集上跑一遍 Hit Rate 和 MRR用数据说话不要靠感觉。这带来的好处是你可以放心地尝试不同的切分策略、不同的嵌入模型因为你知道不会“把系统调坏了都不知道”。5.2 提升命中率的三板斧当你发现 Hit Rate 偏低按顺序排查这三件事绝大多数问题都能解决第一检查 query 到 chunk 的表达鸿沟。用户问的句子和知识库里写的方式差异太大导致向量相似度不高。这时候用 query 改写或者用多 query 召回效果立竿见影。第二检查切分策略。如果知识库里按固定字符切分试试按语义边界切分。我踩过最深的坑是一篇技术文档里有一个很关键的表格固定切分把表格劈成了两半检索出来模型根本看不懂。改成“表格整体保留为一个 chunk”之后命中率直接提升了 12%。第三加入重排模型。前面说过的 rerank 策略在这一步收益最明显。很多团队的命中率卡在 60% 左右加了重排之后能到 85% 以上。5.3 幻觉压制与回答质量检查Hit Rate 解决了“能不能找到”但“答得对不对”又是另一回事。即便是 RAG也不可能完全消除幻觉但可以做到“可控”。我的经验是两层防护。第一层在 prompt 里做明确告诉模型“只能基于上下文回答知识库没有的内容必须承认不知道”。第二层在后处理做写一个“回答-引用一致性检查”的代码逻辑提取模型回答中的关键信息点和它引用的那些 chunk 做个交叉验证。如果回答里出现了某句断言但没有对应任何引用来源就判定为可疑返回给模型要求修正或直接拒绝回答。这层“校验器”听起来工程量大实际操作起来并不复杂你可以在 LangChain 里把它实现为一个单独的 node。我上线过一套客服 Agent加了这个校验器后幻觉相关的客诉率基本降到了零。5.4 一份“常见问题速查表”根据我自身的开发经历我整理了一份 RAG 落地中的常见问题速查表可以直接收藏备用问题现象排查方向常用解法命中率低、答非所问切分策略、query 改写、嵌入模型语义切分、Multi-Query、换中文嵌入模型回答与知识库不符prompt 约束、引用一致性明确“不知道”规则、后处理校验检索结果全是无关内容元数据过滤、domain 隔离按领域加 metadata 过滤缩小检索范围回答太长/上下文溢出chunk 太大、召回数太多调小 chunk_size、降低 top_k、做 context 预算知识库更新后效果不变缓存未清、索引未更新确认增量索引逻辑必要时全量重建精确编号/型号查询不准向量检索不擅长精确匹配混合检索BM25 向量或启用全文索引6. 从 RAG 基础走向完整知识管道说回到文章最初的命题——知识获取管道。RAG 基础能力搭建完之后你其实已经拥有了 Agent 的“外接大脑”的第一版。但真正的生产系统往往还需要往两个方向延伸。第一个方向是“结构化知识的融合”。我见过很多团队的知识库既有文档也有数据库表还有图结构的关系。单一 RAG 擅长处理文档但拿它查数据库就非常蹩脚。所以在完整知识管道中我会把 SQL Query、GraphRAG、文档 RAG 都纳入到 Agent 的 tool set 中由 Agent 根据问题类型自动选择去查哪个。第二个方向是“知识的生命周期管理”。知识不可能一劳永逸地入库。旧文档要淘汰、新文档要加入、冲突的信息要仲裁。我在工程实践中会给每个 chunk 打上时间戳和来源并定期通过相似度检查来发现“新旧矛盾”——同一主题下哪些 chunk 的内容互相冲突再决定是否更新或删除。这些扩展方向都是在 RAG 基础之上长出来的。基础没打好后面这些功能全是空中楼阁。最后说一点个人心得。我做了那么多 Agent 项目最常对团队强调的一句话是RAG 不是模型而是一种“获取知识的管道设计”。你用什么样的k开头、用什么样的方式切文档、给模型什么样的引用上下文所有这些都决定了 Agent 是不是真的可靠。它不像调大模型那样“黑盒”而是每一个环节都可以被观察、被度量和被优化。这正是知识管道的魅力——它让 AI 系统变得可解释、可控。如果你也想自己动手我建议从本地搭建一个小型 RAG 开始选一本文档集用 LangChain 完成切分和向量化接入一个开源向量数据库再跑几个问题试试命中率。按这篇文章里的步骤走一遍你会对“管道”这两个字有完全不同的实感。后面我会继续更新 Agent 系列的其他主题包括规划能力、工具调用的设计、记忆机制的演进大家可以按需跟进。