近两年聊 AI Agent,绕不开的一个词就是 RAG。很多人把它当成一个“给大模型接上知识库”的黑盒,Q&A 一问一答就完了。但真正从 0 到 1 去搭过 Agent 知识管道的人都会有同感:RAG 的核心难点根本不是“调一个向量数据库再拼一段 prompt”这么简单,而是整条链路的工程化——从文档解析、切片策略、向量化、检索排序,到重排、上下文组装、迭代式检索,再到评估和持续优化。这篇是“走进 AI Agent”系列的第四篇,我把自己在搭建知识获取管道时沉淀下来的一些思路、参数选择、踩坑记录和排查方法整理出来,希望能给正在搞 RAG 项目、用 LangChain 或 Spring AI 做 Agent 应用开发、以及准备搭建本地知识库的朋友一些可复用的参考。
很多人会问:有了大模型,为什么还要 RAG?直接用长上下文把资料全塞进去不行吗?这事我在实际项目中试过,效果确实不稳定。 Token 长度上去了,模型对中段信息的关注度会明显下降,而且每次推理的延迟和成本都跟着涨。更关键的是,知识是会过时的,模型训练时的知识截断日期摆在那里,你不可能为了几条新文档就去微调一次模型。RAG 做的事情本质上是在推理时外挂一个“可更新的记忆系统”——把内部参数化知识和外部非参数化知识做分离,用户提问时先从外部存储里检索出最相关的片段,再把这些片段作为上下文交给大模型生成答案。这个思路看起来平淡,但它解决了三个很实际的问题:让模型能回答私有领域或实时更新的问题,让答案有据可查,让知识更新不需要重新训练模型。
我在系列文章里一直强调一个观点:Agent 的规划、工具调用、记忆管理,这些能力都依赖一个前置条件——它能拿到“对的信息”。信息拿错了,后面的推理和行动全是空中楼阁。所以 RAG 这条管道做得好不好,直接决定了 Agent 回答的底限。这篇文章不会只停留在概念解释上,我会从整体架构、索引构建、检索链路、优化手段、评估方法、常见故障排查几个维度展开,尽量把每个环节的“为什么这么做”和“踩过的坑”讲透,让不同基础的朋友都能找到自己需要的那部分。
1. 内容整体设计与思路拆解
1.1 RAG 不是什么“高级功能”,而是一条完整的管道
我先给 RAG 画个像。它绝对不是“把 PDF 喂给大模型,然后问它问题”这么简单。从工程视角看,RAG 是一条包含索引构建和查询推理两个阶段的管道。
索引构建阶段要完成四件事:文档加载,也就是把 PDF、Word、Markdown、HTML 等不同格式的内容解析出来;文本切分,把长文档切成适合检索和生成的片段;向量化,把文本片段通过 Embedding 模型转换成向量;向量入库,把向量和原文元数据写入向量数据库,同时建立索引。
查询推理阶段同样有四步:查询理解,对用户原始问题做改写、扩展或意图识别;检索,在向量库中找最相似的 TopK 候选;重排与过滤,通过交叉编码器或规则进一步精排,把真正相关的信息留在最后的上下文里;生成增强,将检索结果与原始问题组装成 Prompt,交给大模型产出最终答案。
这两条链路环环相扣。索引阶段切分方式直接决定了检索阶段的命中率,检索阶段的 TopK 参数又直接影响了最终生成的质量。如果你把 RAG 理解成“向量数据库 + 提示词拼接”,那大概率会在上线之后遇到“检索到的内容牛头不对马嘴”“答案出现幻觉”“明明知识库里有答案模型却说不知道”这类问题。本质上,这些问题都出在管道某个环节的设计上,而不是大模型本身。
1.2 为什么选择“检索增强”而不是“长上下文硬塞”或“微调”
在实际项目选型时,摆在面前的无非三条路:RAG、长上下文直接输入、微调。我分别说下它们的适用场景和取舍逻辑。
长上下文硬塞看起来最省事,尤其现在模型窗口动辄 128K、1M。但你真把 50 份文档全部塞进上下文,检索能力会退化。我做过一个对比实验:同样的问题,只在上下文里放入与问题相关的 4 个片段,和把整份 80 页报告全塞进去,前者的回答准确率显著更高。原因是注意力机制对长文本中的关键信息“淹没”问题,本质上信息密度下降后,模型难以聚焦。而且长上下文的延迟和成本是线性增长的,对线上服务并不友好。
微调方案的目的是把知识“内化”进模型参数里,适合需要改变模型行为风格的场景,比如让模型学习某种特定输出格式或业务逻辑。但微调不适合做知识更新频繁的系统,因为每次更新都要重训,成本高、周期长,而且模型会“记错”或“混淆”知识,产生幻觉的风险并不比 RAG 小。
RAG 的优势在于三点:知识的增删改查完全在外部系统完成,更新即时生效;回答时可以引用来源,用户能溯源,这在企业场景里几乎是硬需求;构建成本相对微调低很多,一套基础 RAG 链路用开源组件就能跑通。当然它也有短板,比如检索不准时答案会差,响应延迟比纯模型推理高一些,Prompt 组装复杂等。但在绝大多数 Agent 应用里,RAG 作为知识获取管道依然是性价比最高的方案。
1.3 从“朴素 RAG”到“Agentic RAG”的设计演进
如果是 Mini 项目,朴素 RAG 够用:一次检索、一次生成、完事。但如果你在做一个多轮对话的 Agent,或者需要解决复杂问题的系统,朴素 RAG 的瓶颈就出来了。
朴素 RAG 的问题在于“一次定生死”。用户的真实问题往往是模糊的,比如“我们公司上季度的销售数据为什么下滑了”,这问题需要先拆解成“上季度销售额是多少”“哪些地区下滑最严重”“有没有竞品因素”等子问题,再分别检索,最后综合推理。一次向量检索很难覆盖这些不同维度的信息。
所以现在大家开始往 Agentic RAG 方向演进。它的核心思想是让大模型参与检索决策:模型根据用户问题决定是否需要检索、检索什么、检索几次,甚至决定是走向量检索还是走 SQL 查询还是调用外部 API。这样 RAG 就从“被动的知识查询工具”变成了“主动的信息获取智能体”。
我在实际项目中采用了一种折中方案:用路由模块判断问题类型,简单事实类问题直接走基础检索;多跳类问题走多步检索;需要实时数据的问题则接入工具调用。这比一上来就上完整的 Agentic 编排要稳妥得多,也更容易排查问题。后面在核心细节和常见问题部分,我会把这种分层路由的具体实现思路展开讲。
2. 核心细节解析与实操要点
2.1 文档解析:整个管道的“脏活累活”
很多人轻视文档解析,总觉着用现成库把 PDF 转成文本就行。实际上一份扫描版 PDF、一份带复杂表格的财报、一份双栏排版的论文,解析出来的效果天差地别。文档解析做不好,后面切片再合理、检索再精准都没用,因为源头的文本已经带了大量乱码和语义断裂。
这里我总结几个实操中确定要处理好的点。
第一,PDF 解析要分情况。文字版 PDF 用 PyMuPDF(fitz)或 pdfplumber 都能处理,但表格结构建议单独用 pdfplumber 提取,因为它的坐标信息更完整。扫描版 PDF 必须走 OCR,我这边用的是 PaddleOCR,中文识别效果比 Tesseract 好一截,尤其在带公式、带特殊符号的场景下。
第二,格式信息要尽量保留。标题层级、段落边界、表格行列关系,这些结构信息在后续切片时非常有用。比如我可以根据文档里的标题结构来判断哪些段落属于同一个主题块,从而做“结构感知切片”,效果远好于纯按字符数硬切。
第三,去噪很关键。页眉页脚、页码、水印、超链接文本、重复的导航文案,这些信息如果不清理,会被当成正文切进片段里,检索时产生大量噪声干扰。我处理企业文档时,通常会用正则规则先过滤掉明显的噪声模式,再配合人工抽检。
我在项目中定的流程是这样的:先做格式识别,确认是文字版还是扫描版;再用对应解析器提取内容和元数据;然后做一轮清洗,去掉页眉页脚水印,处理列表缩进和表格转义;最后抽检 5% 的页面,确认解析质量过关再进入切片环节。这个流程不复杂,但能省掉后面检索阶段的大量麻烦。
2.2 切片策略:参数选择背后的计算逻辑
切片是整个 RAG 管道里最容易被算法同学忽视、却被效果直接放大的环节。切片过大,单个片段包含太多无关信息,向量化后的语义会被稀释,检索精度下降;切片过小,语义不完整,尤其是一句话被拦腰截断,检索召回的片段往往缺乏上下文,答案生成时缺信息。
我常用的几个参数组合,分享出来供参考:
| 场景 | 切片长度(字符) | 重叠长度(字符) | 切片方式 |
|---|---|---|---|
| 通用文档问答 | 800-1000 | 100-150 | 按段落优先,其次按句边界 |
| 代码文档 | 1500-2000 | 150-200 | 按代码块结构切 |
| 法律合同、规章 | 500-800 | 80-100 | 按条款编号切,保留条款标题 |
| 多跳复杂问答 | 1200-1500 | 200-300 | 保留标题上下文,做父子切片 |
这里有个很重要的概念叫“父子切片”。简单说,就是对同一份文档同时做粗切片和细切片,检索时在细切片上做向量匹配,找到后再把对应的父级粗片段作为上下文返回给模型。这样做的好处是检索的精度和生成的上下文完整性兼得。成本是存储的片段数量变多,索引体积变大,但效果提升很明显。
切片的代码实现上,我踩过一个坑:直接按字符数切片会把句子和段落拦腰截断。后来我用的是递归式字符文本分割器,先尝试按段落分隔符切,如果切出来的块还是大于目标长度,再按句号、感叹号等句边界切,再不行才按字符硬切,并且每一段都加了重叠区。重叠区的作用是防止关键上下文恰好落在边界处而丢失。
提示:切片长度其实和 Embedding 模型的处理长度有关。比如用的模型支持 512 个 token 的输入,而中文里一个 token 大概对应 1 到 1.5 个汉字,那么向量化时超过 512 token 的部分会被直接截断。所以切片长度要反过来适配模型,而不是盲目拍脑袋定一个数。
2.3 Embedding 模型选型与向量库对比
Embedding 模型决定了“语义相似度”怎么算。选错了模型,后续所有检索质量都会受限。我在实际项目里做过几组对比,这里把核心结论分享出来。
中文场景下,如果要求部署简单、效果稳定,我常用 BAAI/bge-large-zh-v1.5 或 bge-m3。bge-m3 支持多语言和长文本,处理混合中英文的企业文档体验不错。如果做的是纯代码相关检索,可以考虑代码专用模型。国外模型如 OpenAI 的 text-embedding-3 效果确实好,但企业内部数据通常不允许出网,所以本地部署是主旋律。
选型时要关注三个指标:维度数、最大输入长度、语义匹配效果。维度数影响存储空间和检索速度,不一定越大越好,有些场景 256 维和 1024 维的最终效果差异很小,但存储和计算开销差很多。最大输入长度决定你对切片长度的上限约束。语义匹配效果建议用自己的业务数据做小规模评测,用公开榜单数据做参考意义有限。
向量数据库的选型,我把常用的几个放在一张表里。
| 方案 | 部署方式 | 适合场景 | 需要注意的点 |
|---|---|---|---|
| Milvus | 分布式/单机 | 大规模生产环境 | 组件多,运维成本较高 |
| Qdrant | 单机/集群 | 中等规模,API 友好 | 内存占用偏高 |
| Chroma | 嵌入式 | 原型和小型项目 | 不适合高并发 |
| pgvector | PostgreSQL 插件 | 已有 PG 体系,混合查询 | 性能受 PG 配置影响 |
| ES 向量检索 | 已有 ES 集群 | 文本检索与向量结合 | 需要 8.x 以上版本 |
我的选择逻辑是:如果项目本来就是 Java 技术栈且用了 PostgreSQL,直接上 pgvector 最省事,连向量和业务数据的事务一致性都解决了;如果检索数据量过千万且并发高,再考虑 Milvus。简易练手项目用 Chroma 或 LanceDB 就可以,没必要一上来就搭一套分布式。
2.4 检索链路:查询改写、TopK 选择与混合检索
检索环节是用户可感知效果最直接的阶段。这里我讲三个高频优化点。
第一个是 Query 改写。用户在对话里的原始问题往往缺少上下文,比如说“它的价格是多少”,如果不知道“它”指什么,直接拿去向量检索,召回结果通常很散。我的做法是:把最近两到三轮的对话历史连同当前问题一起交给大模型,让它生成一个能独立检索的查询语句。这一步成本很低,但对多轮场景的检索命中率提升非常明显。
第二个是 TopK 的设定。TopK 太小,可能漏掉正确答案;TopK 太大,会把大量弱相关片段塞进上下文,模型反而被噪声干扰。我的经验值是检索阶段 TopK 取 20 到 50,重排后保留 3 到 5 个片段进入生成阶段。这个“先宽后严”的思路,比一次性只取 5 个效果好很多。
第三个是混合检索。纯向量检索对同义改写、语义相近的匹配很擅长,但对精确关键词、专有名词、编号类查询反而会失灵。比如“JD 单号 20240012345”,向量检索不一定能精确匹配这个编号。我的方案是 ES 里同时跑 BM25 关键词检索和向量检索,然后用 RRF(Reciprocal Rank Fusion)算法把两份结果融合排序。实测下来,混合检索对包含人名、产品型号、订单号这类查询的提升非常显著。
RRF 的融合公式很简单:对每个文档在两种检索结果里的排名取倒数并累加,排名越靠前贡献越大。这个算法不需要调权重,鲁棒性很好,适合作为混合检索的默认融合策略。
3. 实操过程与核心环节实现
3.1 索引构建实战:用 LangChain4j 或 Spring AI 搭本地知识库管道
我拿 Java 技术栈的 Spring AI 或 LangChain4j 来演示整条索引管道的搭建思路,因为国内做企业级应用用 Java 的仍然非常多。当然 Python 侧用 LangChain 或 LlamaIndex 思路完全一致,底层组件也相差不大。
第一步,把文档加载器接进来。Spring AI 里有现成的 PageContentReader 等组件,但很多企业内部文档是私有格式,需要自己写 Loader。我这里做了一个通用模板,核心是回调机制,解析完一篇文档就丢进下一个处理阶段。
第二步,设置切片器和 Embedding 模型。我用的是自定义的段落感知切分器,按标题层级和段落边界切分。Embedding 模型通过 ONNX 或本地 HTTP 服务接入,Spring AI 支持通过 embedding model builder 配置。这里要注意的是,Embedding 维度必须和向量库集合的维度保持一致,不一致会在写入时报错。
第三步,建立索引并入库。以 pgvector 为例,需要手动创建扩展和表结构,表里至少要有 id、向量列、原文内容、元数据 JSON 列。写入时把切片后的文本逐条向量化并插入,同时给向量列建 HNSW 索引。
注意:HNSW 索引的参数里,m 默认是 16,ef_construction 默认是 64。数据量在百万级以内,这些默认值完全够用。如果数据量上千万或者对延迟敏感,可以把 m 调到 32,ef_construction 调到 100 以上,但索引构建时间和内存占用会同步上升。
3.2 检索与生成链路实现:从向量召回到底层 Prompt 组装
检索代码的核心就三件事:查向量库、跑关键词检索、把结果合并重排。为了便于理解,我用伪代码展示链路骨架,实际工程中可以把每一块拆成独立服务或用 Agent 工具封装。
首先,对用户问题做向量化,在 pgvector 里做相似度检索,取回 TopK 候选。这里排序距离使用的是余弦距离,pgvector 里是向量列与查询向量的内积。如果希望检索结果过滤某些来源或文档类型,直接在 SQL 里通过元数据字段过滤即可。
其次,混合检索时,关键词部分用 PostgreSQL 内置的全文检索或者 ES 的 BM25。Java 工程里如果要省事,可以直接用 Hibernate Search 或 Spring Data Elasticsearch。两份结果拿回来后,按 RRF 公式融合排序。
最后是重排。我用的是 bge-reranker-large 这一类的交叉编码器,对融合后的 Top 50 做精排,取 Top 3 至 5 进入生成阶段。重排的耗时比向量检索高一截,但对最终答案质量的影响非常大。如果对延迟敏感,可以把重排的候选集缩小到 Top 20。
Prompt 组装这部分很关键。我会按固定模板组织上下文,每条检索片段前加上来源标识,如“文档:xxx.docx,页码:第 12 页”,模型回答时就能引用来源。模板里还要明确告诉模型:如果检索内容与问题无关,必须回答“根据现有资料无法回答”,严禁编造。这一步极大降低了幻觉发生的概率。
3.3 增量更新与知识删除:别把知识库建成“一次性工程”
很多 RAG 项目上线后死在知识更新上。文档一变,整个索引就得重建,成本高还容易出问题。我在实际系统里用的方案是“增量管道加版本化管理”。
每当有新文档进来,先做轻量级指纹计算,比如对文档内容做哈希,如果哈希值在库里已存在,直接跳过;如果存在同 ID 但哈希不一致,说明文档更新了,那就先删掉旧的片段再写入新片段。删除时要同步清除该文档对应的所有切片记录,避免产生“文档已删除但片段还在检索结果里”的脏数据。
知识删除这种需求在企业合规场景里很常见。比如某份合同被判定无效,就必须从知识库里彻底移除。我当时在 pgvector 里用 document_id 字段做了关联,删除时一条 SQL 把所有片段清空,同时把对应的原文文件记录标记为失效。这个操作一定要设计成幂等的,也就是重复执行不会报错,避免定时任务重复触发时出问题。
增量更新之外,还有一个容易忽略的点:向量库的统计信息和索引需要在写入后进行刷新,否则刚写入的向量可能无法立即被检索到。当时我用 pgvector 就遇到了这个问题,后来在写入流程末尾强制刷新了统计信息才解决。
3.4 一个可落地的分层路由实现
如果只让我保留一个“从朴素 RAG 到 Agentic RAG”的过渡方案,那我选分层路由。思路是:
- 第一层:意图分类。用户问题进来,先用一个分类模块判断是“事实查询”“多跳推理”“数据计算”还是“闲聊”。
- 第二层:针对不同意图走不同管道。事实查询走标准 RAG;多跳推理走多步检索并在中间插入总结;数据计算走工具调用,接 SQL 或 API;闲聊直接走模型本身,不进知识库。
- 第三层:在标准 RAG 管道内再做一次条件分支。如果检索结果相关性得分都比较低,可以触发一次查询改写后重检索,或者直接告知用户资料不足。
这个分层方案的好处在于:每一层都可以独立测试、独立迭代,出问题时定位很快。比如发现多跳问题回答差,只需要优化第二层里多步检索的策略,不需要动整个知识库。这也是我推荐团队从朴素 RAG 起步时优先采用的演进路径。
4. 常见问题与排查技巧实录
4.1 检索命中但答案胡说,问题大概率出在上下文组装
有一种情况很迷惑:向量检索返回的相关片段确实包含正确答案,但模型给出的答案却引用了别的信息,甚至编造。排查后发现,有两种常用原因。
第一种是片段之间互相冲突。TopK 里同时出现了内容矛盾的片段,模型无法判断谁更可信,就可能导致“和稀泥”式的回答。解决办法是在 Prompt 中明确要求模型优先采用来源时间较新或来源可信度较高的信息,并且如果片段之间存在矛盾,要明确指出冲突点。
第二种是上下文太长,关键信息被稀释。重排后保留的片段太多,导致关键事实淹没在无关信息中。我一般把最终上下文控制在 1500 到 2000 字左右,只保留重排后分数最高的 3 到 5 个片段,并且每个片段前加上来源说明。
如果你的现象是“检索出来的片段和问题毫无关系”,那问题出在更上游,大概率是切片策略或 Embedding 选型不当。切片粒度过大导致语义混杂,或者 Embedding 模型对领域术语理解不足,都值得排查。
4.2 多轮对话里检索结果飘忽不定,试试查询改写
多轮对话场景下,用户的问题常常是不完整的。比如“那第二点呢?”“上面说的那家公司后来怎么样了?”如果不做任何处理直接检索,效果必然差。我在管道里加了一个查询改写模块,用大模型基于最近三轮对话生成独立的检索查询,实测准确率提升非常明显。
实现上要注意一点:改写后的查询要能独立理解,不能带有“它”“这个”“之前说”这类指代词。我见过一些实现,只做简单拼接,把整段对话历史都塞给检索器,结果向量维度和语义都被历史噪声污染。正确的做法是让模型理解用户意图后输出一句简洁、无指代歧义的查询语句。
如果你用 LangChain 或 Spring AI,可以在 QueryTransformer 这类组件里做这一步。这个模块的延迟大约增加一两百毫秒,但对多轮对话的体验改善非常值。
4.3 向量检索“精确匹配”失灵,混合检索兜底
向量检索的优势在于语义相似度,但对精确的 ID、编号、型号并不友好。比如检索“零件型号 AB-1234”,向量模型往往会把它和“AB-1235”搞混,导致返回了错误的片段。这种场景下纯关键词检索反而更可靠。
我经历过一个物流领域的项目,用户查询经常包含运单号、日期区间、目的地编号,纯向量检索的效果惨不忍睹。最后我上了 ES 加 pgvector 的混合检索,关键词部分处理编号类查询,向量部分处理语义类查询,再用 RRF 融合。上线后检索命中率从 67% 提升到接近 90%,这个数字我记得很清楚。
提示:做混合检索时,关键词检索和向量检索最好共享同一份文档 ID 体系,这样融合排序时才能正确对齐。我第一次实施时两套系统各存各的 ID,融合时发现对不上号,不得不做映射表,折腾了好久。
4.4 答案延迟太高,先别怪模型,查查检索环节
RAG 的平均响应延迟往往比纯模型推理高不少。我在排查延迟问题时,按耗时从高到低排查顺序是:重排模型推理耗时、Embedding 模型推理耗时、向量库查询耗时、大模型生成耗时。
很多场景下,重排模型是一个容易被忽视的延迟大头。交叉编码器需要把查询和每个候选片段拼接后过一遍模型,TopK 取 50 时就要推理 50 次。优化手段有两个:一是把候选集缩小到 20 再重排;二是对重排结果做缓存,相同或相似查询直接命中缓存;三是如果对精度要求不高,可以去掉重排阶段,改用向量相似度加简单规则过滤。
向量库查询的延迟也可能成为瓶颈。pgvector 里如果 HNSW 索引没建对,或者表数据量增长后未重新 ANALYZE,查询性能会退化。建议定期检查查询计划,确认是否真正走到了向量索引。
4.5 知识更新后检索不到新内容,大概率是索引写入的坑
这个坑我在生产环境踩过。新文档在系统里显示已入库,但用户怎么问都检索不到。排查过程发现,问题是文档切片写入时向量化请求超时,部分片段写入失败,但业务层只检验了“文档主记录已创建”,没有校验“所有片段写入成功”。
我后来在写入管道里加了两层保障:第一层,写入前生成文档指纹,如果指纹没变则跳过;第二层,每个切片写入后确认返回影响行数,如果有失败则整体标记为失败并进入重试队列。这个机制实现后,知识更新类故障几乎消失。
还有一次是索引刷新的问题。pgvector 在大量写入后,如果不执行统计刷新,优化器可能选择错误的查询计划。我是在写入流程末尾加了一步,防止类似问题再次发生。
5. 效果评估与调优方向
5.1 别只盯着“答案对不对”,要把管道指标拆开
评估 RAG 系统,如果只看最终答案的对错,问题就很难定位。因为答案不好可能是检索的问题,也可能是生成的问题。我把评估分成两层:检索层和生成层。
检索层我常用的指标是 Recall@K 和 Hit Rate。Hit Rate 衡量的是“正确答案是否出现在 TopK 结果中”,Recall 衡量的是“相关片段被召回的完整程度”。这两个指标可以在不依赖大模型的情况下用标注数据集计算,很适合做回归测试。
生成层的指标包括忠实性、相关性、完整性。忠实性指答案是否严格基于检索片段、有没有幻觉;相关性指答案是否回答了用户问题;完整性指是否遗漏了关键信息。这一步可以用大模型做裁判,也可以用人工标注小样本。我的建议是两边都做:大模型裁判跑全量回归,人工标注抽检高风险场景。
5.2 评估数据集怎么造
没有好的评估集,调优就是无底洞。我造评估集的方式是“从真实日志里捞问题,再人工标答案和来源片段”。先跑一版基线系统,把线上用户问题记录下来,让标注人员为每个问题标记出正确的答案和对应片段。不要凭空编问题,因为编出来的问题分布和真实场景往往差异很大。
标注数量不用多,质量是关键。每个核心场景有 30 到 50 个问题就能开展一轮有效的回归评测。关键是覆盖高频类型:事实查询、多跳推理、带编号的精确查询、模糊表述、多轮依赖等。这样评测结果才有代表性。
5.3 可选的调优方向:GraphRAG、Ontology RAG 与 Agentic 检索
如果基础 RAG 已经稳定,但碰到的是企业级知识图谱类场景,比如“组织架构里谁负责哪块业务”“项目之间的依赖关系是什么”,朴素向量检索就很难表达关系型知识。这种情况下可以往 GraphRAG 或者 Ontology RAG 方向探索。
GraphRAG 的思路是:先利用大模型从文档中抽取实体和关系,构建知识图谱,回答问题时通过图谱的关联路径补全上下文。它特别适合处理“多跳关系类问题”。代价是索引构建成本比普通 RAG 高很多,需要设计实体抽取的 Prompt 和图谱存储方案。
Ontology RAG 更进一步,通过构建领域本体来约束实体之间的关系。它适合知识边界清晰、关系固定的行业,比如医疗、金融风控、法律条款。我在自己的项目里没有大规模用这层,但已经在调研它的边界场景。对大多数通用场景,先做好基础 RAG 和分层路由,性价比最高。
如果团队资源充裕,Agentic RAG 也是个可探索方向。它让模型自主决定检索路径,比如先查文档目录再决定检索哪些章节,比一次性 TopK 召回更精准,但实现和评测的复杂度都上了一个台阶。建议在基础链路稳定之后,再以“专题优化”的形式引入,不要一上来就用。
6. 落地经验与个人体会
项目做了这么多年,我越来越确认一个观点:RAG 的价值不在“用了多先进的模型”,而在“管道是否经得起真实场景的考验”。知识库里的文档格式千奇百怪,用户的提问方式五花八门,线上流量忽高忽低,每一个环节都可能成为瓶颈。它不是一次搭建就完事的系统,而是要持续用评估数据喂养、持续调优的管道。
我个人在实际操作中的体会是:先把端到端链路跑通,再把评估体系建好,然后才谈得上优化。很多团队一上来就追 GraphRAG、Agentic RAG 这些新概念,基础检索还没调明白,结果是换了好几个框架,每个都跑在“论文 Demo”水平。我更推荐的做法是,在基础管道里先把切片、Embedding、混合检索、重排这四件事做扎实,再根据评估数据决定是否引入更复杂的架构。
最后再分享一个小技巧:把 RAG 管道里的每个环节都加上可观测性。从文档解析的耗时和失败率,到切片数量、向量化耗时、检索命中率、重排分数分布,全部打点记录。这样当线上出现“回答质量下降”的情况时,你能快速定位是哪一层出了问题,而不是靠猜。
下一篇我准备聊聊 Agent 的记忆模块——短期记忆、长期记忆怎么设计,以及它和知识管道的边界在哪里。这个话题和 RAG 的关联非常紧密,值得单独拿出来讲。如果你也在搭 Agent 知识管道,欢迎把你的踩坑经历留言分享,咱们一起把这套方法打磨得更扎实。