
做 AI Agent 应用最难的不是让大模型会聊天而是让它知道业务知识从哪里来。我见过太多 Agent 项目前面意图识别、工具调用都跑通了一到真实业务问题就翻车——模型训练时没见过你们公司的产品目录也没读过你们最新的售后规范你让它怎么答这就是知识获取管道要解决的问题也是 RAG 真正发光的地方。RAGRetrieval-Augmented Generation检索增强生成是当前落地最稳的方案先把知识切成块、做成索引等 Agent 接到问题时去检索相关资料再把资料塞给大模型让它基于资料作答。这篇是 AI Agent 系列第四篇我会带你把一条完整的 RAG 管道走一遍从索引、检索、生成到排查再聊到 Agentic RAG 和 GraphRAG 这些进阶方向。文章面向两类人刚开始接触 RAG 的开发者以及已经跑通 Demo、但搞不明白为什么 Hit Rate 上不去的应用工程师。1. RAG 在 AI Agent 里的定位知识获取管道的三种接法1.1 为什么大模型“背课本”解决不了业务知识问题大模型的参数知识是它的“课本记忆”训练截止日期之后发生的事、企业内部规范、某个项目的私有数据它一概不知道。模型参数再大也只能在高层面上“猜一个大概”一猜就容易一本正经地胡说。给 Agent 配 RAG本质上是给它配一间可以随时查阅的档案室。我习惯用一个类比去解释这件事你招了一个名校毕业的高材生什么知识他都能聊两句但他刚入职不知道公司的报销流程也不知道你们正在做的项目代号。你不可能让他瞎编一套流程出来正确的做法是让他自己去查内部 Wiki 和手册。RAG 就是那本手册还是可以按需翻页、自动定位的那一种。在 Agent 的整体架构里RAG 的角色需要再拆细一点。Agent 的决策靠大模型行动靠工具调用而 RAG 是把“非参数化知识”灌进决策过程的管道。它本身不是 Agent更不是记忆系统它是 Agent 的“知识后端”。如果你把这个定位搞混了就会出现两种典型问题一种是把所有问答都塞给 RAG结果无关问题也检索半天另一种是让 Agent 裸奔什么问题都靠模型瞎猜然后怪模型不够聪明。1.2 三种接法同步调用、路由分发与 Agentic RAGRAG 接入 Agent 的方式行业内能看到三类典型形态我建议按顺序演进不要一上来就追求最复杂的。同步调用模式最直接Agent 每次收到用户问题都先去知识库检索一遍再把检索结果随 Prompt 一起发给大模型。适合知识库数量少、对话问题几乎都依赖文档的小工具。缺点是无关问题也会走一遍检索既浪费延迟又抬高了成本。路由分发模式是把 RAG 当成一个可选路径先做意图识别判断这个问题需不需要走知识库。比如“今天天气怎么样”直接调天气工具“公司报销上限是多少”走 RAG。Spring AI、LangChain4j 里都有类似路由的抽象本质上是给 Agent 一段决策逻辑什么情况调用检索技能什么情况不用。路由逻辑写多了会变得很繁琐所以一般只在意图边界清晰时使用。Agentic RAG则是把检索决策完全交给 Agent 自己。Agent 收到问题后自己决定要不要查、查什么、查几轮检索结果不够就再查一次甚至能把一个大问题拆成多个子查询分配不同的知识库去查。这是当前企业级平台最流行的做法但调试难度也最大因为你要同时面对 LLM 规划不稳定和检索质量波动两个变量。我给团队的建议永远是先按同步调用跑通端到端再根据业务需要加路由最后再上 Agentic RAG。因为每一步都要有评估数据做支撑跳级容易死得不明不白。接法典型场景优点主要风险同步调用文档问答工具、内部客服助手实现简单效果可控无关问题也检索资源浪费路由分发复杂业务系统多工具并存能省成本路径清晰规则膨胀后维护困难Agentic RAG知识密集型企业平台灵活能处理多跳问题规划不稳定调试成本高2. 索引阶段实操文档清洗、切分策略与 Embedding 选型2.1 文档加载与清洗PDF、表格和爬虫内容的处理索引阶段是整个 RAG 管道里最不起眼、但最决定上限的环节。资料类型五花八门PDF 多栏排版、Word 带批注、HTML 带导航还有从本地 ERP 导出的产品型号、规格属性这类结构化表格。清洗的目标是去掉噪声、保留语义。我处理过最多的两类资料一类是 PDF一类是表格类导出文件。PDF 用 pdfplumber 处理带表格的页面比较顺手PyMuPDF 速度快但复杂表格容易乱扫描件就得先 OCRPaddleOCR 和 Tesseract 是常用选择。通用抽取可以走 unstructured 这个库它能把 PDF、Word、HTML 转成相对干净的结构化元素。爬虫抓到的网页用 BeautifulSoup 或 Readability 提取正文比直接拿整段 HTML 去切要可靠得多。有个常见的坑必须提醒PDF 里的表格一转出来单元格内容会被拼成一行空格文本看着像模像样切分之后语义全碎。清洗完一定要人工抽检 10 到 20 篇文档别只看前几页就觉得没问题。页眉页脚、目录页码、版权声明这些内容要么删掉要么单独存成元数据别让它混进正文参与切分。2.2 切分策略块大小、重叠参数怎么定才有效切分的目标是让一个块尽可能覆盖完整的语义单元。我见过有人直接按字符固定长度切结果一句话被拦腰截断问什么检索都召回不了。这里必须根据文档结构选择合适的策略。固定长度切片最简单通过 token 数量控制设置重叠区避免信息被切断但缺点是无法感知语义边界。递归字符切分是更实用的方案优先按段落切段落太长再按句子切句子还太长再按子句切LangChain 里的 RecursiveCharacterTextSplitter 就是这个思路。语义切分更进一步用 Embedding 计算相邻句子之间的相似度差异突然变大就断句切块质量最好但处理时间长。参数经验我这里可以直接给参考值初始建议 256 到 512 token 一块重叠区 50 到 100 token具体一定要拿自己的评测集跑 Hit Rate 确定别抄网上现成的。块太大噪声多低相关片段会把正确答案的占比稀释掉块太小单块信息不完整靠多个片段硬拼逻辑容易出现断层。我做过一个产品资料库512 token 固定切分时 Hit Rate 只有 0.6 左右改成 420 token 递归切分后升到 0.74这个提升完全不需要换模型。另外切分时要把标题、文档路径、页码这些元数据写进块对象里后面做引用溯源和过滤都用得上。切分这一步做得干净检索和生成阶段的麻烦能少一半。2.3 Embedding 与向量库选型本地部署还是云 APIEmbedding 选型是另一个关键决策核心看三件事语言覆盖、领域匹配度、硬件条件。中文场景下bge-m3、bge-large-zh、m3e 这些模型都值得试验英文和通用场景OpenAI 的 text-embedding-3 系列、bge、e5 都被广泛使用。做垂直领域比如法律、医疗、金融时通用模型未必最好可以找领域微调过的模型或者拿标注数据自己微调一版投入产出比通常比换大模型更明显。部署方式上云端 API 省事但数据出境和调用费用是隐患本地部署要考虑推理速度CPU 上跑一个 bge-large-zh看每秒能编码多少条文本这会直接影响文档更新时重建索引的耗时。向量库选型不要迷信“越重越好”。我的经验是数据量小、快速验证用 Chroma 或 FAISS 就够了数据量到百万级再考虑 Qdrant、Milvus 这类专用向量库如果业务系统本来就用 Postgres 或 Elasticsearch直接利用它们的向量扩展能力更划算少引入一个组件运维成本低一大截。本地搭建 RAG 知识库时很多人一上来就上全套组件其实单机场景 FAISS 加脚本完全够用。3. 检索阶段优化混合检索、命中率指标与 Reranker3.1 命中率低、排序不对怎么办先看懂 Hit Rate 和 MRR很多同学搭完知识库随口问我“效果怎么样”我第一反应是反问一句“你的 Hit Rate 是多少”如果对方答不上来说明他还在凭感觉调参。Hit RateK 的含义是前 K 个检索结果里是否包含人工标注的正确文档。比如 50 道评测题每道题标注了“正确答案在第几份文档的第几段”跑一遍检索管道后统计命中比例。Hit Rate3 是 0.8意思是 80% 的问题在前 3 个结果里能找到正确答案。这个指标直接从业务角度回答了一个问题召回到底行不行。MRRMean Reciprocal Rank看的是排序质量第一个正确答案的排名倒数然后对所有问题取平均。假如一个问题第一个正确答案排在第二名那这条就贡献 1/2 ≈ 0.5 的分数。MRR 低说明答案“有被召回但排名靠后”大概率要加 Reranker。评测集怎么建也有讲究。从用户真实提问记录里筛 50 到 100 个高频问题让业务人员标出答案来源比你自己拍脑袋造问题靠谱得多。我做过最值钱的一件事就是把线上客服的历史工单整理成了评测集之后每一次改动都能用数据说话。下面这张表可以直接贴在项目文档里做排查参考指标观察要点指标低时的排查方向Hit RateK正确答案是否被召回索引缺失、切分过碎、Embedding方向不对、没有混合检索MRR正确答案排得靠不靠前召回没问题但排序差考虑 Reranker、调整权重RecallK相关片段占比知识库覆盖面不足、元数据过滤过严3.2 向量检索加关键词检索的混合策略向量检索的优势是语义相似用户问“报销上限多少”和文档里“差旅费用报销标准”能匹配上。但越具体的信息越容易翻车产品型号“ACS-300”、工单编号“E1234”、代码报错信息这些都是精确匹配问题向量空间里它们可能跟一堆无关文本纠缠在一起。这时候 BM25 关键词检索能救命。混合检索的标准做法是向量检索和 BM25 各自返回 TopK分数归一化后按权重合并一般向量 0.7 加关键词 0.3 起步再根据线上数据调。LangChain 里可以组合多个检索器LangChain4j 里也有类似混合检索的封装。如果你用 Spring AI通常要自己实现两个来源的结果合并逻辑不复杂但要注意分数字段口径统一。这里我有一个很直观的经验某个型号检索场景纯向量召回经常把“ACS-300”和“ACS-310”混在一起加 BM25 之后精确型号的召回率明显提升。做一个知识库别急着上什么高端算法先搭一个混合检索再说它能把底兜住。关键词分支的细节也值得注意中文场景要配中文分词器否则 BM25 按单字匹配反而引入更多噪声。3.3 重排器Reranker到底什么时候该加向量检索本质是“粗筛”把问题和一个块各自的向量编码然后算余弦相似度。这种做法高效但信息量有限。Reranker 走得更远它把问题和候选文档拼在一起用一个交叉编码器逐字比较相关性分数比向量相似度可靠得多。我的落地习惯是先用向量检索加 BM25 召回 Top30 到 Top50再用 Reranker 从里面挑出 Top5 到 Top8 作为最终上下文。测试一个客服知识库项目时Hit Rate10 从 0.72 提升到 0.81体感更明显的是回答不再“东拉西扯”因为低分段噪声块被清掉了。但 Reranker 不是无脑加。它每次都要对 query 和每条候选做一次模型推理延迟和算力开销不可忽视。实时性要求高的场景要先粗排再重排控制好候选数量。开源模型方面bge-reranker 系列在中文场景表现稳定。如果项目没有 GPU就要认真评估 Reranker 带来的增益是否值得额外延迟有时候把召回阶段做好已经能解决大部分问题。4. 生成阶段落地提示词构造、上下文压缩与引用溯源4.1 系统提示词怎么写让模型只信检索结果检索做得再准生成阶段提示词写得不行照样会胡编。我的 System Prompt 里有几条铁规矩写在这里可以直接抄作业你是一个企业知识助手请严格基于下面的资料回答用户问题。 资料 [1] {来源文档标题} 第{X}页/第{Y}节{检索片段} [2] {来源文档标题} 第{X}页/第{Y}节{检索片段} 要求 1. 只允许使用资料中提供的信息回答问题。 2. 如果资料不足以完整回答请明确回复“根据现有资料无法完整回答”并告知用户缺少哪些信息。 3. 回答时在关键句末尾用[1]这种编号标注信息来源。 4. 禁止编造资料中不存在的产品参数、价格、日期或人物。这几条约束的底层逻辑是把“模型可能用参数知识脑补”的概率压到最低。尤其是第 2 条等于给模型提供了一个合法的“不知道”出口。你不给它出口它就倾向于硬编一个答案这是大模型的本能。提示词之外温度参数也要配合。做知识问答场景温度一般设置在 0.1 到 0.3 之间比较合适。温度拉太高同一个问题每次答案都不一样用户会怀疑你知识库是不是坏掉了。4.2 上下文压紧与去噪别把一堆低分块塞给模型检索返回的块不一定都相关直接全部塞进 Prompt会让模型抓不到重点还白白消耗上下文窗口。你给模型 8 个块只有 3 个有用回答质量一定下滑。我常用三招解决这个问题。第一招是相似度阈值过滤比如余弦相似度低于 0.4 的块直接丢弃阈值要根据你的线上分数分布统计出来不要拍脑袋。第二招是用 Reranker 分数截断只保留 TopK 里足够可靠的那几个。第三招是 LLM 压缩让模型从候选块里抽取与问题相关的句子再喂给主回答链路相当于在检索和生成之间加了一层清洗。还有一类场景要特别提一下某个问题的关键信息分散在多个段落里单块检索只能拿到其中一个片段。这时候“父子文档”模式值得用检索小 chunk把包含它的大段落完整取回既保证精准定位又保留上下文。但要注意这会带来更大的 Prompt token 量延迟和成本都要提前算好。4.3 引用溯源和“不知道”机制是怎么配合的企业场景里用户和审核方都要验证答案的可信度。没有引用的 AI 回答就像没有出处的新闻很难让业务部门买账。我建议做三层设计第一层chunk 对象里保存 doc_id、标题、页码、章节号第二层提示词要求模型回答时带编号引用第三层后处理阶段把编号映射成文档链接让用户可以点击跳到原文页面。“不知道”机制也要配合问题改写。系统提示词里规定找不到就直说但实践层面我更推荐先补救一轮拿原始问题去检索如果最高分数低于设定阈值用大模型把问题改写得更具体再检索一次。最多做一两轮改写再多成本就失控了。这样处理之后真正回“资料不足”的次数会明显减少用户体验好很多。顺带说一个工程上的做法在 Agent 里RAG 完全可以注册成一个工具函数Agent 需要时调用 search_knowledge(query)而不是每次强制检索。这样检索行为就跟其他技能一样可以被 Agent 自主调度这也是 Skill 和 RAG 结合比较自然的切入方式。5. 常见问题与排查技巧实录从症状到根因的排障表5.1 经典翻车现场答案没召回、回答乱编、更新不生效我整理了一份排障速查表基本覆盖了日常维护中最常碰到的几类问题症状可能原因排查手段知识库里明明有答案但召回不到切分把关键信息切碎、Embedding 匹配不理想、没做混合检索把标准答案定位到具体块打印该块的相似度得分单独看检索日志召回内容不少但模型回答乱编细节TopK 太大、低分噪声块混入、Prompt 约束弱降低 TopK、加 Reranker、提高相似度阈值、增强 System Prompt 约束文档更新后回答还是旧版本向量库没有同步更新、索引未重建、有缓存建立增量更新管道监听文档变更事件重建后校验版本号相似度分数整体偏高或偏低Embedding 空间分布差异、归一化未统一对分数做分位数统计用分位数作为阈值而不是绝对分数中文按关键词查不中没配中文分词器按 ik/jieba 这类中文分词方式重新构建 BM25 索引这里面最容易被忽略的是“文档更新不同步”。很多团队把知识库当成一次性工程文档改了向量库里还是旧向量线上用户问到的答案永远是过去时。解决方式很简单chunk 里记录文档版本号或更新时间增量更新模块检测到源文件变化后把受影响的块重新切分、重新 Embedding再写入向量库。这件事听起来基础但没做好的项目一抓一大把。5.2 知识割裂问题一个跨越多个文档的难题“知识割裂”是我在大型企业知识库项目中反复遇到的场景。举个例子公司资料里“产品 A 的保修期”写在销售手册里而“保修期内故障处理流程”写在一份技术文档里客户问“产品 A 保修期内坏了怎么办”需要同时用到这两份文档的知识。单一 RAG 管道如果只做相似度检索往往只召回其中一个。处理思路有三条。第一条是在元数据层面做关联用产品型号把销售手册和技术文档对齐检索时允许按型号扩展。第二条是切换到 GraphRAG 思路把文档中的实体关系抽成图谱检索时沿着关系扩展上下文。第三条是把问题做 query 拆分先识别出问题涉及“保修期”和“故障处理”两个子主题分别检索再合并。这三条不需要同时上但你要知道单纯调大 TopK 解决不了知识割裂因为割裂的本质是信息分散在多个文档、多个语义簇里。5.3 中文场景的两个额外坑中文环境的 RAG 有两个容易被忽略的坑。第一个是分词问题BM25 这类词频算法依赖分词质量英文天然按空格分词中文必须选好分词器否则“汽车保险”会被切成一堆单字匹配结果自然乱七八糟。第二个是中文 Embedding 模型的领域差异通用中文模型在新闻语料上表现不错但换到机械设备参数、法务条款这类专业文本分数分布可能完全不对这个时候一定要用业务语料做验证必要时做领域微调。还有一个小提醒同一个知识库如果内容横跨多个领域比如既有产品规格表又有售后流程建议分别建立索引或知识点在路由阶段就分流而不是混在一个向量库里。这样既降低互相干扰也让后续维护时能独立更新。6. 从基础 RAG 走向 GraphRAG 与 Agentic RAG6.1 基础 RAG 在多跳问题上的软肋基础 RAG 擅长“根据相关文本直接回答”但遇到多跳问题时容易力不从心。多跳问题是什么样的比如“供应商 A 给项目 B 供过货那么项目 B 的负责人是谁”需要从供应商关系跳到项目信息再跳到负责人员工。普通 RAG 拿这个问题去匹配单次检索基本得不到完整链路。即便把问题拆成两个查询两段搜索结果之间怎么拼接、怎么证伪也是个麻烦。另一个软肋是全局性问题。GraphRAG 的定位很好地补足了这一点当用户问“整个产品线里哪些型号的售后投诉率偏高”这种需要跨文档统计的问题时纯向量库很难给出完整答案。6.2 GraphRAG 与 Ontology RAG用关系补足语义GraphRAG 的核心做法是先让大模型从文档里抽取实体和关系构建成知识图谱再把相似实体聚成社群最终面向社群做全局摘要。它的优势是能回答需要全局视角、关联关系的问题。代价也很直观构建图谱的 LLM 调用量远高于普通切分 Embedding处理一大份文档可能要跑很久。所以我一直提醒团队别迷信 GraphRAG大多数知识库其实只需要基础 RAG。Ontology RAG 更强调“先定义一套领域本体”。比如产品知识库先把“产品型号、所属系列、防护等级、适用场景”这些概念和等级关系定义清楚检索时按本体做查询扩展和下钻。用户问“户外高温场合用哪个型号”本体允许你沿“适用场景→户外→高温”这条路径展开查询。对于本地 ERP 加产品检索这类结构化和半结构化数据混合的业务场景Ontology 的价值能发挥得很明显。6.3 Agentic RAG 怎么落到工程上Agentic RAG 的落地套路大致分两种。一种是检索规划型Agent 先判断当前问题是否需要查知识库、需要查哪几个知识点把大问题拆成子查询逐个子查询做检索最终汇总结论。另一种是反馈循环型Agent 读了一遍检索片段觉得证据不足再发起一轮检索换关键词或者换个角度继续查。工程上有几个硬约束必须设好。限制最大检索轮数我一般设 2 到 3 轮避免死循环和成本爆炸每一轮检索的 query 和来源都记录日志方便审计和复盘决定“要不要再查”的条件尽量明确比如置信度低于阈值或者关键信息之间有矛盾。LangChain4j、Spring AI 这类框架组合起来都能把 RAG 检索能力以工具函数的形式暴露给 Agent这也是企业级 Java 平台里常见的模式。很多智能体产品在做盘点时会把这类“把检索封装成独立服务”的架构称作 RAG as a Service本质就是把知识获取从业务代码里抽离出来变成可复用、可治理的能力。6.4 RAG 建好之后还要持续运营知识服务是长期迭代的过程最后想强调一个被低估的真相RAG 管道建好不是结束而是开始。文档会更新用户问题的分布会变化新的知识域会不断出现。你至少要有三套机制保证系统长期可用增量文档更新管道、线上质量监控比如每天抽样回答让业务人员打分、以及一个持续积累的回归评测集。每当你发现一个新 badcase就把它加入评测集这样系统只会越用越稳。这个工作不性但很值得。我见过太多团队在 Demo 阶段惊艳全场上线三个月之后因为无人维护回答质量一路下滑最后被业务部门弃用。RAG 不是一次性工程它是一条需要持续运营的知识管道。我在实际项目里最大的体会是先把端到端最小闭环跑通再谈优化。RAG 看起来三步就能搭起来但每一环都是评估的产物——切分参数要调Embedding 要换着测混合检索的权重要试Reranker 要不要上完全看业务对精度的要求。不要指望一次建成完美管道。给一个非常实用的建议新建项目时先花两天把 50 道带标准答案的评测题做出来把 Hit Rate、MRR 记下来。之后无论怎么改都有对照数据。否则你很容易陷入“感觉比之前好多了”的幻觉。下一篇我会顺着这条知识管道继续往下聊请求路由、多知识库隔离和更新机制有兴趣的可以持续关注。