AI Agent开发实战(十)RAG 基础与 Agentic RAG 演进
引言:
之前文章我们把 Agent 的大脑、工具、编排都搭好了,但有个致命短板一直没补:模型不知道你的私有知识——你公司的产品文档、历史工单、内部规范,它一概不知。这恰恰是企业 Agent 价值的大头。这一篇进入第四部分,从 RAG(检索增强生成)的基本原理讲起,一路演进到让 Agent 自主掌控检索的 Agentic RAG。
一、为什么需要 RAG:模型的三个"不知道"
大模型很强,但有三件事它天生做不到:
它不知道你的私有数据。 模型的知识来自公开语料的预训练(第 00 篇),你公司内网的东西它没见过,问它"我们的退货政策是什么",它只能编。
它不知道最新的事。 训练有截止时间,截止之后发生的事、更新过的文档,它都停留在旧版本。
它记不住太多。 就算你想把全部文档塞进上下文,窗口有上限、还烧钱、还有"上下文腐化"(第 13 篇)——把一整个知识库塞进 prompt 既不现实也不划算。
RAG 的思路简单到近乎朴素:别让模型硬记,用的时候现查。 回答问题前,先从你的知识库里检索出最相关的几段材料,连同问题一起交给模型,让它"开卷作答"。
闭卷(纯 LLM): 问题 ──▶ [LLM 凭记忆] ──▶ 可能瞎编
开卷(RAG): 问题 ──▶ [检索相关材料] ──▶ [LLM 基于材料作答] ──▶ 有依据
这带来两个直接好处:答案有据可查(能附出处,大幅减少幻觉),知识即插即换(更新文档就行,不用重训模型)。
二、朴素 RAG 的完整流程
朴素 RAG(Naive RAG)分两个阶段:离线建索引和在线查询。先看全景:
── 离线:建索引(数据准备,只做一次)──
文档 ──▶ [切分成块] ──▶ [每块转成向量] ──▶ [存入向量库]
│
── 在线:查询(每次提问)────────────────────────┘
问题 ──▶ [问题转向量] ──▶ [向量库里找最相似的 K 块] ──▶ [拼进 prompt] ──▶ [LLM 作答]
离线阶段把知识"消化"成可检索的形式:文档切成小块(chunk),每块通过 Embedding 模型转成一个向量(一串浮点数),存进向量数据库。在线阶段把问题也转成向量,去库里找距离最近的 K 个块,把它们塞进 prompt 让模型作答。
关键是中间那个"转成向量"和"找最相似"——这就是向量检索,得单独讲清楚。
三、向量检索的原理:把语义变成距离
传统关键词搜索(如数据库 LIKE)有个硬伤:它匹配字面,不懂语义。搜"如何退货"匹配不到写着"退款流程"的文档,尽管两者说的是一回事。
Embedding(嵌入)解决的正是这个。它把一段文本映射成高维空间里的一个点(向量),使得语义相近的文本,向量距离也近。
语义空间(示意,实际是几百上千维)
▲
"退货流程" • • "如何退款" ← 语义近 → 距离近
│
│ • "年会时间" ← 语义远 → 距离远
└──────────────────▶
于是"找最相关的文档"就变成了"找距离最近的向量"。相似度通常用余弦相似度(看两个向量方向有多接近)。检索过程就是:问题向量 vs 库里所有块向量,算相似度,取最高的 K 个。
库里向量成千上万,逐个算太慢,所以用 ANN(近似最近邻) 索引(如 HNSW)——牺牲一点点精度,换来毫秒级检索。向量库干的就是这个活。
一段 Java 伪代码把在线流程说清楚(省略 HTTP/SDK 样板,聚焦逻辑):
// 离线:文档切块后,每块存入向量库
for (String chunk : splitIntoChunks(document)) {
float[] vec = embed(chunk); // 调 Embedding 模型
vectorStore.save(chunk, vec); // 存 (原文, 向量)
}
// 在线:一次 RAG 问答
String answer(String question) {
float[] qVec = embed(question); // 问题转向量
List<String> topK = vectorStore.search(qVec, 4); // 找最相似的 4 块
String context = String.join("\n---\n", topK);
return chat("""
只根据以下资料回答问题,资料没提到就说不知道。
资料:
%s
问题:%s""".formatted(context, question));
}
注意那句提示词"资料没提到就说不知道"——这是 RAG 降低幻觉的关键约束,后面还会强调。
四、朴素 RAG 不够用:四个必须优化的环节
上面的流程能跑,但生产里效果往往一般。问题出在四个环节,每个都有对应的优化手段。
① 分块策略(Chunking):切不好,全盘皆输。 块太大,一个块里混了好几个主题,检索到的内容不聚焦、还浪费上下文;块太小,语义被切碎,一句话的上下文没了。常见做法:按语义边界切(段落、标题层级)而非硬按字数切;块之间留重叠(overlap),避免把一个完整意思劈成两半;保留结构信息(这段属于哪个章节)。分块是 RAG 里性价比最高的优化点——很多"RAG 效果差"其实是"块切得烂"。
② 混合检索(Hybrid Search):向量不是万能的。 向量擅长语义,但对精确匹配很弱——产品型号 "X-2000"、错误码 "ERR_507"、人名,这些向量反而容易搞混。解法是把关键词检索(BM25)和向量检索结合:BM25 保精确匹配,向量保语义泛化,两路结果融合。专有名词多的场景,混合检索几乎是必需的。
③ 重排序(Rerank):初筛和精排分开。 向量检索为了快,用的是"粗糙但高效"的相似度。可以先用它召回较多候选(如 Top 20),再用一个更精准但更慢的 Rerank 模型对这 20 个精细打分,取真正最相关的 Top 4。先广撒网、再精挑,召回率和精度兼得,这是提升质量最有效的手段之一。
④ 查询改写(Query Rewriting):用户不会好好提问。 用户的原始问题往往口语化、有指代、或太宽泛("这个咋弄")。在检索前先用 LLM 把问题改写得更适合检索——补全指代、拆成多个子查询、生成假设性答案再拿去检索(HyDE)。问题问得好,才检索得准。
优化后的 RAG 检索链:
问题 ─[改写]─▶ [BM25 + 向量 双路召回 Top20] ─[Rerank]─▶ Top4 ─▶ LLM
①查询改写 ②混合检索 ③重排序
(文档侧:③分块策略决定了库里存的是什么)
五、从 RAG 到 Agentic RAG:让 Agent 掌控检索
前面讲的都是固定的检索流程——不管什么问题,都是"改写→检索→作答"一条道走到黑。这就是朴素 RAG 的根本局限:它把"要不要检索、检索什么、检索够了没"这些决策全写死了。 而这些恰恰该是智能判断。
几个朴素 RAG 处理不好的场景:
- 用户问"你好"——根本不需要检索,但朴素 RAG 还是傻乎乎查一遍。
- 问"对比 A 方案和 B 方案"——需要分别检索 A 和 B再综合,一次检索给不全。
- 第一次检索的资料不够回答——该换个查询再检一次,但朴素 RAG 没有"再来一次"的能力。
- 问题要跨多个来源(先查数据库拿到订单号,再查文档看政策)——需要多步、多源。
Agentic RAG 的核心转变:把"检索"从一个固定步骤,变成 Agent 手里的一个工具。 Agent 用第 一 篇的感知-规划-行动-观察回路,自主决定:现在要不要检索?查什么?查回来够不够?要不要换个说法再查?够了就作答。
朴素 RAG(流程写死):
问题 ──▶ 检索 ──▶ 作答 (永远这三步)
Agentic RAG(Agent 自主):
问题 ──▶ [Agent 判断]
├─ 不需要检索 ──▶ 直接答
├─ 需要检索 ──▶ [检索工具] ──▶ 够了吗?
│ ├─否─▶ 改写查询,再检
│ └─是─▶ 作答
└─ 需要多源 ──▶ 分别调不同检索工具 ──▶ 综合
用图来看,这不就是把"检索"做成一个工具节点、让模型在图上自主循环吗?Agentic RAG = Agent 循环 + 检索工具。 它可以有多个检索源(产品库、工单库、网页搜索各是一个工具),Agent 按需选用;也可以在拿到结果后自我评估"这些资料够不够",不够就再来一轮
它的代价也很实在:多轮检索 + 多次 LLM 判断 = 更高的延迟和成本。所以别无脑上 Agentic——问题类型固定、单次检索够用,就用朴素 RAG(它就是个工作流);问题开放、需要多步多源判断,才上 Agentic RAG。
六、评估 RAG:三个必须盯的指标
RAG 系统最忌"感觉还行就上线"。它有三个环节会独立出错,得分开量:
召回率(Recall)—— 检索环节:该找的找到了吗? 回答问题需要的材料,有没有被检索出来。如果关键材料压根没召回,后面模型再强也是巧妇难为无米之炊。这是 RAG 的地基,先保证这个。 召回差,先查分块和检索策略。
忠实度(Faithfulness)—— 生成环节:答案是不是真的基于检索到的材料? 模型有时会"无视资料、自由发挥",检索到的东西没用上,还是凭记忆编。忠实度低,说明模型没老老实实开卷作答——除了强化提示约束("只根据资料回答"),严重时要考虑换模型或加校验。这是 RAG 区别于普通问答的命门:有依据 ≠ 用了依据。
答案相关性(Answer Relevancy)—— 整体:答案切题吗? 检索对了、也忠实了,但答非所问也不行。这衡量最终答案和用户问题的匹配度。
用户问题 ──▶ [检索] ──▶ 材料 ──▶ [生成] ──▶ 答案
│ │ │
召回率? 忠实度? 答案相关性?
(该找的找到没) (答案基于材料没) (答案切题没)
分开量的意义在于精准定位问题:答案不好,到底是没检索到(召回问题)、还是检索到了没用好(忠实度问题)、还是跑题了(相关性问题)?三个指标一测便知,不用瞎猜。评估方法(LLM-as-Judge、构建测试集)和工具(RAGAS 等)在后面文章展开,这里先建立"必须分环节评估"的意识。
八、小结
这一篇我们理清了 RAG 的来龙去脉:它用"开卷作答"补上了模型"不知道私有数据、不知道最新信息、记不住太多"三个短板;朴素 RAG 是"切块→向量化→检索→作答"一条链,其中分块、混合检索、重排序、查询改写是四个必须优化的环节;而 Agentic RAG 的本质是把检索变成 Agent 手里的工具,让模型自主决定要不要查、查什么、够不够——它就是"Agent 循环 + 检索工具",代价是更高的成本与延迟,实战要根据业务实际情况决定用哪种。最后,RAG 必须分环节评估召回率、忠实度、答案相关性。
更多推荐


所有评论(0)