RAG 开发入门(一):从关键词检索到 Agentic RAG
RAG 不等于向量数据库。文档预处理、混合检索,以及把检索工具交给 Agent,才是这条链路真正变化的地方。
RAG(Retrieval-Augmented Generation,检索增强生成)做的事情很直接:模型回答之前,先从外部资料里检索相关内容,再把这些内容放进本次对话的上下文,让模型基于资料回答。
它主要补的是模型参数里没有的知识。公司制度、接口文档、业务规则、产品手册、故障记录,这些东西不一定在模型训练数据里。RAG 把回答锚定到外部资料上,可以减少模型在没有依据时凭空猜答案的概率。
它不是把知识永久写进模型参数,也不是单纯上一个向量数据库。文档切块、Embedding、向量库、相似度搜索,都是常见实现方式,但不是 RAG 的全部。
用 Java 后端的视角看,RAG 更像是在搜索服务和问答接口之间加了一层上下文组装逻辑。先检索,再整理检索结果,控制长度、来源和引用,最后调用模型生成答案。
这篇先不写代码,先把 RAG 这条链路的变化讲清楚。从关键词检索到向量检索,从文档预处理到多模态资料,从固定流程到 Agent 自主检索,变化看起来很多,落到工程上都是同一个问题:怎么把更合适的上下文找出来。
1. 检索先从关键词开始
在大模型之前,搜索系统的主角是倒排索引、TF-IDF、BM25 这一套。Java 开发者对它们并不陌生,Elasticsearch、Solr、Lucene 背后都是这条路线。
倒排索引解决的是“词在哪些文档里出现过”。用户输入关键词,系统找到包含这些词的文档,再根据词频、逆文档频率、字段权重、文档长度这些信号排序。BM25 之所以长期好用,是因为它非常适合处理明确的词面匹配。
比如用户搜索 NullPointerException、OrderService、ERR_10027、退款失败,关键词检索通常很可靠。错误码、类名、接口名、产品术语、法规条文编号,这些东西本来就应该精确匹配。
它的问题也明显:用户不一定会用文档里的原词。
文档里写的是“费用报销审批流程”,用户问的是“出差回来钱怎么报”。文档里写的是“账号冻结”,用户问的是“为什么登录不了”。词没对上,传统检索就可能漏掉。哪怕文档里有答案,搜索系统也不一定找得到。
所以在大模型时代之前,搜索系统已经有很多补丁:同义词词典、分词词库、query rewrite、人工运营的搜索规则、学习排序。这些都在试图弥补一个问题:关键词检索不理解语义,它只是在匹配词。
2. 向量检索补上语义召回
Embedding 的出现,把检索从“词面匹配”推到了“语义相近”。
一个 Embedding 模型会把文本转成一串数字,也就是向量。两个句子的意思越接近,它们在向量空间里的距离通常越近。这样用户问“出差回来钱怎么报”,系统也有机会召回“费用报销审批流程”这类文档。
2020 年前后,Dense Passage Retrieval 和 RAG 这些工作把这条路线推到了开放域问答里。DPR 证明了用稠密向量做段落召回,可以在很多问答数据集上超过强 BM25 基线。RAG 则把检索器和生成模型组合起来,让模型在生成答案前先拿到外部知识。
这就是今天很多人理解的 RAG:文档切块,向量化,召回,生成。
但这里有个很容易被忽略的点:向量不是原文,它是压缩后的语义表示。压缩就会丢信息。
对自然语言问题,向量检索很有用。对代码符号、错误码、版本号、配置项、表字段、枚举值,它未必稳定。userId 和 accountId 在语义上可能很接近,但在系统里完全不是一回事。S3、S4、P0、P1 这种短词,在向量空间里也经常不如关键词可靠。
所以向量检索不是关键词检索的升级替代,而是另一种召回信号。它补上了“同一个意思,不同说法”的问题,但没有解决所有检索问题。
3. 向量化之后,关键词又回来了
这几年 RAG 走过一个有意思的弯路。
早期大家觉得关键词检索太旧,向量检索才是未来。后来做了很多真实系统才发现,纯向量检索并不稳。它擅长语义相近,不擅长精确约束。技术文档、代码仓库、客服知识库、法律条文、企业制度里,恰好有大量必须精确匹配的词。
于是关键词又回来了,只是这次不再是单独回来,而是和向量一起回来。
现在更常见的做法是混合检索:BM25 召回一批,向量召回一批,再用 RRF、加权融合或 rerank 模型把结果排起来。关键词负责抓住精确术语,向量负责补上语义表达,重排负责在候选结果里做更细的相关性判断。
这不是技术倒退,而是工程系统承认了一个事实:检索没有一条路线能覆盖所有问题。对 Java 开发者来说,不要一上来就把 Elasticsearch 扔掉,也不要以为上了向量库就自动有了知识库问答能力。很多时候,最稳的第一版方案反而是保留现有搜索能力,在旁边加向量召回和重排,再用日志和评测决定比例怎么调。
4. 文档预处理和工程链路决定 RAG 质量
很多 RAG 项目最容易低估的环节,是文档预处理。
表面看,预处理只是把文件读出来,切成一段一段,再送去 Embedding。真实系统里,这一步经常决定后面的检索有没有意义。
先看解析。PDF 可能有页眉页脚、脚注、水印、双栏排版和扫描页。Word 里可能有批注、表格、目录和修订痕迹。网页里可能混着导航、广告和无关推荐。接口文档里可能有请求参数、响应字段、错误码和代码块。如果解析阶段把这些结构打散,后面再好的向量模型也只能处理一堆碎片。
再看切块。按固定字符数切最简单,但很容易把一个完整语义拆断。一个接口说明被拆成两块,前一块只有字段名,后一块只有字段含义,检索时就会两边都不完整。技术文档更明显,标题、正文、代码块、表格、图片说明经常要作为一个整体处理。
还有元数据。文档属于哪个系统、哪个版本、哪个租户、哪个权限范围、哪个发布时间,这些信息不能只放在正文里。它们应该成为索引字段,用来过滤和引用。否则用户问 2026 年新版流程,系统可能把 2024 年旧制度拿出来;用户没有某个业务线权限,系统也可能召回不该看的资料。
所以预处理不是 RAG 的准备工作,而是 RAG 的一部分。文档解析、结构保留、切块策略、元数据抽取、权限绑定、去重和版本管理,都会影响召回质量。
资料处理完之后,还要进入完整的 RAG 工程链路。文档块会进入关键词索引、向量索引或多模态索引。用户提问之后,系统也不一定直接拿原问题去搜,很多场景会先做 query rewrite,把口语问题改写成更适合检索的查询,也可能拆成多个子问题分别检索。召回之后还要重排,把最可能有用的内容放前面。
重排之后才是上下文打包。模型上下文窗口有限,系统要决定哪些片段能进 prompt,哪些片段只能丢掉,还要控制来源、引用、权限和版本。生成之后也没结束,一个可上线的 RAG 系统还要处理兜底、评测和日志。用户问了什么,系统搜到了什么,模型用了哪几段,答案有没有引用来源,这些都要能追踪。
如果把它翻译成 Java 后端架构,大概会拆成几层:文档摄取服务、索引服务、检索服务、重排服务、上下文组装服务、模型调用服务、评测和观测。向量数据库只是其中一块,不是整个系统。
这几年常被提到的 GraphRAG,也可以放在这条工程链路里理解。它不是简单把向量库换成图库,而是先从资料里抽取实体和关系,再用图结构、社区摘要和局部邻居检索来回答更全局的问题。它适合“这批资料主要在讲什么”“这些事件之间有什么关系”这类问题,但它同样要付出索引成本和维护成本。
5. 多模态让资料不再只是文本
最早的 RAG 主要处理文本。但企业里的知识不只在文本里。
很多信息藏在图片、截图、表格、扫描件、流程图、PPT、监控图、架构图里。只把 PDF 里的文字抽出来,往往会丢掉版式和视觉关系。比如一个产品手册里的按钮截图、一个报表里的列关系、一个架构图里的箭头方向,只靠纯文本很难表达清楚。
CLIP 这类图文对齐模型把图片和文本放进同一个语义空间,后来更多多模态 Embedding 模型继续扩展这条路线。它们让系统可以用文本搜图片,也可以把图片、页面截图、文档块放进同一套检索链路。
这一步的意义不是“图片也能向量化”这么简单,而是 RAG 的资料边界变宽了。
以前 RAG 默认处理的是文档段落。多模态之后,一个可检索的知识单元可能是一段文字、一张截图、一块表格、一个页面区域,甚至是一段视频里的关键帧。对做企业知识库、客服助手、运维助手、代码助手的人来说,这会直接影响文档解析和切块策略。
不过多模态也没有让问题消失。图片里的文字要不要 OCR,表格要不要结构化,截图和说明文字怎么绑定,召回后怎么引用来源,这些都还是工程问题。模型能力变强了,系统设计反而更不能偷懒。
6. Workflow RAG 可控,但上限有限
很多生产系统会先做 Workflow RAG,因为它容易上线。
Workflow RAG 的特点是流程固定。用户提问进来,系统按预设步骤执行:识别意图,改写查询,选择知识库,做关键词和向量召回,重排,组装上下文,调用模型,生成答案,校验引用,返回结果。
这种方式的优势是可控。每一步出了问题都能定位:是问题改写错了,还是召回错了;是重排没排上来,还是上下文打包丢了关键段落;是检索没问题但模型胡答,还是模型答案对但引用不完整。
对 Java 团队来说,Workflow RAG 也更像熟悉的后端系统。每一步都是一个服务或一个组件,有明确输入输出,可以打日志,可以做压测,可以加缓存,也可以单独写测试。
但我现在不太看好它的长期上限。固定流程适合标准问答,问题一旦变成跨系统、跨资料、多轮追查,Workflow 就会不断膨胀。你会继续加意图识别,加分支,加规则,加兜底,最后把一个检索系统写成复杂的流程编排。
Workflow RAG 仍然适合做基线。它能让团队先把文档、索引、召回、重排和引用这些基础能力跑通。但如果目标是让系统处理开放问题,而不是回答固定 FAQ,它很难成为最终形态。
7. Agentic RAG 是给 Agent 一个检索工具
Agentic RAG 离不开 Agent 本身。这里不需要先展开 Agent 框架,可以先把 Agent 当成一个黑盒:它拿到任务,能调用工具,能观察工具返回结果,再决定下一步做什么。
从这个视角看,Agentic RAG 的本质很简单:给 Agent 一个检索工具。
这个工具可以叫 searchKnowledgeBase,也可以叫 searchDocs。输入就是一组关键词,输出是一批带来源的候选片段。Agent 不需要知道底层是 BM25、向量库、混合检索还是 rerank,它只需要知道:我可以查资料。
区别在于,关键词不再完全由用户输入决定,也不再完全由工作流提前规定。Agent 会根据任务自己生成多个检索词,先查一轮,看结果够不够,再继续换词、补词、缩小范围或扩大范围。
比如用户问:“为什么这个订单退款失败,用户又收到了两次通知?”
固定 RAG 可能只会去知识库里搜退款失败。Agentic RAG 会更像一个排查过程。它可能先搜“退款失败”,发现结果只解释了业务状态;接着搜“退款通知发送规则”,再搜“订单状态回调”和“通知幂等”;如果工具允许,它还可以查接口文档或日志查询工具。每次检索都会改变下一次检索关键词。
这也是为什么向量化之后,关键词又变重要了。Agent 生成的很多查询不是自然语言问题,而是一组更适合检索系统的关键词:错误码、状态名、接口名、字段名、业务动作、同义表达。RAG 不再只是“用户问题向量化后搜一下”,而是 Agent 在执行过程中持续产生检索查询。
这类能力对复杂问题有价值,尤其是问题本身需要多跳推理、跨系统定位、动态选择工具的时候。它也带来明显成本:调用次数增加,延迟变高,调试更难,失败路径更多。Agentic RAG 不是更省事,而是把固定流程里的分支判断,挪到了 Agent 的循环里。
8. Java 开发者先抓四层
如果暂时不写代码,Java 开发者理解 RAG 可以先抓四层。
第一层是文档层。它负责把资料变成可检索的知识单元。这里包括解析、清洗、结构保留、切块、元数据、权限、去重和版本管理。
第二层是检索层。它负责把候选上下文找出来。这里不只包括向量库,也包括 BM25、过滤条件、权限、query rewrite、rerank 和混合检索。
第三层是 Agent 和生成层。普通 RAG 里,它负责把检索结果变成模型上下文,再生成答案。Agentic RAG 里,它还负责决定什么时候检索、用什么关键词检索、是否继续检索、什么时候停止。
第四层是评测层。它负责回答一个很实际的问题:系统答错时,到底是文档没处理好,没搜到,搜到了没排上来,排上来了没塞进 prompt,还是模型拿到了证据也答错了。
很多 RAG 项目做不下去,不是因为向量库选错了,而是因为没有评测层。没有评测,就只能凭感觉调解析规则、chunk size、topK、相似度阈值和 prompt。调到最后,线上一换问题集又坏了。
后续写代码时,我们也会按这个顺序来:先讲文档预处理,再手写一个最小可跑的 RAG,然后补 Embedding、向量库、混合检索、重排和评测。Agentic RAG 放在后面,但不是因为它不重要,而是因为它依赖前面的检索工具足够可靠。
9. 先别急着选框架
Java 生态里已经有不少 AI 框架,比如 Spring AI、LangChain4j、AgentScope Java。它们都能帮你少写很多胶水代码。
但在学 RAG 的第一阶段,我不建议直接从框架开始。框架会把很多关键细节藏起来:文档怎么切,向量怎么存,topK 怎么取,检索结果怎么进 prompt,模型为什么会引用错来源。你如果还没看过这些底层链路,遇到问题时很容易只会改配置。
更好的路径是先手写一版。代码不用复杂,只要能把一篇 Markdown 文档预处理、切块、向量化、存储、召回、塞给模型回答,就够了。跑通之后再引入框架,你会知道框架到底帮你省了什么,也知道它的抽象边界在哪里。
这篇先把路线讲清楚。下一篇先讲文档预处理,把文件怎么变成可检索的知识单元讲清楚,然后再进入 Java 最小 RAG。
参考资料
- The Probabilistic Relevance Framework: BM25 and Beyond
- Dense Passage Retrieval for Open-Domain Question Answering
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT
- Learning Transferable Visual Models From Natural Language Supervision
- OpenSearch Hybrid Search
- Weaviate Hybrid Search
- From Local to Global: A Graph RAG Approach to Query-Focused Summarization
- Agentic Retrieval-Augmented Generation: A Survey on Agentic RAG