news 2026/10/19 13:13:37

Agentic RAG实战:从传统RAG的瓶颈到多步迭代检索的构建指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agentic RAG实战:从传统RAG的瓶颈到多步迭代检索的构建指南

1. 传统RAG的极限在哪里

1.1 一次标准RAG的过程长什么样

先别急着上概念,我直接说一个场景:你做了一个基于大模型的内部知识库问答助手,把几十篇产品文档切成小块,做了向量化处理,然后用户问“退货流程是什么”,系统就把问题转成向量,去向量数据库里做相似度检索,把最像的几个文本块取出来,再拼到Prompt里交给大模型生成答案。

这套流程就是最经典的Retrieval-Augmented Generation,也就是常说的RAG。它的核心假设很简单:大模型的参数记忆有限,但这不影响它“临时抱佛脚”,你先把参考资料塞进上下文,它就能对着材料回答问题。

我最初搭这种系统时,最大的感受是:管道很顺,但脑子很死。所谓“脑子很死”,指的是RAG只有固定的三步:Embedding -> TopK检索 -> 生成。无论用户问什么问题,都走同一条管道,差不过一个阈值就返回结果。这也是RAG被形容成“搜索引擎套了一个壳”的原因。

很多小白卡在这里:为什么同样的RAG工程,别人做出来效果不错,自己做出来回答离谱?其实不是因为代码水平差,而是没有意识到RAG的瓶颈不是生成,而是检索和决策层面的僵化。检索结果的好坏,直接决定了最终答案的上限;而检索环节恰恰是整个链路里最不会“思考”的一部分。

1.2 处理复杂查询时,固定流程为什么失效

传统RAG最常见的翻车场景,是“混合条件查询”和多跳问题。举个例子,有一个用户问:“哪个酒店在市中心,附近有宠物友好的餐厅,而且我们小组预算人均不能超过150?”

如果你拿这个问题直接去做相似度检索,会遇到三重麻烦:

  • 语义被稀释:问题里同时包含酒店位置、宠物友好、人均预算三个约束条件,向量化之后它们被揉成一团,匹配出来的文本块可能只对上了“酒店”和“市中心”,另外两个条件直接被忽略。
  • TopK两难:K设小了,漏掉关键信息;K设大了,噪声片段全挤进来。我见过不少人把TopK从4调到8再调到16,效果依然不稳定,就是因为问题本身可以被拆成多个独立维度,而单次向量检索只适合“一段话找一段话”。
  • 时间或其他结构化条件没法满足:“最近一个月”“预算不超过150”“南部区域”这类条件,向量检索根本不懂,它只能算语义的相似,却无法做数值过滤和逻辑判断。

还有更典型的多跳问题,比如“张三在上家公司主导的支付系统,被哪篇技术博客评价过?”这种问题有两个隐含的实体跳转:先要查出张三在哪家公司,然后再拿这家公司去匹配技术博客。传统RAG在第一步就已经把相关性最高但方向不对的内容拉回来了,后续生成自然不会对。

用句大白话说,传统RAG像一个把所有快递都送到一个配送站再分发的大仓库,它适合批量处理、高效分发,但遇到“多个收件人之间还有依赖关系”的包裹,就手足无措了。业界把这类问题叫“单跳检索失效”,现在大家已经形成共识:问题复杂到一定程度后,需要让模型自己决定“下一步干嘛”,而不是靠工程师写死流程。

2. Agentic RAG的核心思路

2.1 从“检索后生成”到“边想边检”的转变

Agentic RAG这个名词这两年高频出现,但理解起来并不难。它没有把RAG推翻,而是把“一次性检索”换成了“Agent驱动的多步迭代检索”。如果把传统RAG比作一个只能按菜单做菜的厨师,那么Agentic RAG就是一个会自己看冰箱、查菜谱、边炒边尝、发现缺调料还会自己出门买的厨师。

这个转变的关键在于:系统由一个大模型作为“大脑中枢”,它有权限调用不同的工具,比如向量数据库、SQL查询器、Web搜索、文档解析器,并且在每一步执行完之后,把工具返回的结果拿回来“看”一眼,再决定下一步是直接生成最终答案,还是继续调用新工具补查信息。

换句话说,检索不再是一次性动作,而是被放进了Agent循环里。

很多没有动手做过的人会以为,这不就是在代码里写个while循环,让模型反复调用检索函数吗?说出来你可能不信,思路确实就这么简单,但难点在于:什么情况下该继续检索?什么情况下该停止?工具调用的参数怎么填?多轮结果之间怎么合并去重?这些细节不处理好,系统就会陷入无休止的循环,或者口吐一堆拼凑出来的错误答案。

2.2 组建Agentic RAG的四类核心部件

一个可用的Agentic RAG系统,通常由下面几个部件组成,搞懂它们,你就能自己画出架构图。

规划器

规划器的职责是“拆解任务”。当用户提出一个复杂问题时,规划器会先判断:这是单一问题,还是需要拆成多个子问题?每个子问题应该交给哪个工具?在实现上,规划器通常是让大模型直接输出一个结构化意图,比如JSON格式的“行动计划”,然后在代码里解析并执行。

我做项目时,固定使用一段Prompt让模型从四个角度规划:是否需要检索、检索哪个知识源、当前信息是否足够、是否需要继续。初期你可以不写复杂的规划逻辑,让模型只决定“要检索”和“不要检索”,其实已经能规避很多胡言乱语了。

路由与工具

路由是Agentic RAG的“交通枢纽”。用户问题进来之后,先经过路由判断,不同意图的查询被分发到不同的知识源。举一个实际例子:我的项目里有两个知识库,一个是产品手册,另一个是FAQ会话记录。如果直接混合检索,两者互相干扰;做了路由之后,先判断问题是“询问操作细节”还是“询问已知问题”,再决定只查其中一个库,准确率明显上升。

工具层也不止是向量检索。一个成熟的Agent可以调用SQL查询器查订单数据、调用API查实时天气、调用文档解析器处理PDF表格。这里的核心价值是:不同类型的知识交给最合适的工具,而不是一律转成向量。

记忆

Agent循环会产生大量中间结果,记忆模块负责在这些结果之间保留上下文。它分为短期记忆和长期记忆:短期记忆保存当前任务中已检索过的内容,避免重复查询;长期记忆可以用一个向量库保存用户偏好或历史修正记录,让系统越用越顺。

最常见的坑是:把所有中间步骤一股脑全部拼进下一轮Prompt,结果上下文膨胀,模型反而把关键信息淹没在大量检索片段里。所以记忆模块不只要“记住”,还要“会忘”。

反思

反思机制是Agentic RAG与传统RAG最大的区别之一。模型在生成最终答案之前,会先自检:“这些检索到的片段与问题相关吗?有没有自相矛盾的信息?有没有关键条件没覆盖到?”如果发现不足,系统会触发新一轮检索或改写问题再查。

这里我强烈建议:反思不要只依赖大模型自己的感觉,最好配合打分规则。比如,如果答案里缺少数字实体但问题中包含时间或数值,就触发重查;如果两个片段对同一事实说法矛盾,则追加一次对比检索。规则和模型结合,比单纯让模型“自己判断一下”稳得多。

3. 落地时最常见的几种Agentic RAG模式

3.1 路由模式:一条Query选择最合适的知识源

路由模式是成本最低、见效最快的Agentic RAG改造。它不改变现有RAG的检索和生成,只是在入口加一个“分流器”:用户查询先进模型,模型输出一个路由决策,然后根据决策把查询发往不同知识源。

我在一个具体的模拟项目里实现过两个知识源拆分:一个放标准化产品文档,另一个放客服工单记录。最初所有查询都同时走两个库,返回结果经常是文档和工单拼接在一起,前后风格完全不像。后来加了路由,Prompt只让模型输出两个词,product_docs或support_tickets,实测之后回答的连贯性好了很多。

这个小改动背后的原理是:不同知识源有各自的语域和覆盖范围,混合召回看似“什么都有”,实际是“什么都不精”。路由让每个知识源只处理它真正擅长的问题,噪声自然减少。

3.2 查询改写模式:把模糊的问题变成明确的条件

用户问题往往高度口语化、充满隐含表达。查询改写的目标,不是简单地“换一个说法”,而是扩展和澄清查询背后的多个可能方向。

举个例子,用户问:“这家餐馆怎么样?”这句话直接去检索,结果一定很飘。查询改写之后,可能会变成三个子查询:“这家餐馆的菜品口碑”“这家餐馆的价格是否合理”“这家餐馆的环境和排队情况”。三个子查询分别去检索,再把结果汇总,最后生成的答案就能覆盖多个维度。

这个模式早期有一个很流行的叫法叫“多查询生成”,有些人也把它和“假设性文档嵌入”混着用:先用一个小模型生成一个假想的答案文档,再用这个假想的文档去和库里的文档做匹配。在实际项目里,多查询更常用,因为它实现简单,只需要在代码里拆分列表,然后循环执行现有检索函数就行。

查询改写有一条核心经验:改写方向不能凭空想象,要让模型基于已有的知识切片去提候选问题。没有依据的改写,就像猜谜,最后检索出来的内容通常也不在线。

3.3 子问题分解与递归检索:真正解决多跳问题

如果你遇到的最棘手Case都是“要先搞清A,才能拿到B,最终要回答C”这种多跳问题,那就要上子问题分解模式。

我几年前处理过一个典型多跳查询:“甲公司的售后退款政策里,对超过30天提交的申请是怎么处理的?”要回答这个问题,需要先定位“甲公司售后政策”这个文档片段,再在其中找“退款申请时限”相关条款。放在传统RAG里,一次检索经常只命中“售后退款政策”却没有抓到“30天时限”,因为这两个信息在同一个文档的不同段落,相似度计算时被排名一起压制了。

子问题分解的做法是:先让Agent拆出两个子问题——“甲公司的售后政策文本是什么”和“其中超过30天申请的处理规则是什么”,然后先检索第一个子问题,拿到段落A,再把段落A和第二个子问题的组合检索,最终才生成结论。这里的递归检索质量远高于一次性大TopK,因为它每一步都带着上一步的已知信息继续收敛。

递归检索有一个必须注意的控制点:子问题的数量不宜超过3个。我实测拆出4个子问题时,最后拼接生成的内容会发散,因为每个子问题都消耗一段上下文,而大模型在长上下文里对信息的利用率并不均衡。

3.4 RAG-Fusion与重新排序:让多路结果合并出新答案

RAG-Fusion的思路是:对同一个问题,同时执行多个不同检索策略,然后把各路结果合并后再让模型生成。比如,可以同时走向量检索、关键词检索、SQL轻量过滤三条路径,分别拿到排名列表,再做融合重排。

最常见也最简单的融合算法是倒数排名融合。它不依赖得分绝对值,而是根据每份列表的排名位置给分。原因很简单:不同检索方式的分数尺度不一样,向量相似度是0到1的小数,关键词命中的权重则可能很大,直接用原始分数相加会不公平。按排名算分则绕开了尺度问题,所有检索结果都在同一标准下竞争。

融合之后的结果并不完美,由于多路来源的文本可能存在语义重复或互相矛盾,合并完还需要一道重排,让有价值的片段排在前面,然后才进入生成阶段。这一步是锦上添花,但对稳定性的提升非常直观。

4. 从零搭建一个最小可用的Agentic RAG系统

4.1 技术选型与总体架构

有些朋友一听到“Agent”就以为要上多复杂的框架,其实最小系统完全可以用纯代码实现,核心就是一个函数调用循环。

总体架构是这样:一个LLM入口负责意图判断,两个工具函数分别负责向量检索和SQL查询,一个循环控制器负责处理“继续”或“停止”信号。选型上,LLM用常规的对话模型就行,向量库用常见解决方案都差不多,SQL操作也不需要额外引入重型框架。

我的建议是:前期不要引入复杂的Agent框架或者可视化的编排平台,先在代码里把“选工具、调用工具、把结果加回上下文、再次判断”这个循环写清楚,你会更明白底层发生了什么。框架虽然好用,但会把你和核心逻辑隔开,出问题反而不好排查。

4.2 核心代码结构与关键实现

下面给一个极简的Agentic RAG实现,省略了工程上的异常处理,只保留最重要的循环逻辑。这里我用两个工具做演示:search_docs负责向量库检索,query_db负责查结构化订单数据。

from typing import Callable, Dict, List import json class MinimalAgent: def __init__(self, llm, tools: Dict[str, Callable]): self.llm = llm self.tools = tools def run(self, user_query: str, max_steps: int = 5): messages = [{"role": "user", "content": user_query}] for step in range(max_steps): response = self.llm.chat( messages=messages, tools=[ { "name": "search_docs", "description": "在知识库中检索文档片段", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "检索关键词或句子"} }, "required": ["query"] } }, { "name": "query_db", "description": "查询结构化订单数据,只支持精确条件过滤", "parameters": { "type": "object", "properties": { "customer_id": {"type": "string", "description": "用户编号"}, }, "required": ["customer_id"] } } ] ) tool_calls = response.get("tool_calls") if not tool_calls: return response["content"] messages.append(response) for call in tool_calls: fn_name = call["function"]["name"] args = json.loads(call["function"]["arguments"]) result = self.tools[fn_name](**args) messages.append({ "role": "tool", "tool_call_id": call["id"], "content": json.dumps(result, ensure_ascii=False) }) raise RuntimeError("超过最大步数,没有生成最终答案")

这段代码的逻辑很直白:

  1. 把用户问题放进消息列表。
  2. 让模型输出一个动作。
  3. 如果模型没有调用工具,说明它认为已经有足够信息,直接输出答案。
  4. 如果模型调了工具,就执行工具,把结果作为一条tool消息加回对话中,让模型在下一轮参考工具结果继续决策。

这里的“妙”之处在于:工具返回的结果不是替代用户问题,而是作为“新的上下文证据”加入对话。模型会看到原问题、自己的判断、工具返回的内容,然后综合决定下一步。这种模式也被称为“ReAct循环”,理解它对后面学习更复杂框架非常有帮助。

在实际项目中,search_docs的返回结果通常长这样:一个包含文本片段、来源文件名、页码、相似度分数的列表。你可以在工具函数内部就做好截断和格式化,避免把大段JSON全塞回给模型。我的经验是,每个片段最多留300字,来源信息用一行摘要,否则工具返回消息会变得很臃肿,模型反而不容易抓到重点。

4.3 数据准备与评测指标

Agentic RAG对数据质量的要求比传统RAG更高。因为Agent会主动调用多个工具,如果知识库本身切块质量差、埋点信息缺失,再聪明的规划器也没法检索到想要的答案。

做数据准备时,我习惯按“最小语义单元”来切块,而不是按固定字数切。举例来说,一段合同文本可能包含甲方的义务、乙方的义务、违约责任三个不同的语义块,每块300字左右比一个固定512字符的窗口合理得多。对于结构化数据,则要保证表字段名和业务含义在Prompt里能对得上,否则LLM填工具参数时会出现“猜字段名”的情况。

评测方面,我给自己定过一套简单实用的指标,推荐给新手:

  • 回答覆盖率:标准答案中涉及的关键信息点,有多少出现在模型回答里,权重大概占60%。
  • 引用准确率:回答里标出的引用来源是否真的包含对应信息,这个指标在知识库场景特别重要,因为AI制造幻觉的第一高发区就是引用。
  • 路由准确率:针对有知识源路由的场景,统计实际路由目标和预期是否一致,这个能帮你判断入口意图识别是否可靠。

评测集不用太大,三类问题各准备30条就够了。但有一个关键动作:跑出错误Case之后,把失败记录保存成回归集,每次改动路由或改写逻辑都重跑一遍。没有回归集的Agent项目,改一个参数就会引入一堆不可预期的新错误。

5. 实际项目里踩过的坑与避坑经验

5.1 上下文失控:把整个检索历史全塞给模型

我最早做Agentic RAG时踩的最大坑,是每次工具返回后,把上一轮的完整检索结果、工具输出、解析日志全部拼进新的Prompt。结果跑到第三步,模型已经忘记最初的问题是什么了,开始围绕工具输出自我发散,生成的内容像在复述文档而不是回答问题。

后来我把上下文改成“只保留最近两轮摘要”:第一轮工具输出会做信息压缩,第二轮再检索时,Prompt里只放一个问题、一个工具结果的精简摘要、一个待生成指令。系统效果稳定很多,Token消耗也明显下降。

这条经验可以总结成一句话:Agent循环不是堆料越多越好,而是上下文越精炼越好。工程上要专门写一个摘要函数,对工具返回结果做二次压缩,而不是让原始输出直接进入下一轮。

5.2 工具参数“可空但关键”:路由到空知识源疯狂重试

还有一个印象深刻的问题:某一次上线后,日志里出现大量“调用query_db返回空结果,Agent继续重新生成查询条件”的现象。原因是模型在填参数时,没有校验字段一定是非空,导致它经常拿一个空的ID去查数据库。查回来是空表,Agent就换个参数再查,陷入了无意义的循环。

排查方法是给工具函数加上“空结果就明确报错”的约束,并且在Prompt里强调:“如果参数缺少必要字段,不要自行猜测,先向用户确认。”这听起来很基础,但没有这个约束,模型会产生大量无效工作,对实时接口尤其伤。

5.3 评测的“自我感觉良好”陷阱

还有一次,我在内部测试集上的回答准确率做到了85%,感觉很满意,但一到线上就发现用户反馈很差。调查后发现:测试集的80多条问题里,有超过一半的句子结构和表达套路非常接近,模型的回答质量是被这种重复性数据“抬上去”的。

后来我专门做了“表达扰动测试”:把同一道问题的表达换五六种说法,比如把“张三在哪家公司”改成“你知道张三的雇主是谁吗”。结果准确率直接掉了将近20个点。这说明模型很多时候是在“熟悉问题句式”而不是“真的理解了需求”。

评测一定不能只看答案内容,更要看“问题表达变化后,系统是否还能稳定回答”。表达扰动方法是成本最低、最容易发现Agent系统脆弱点的测试手段。

5.4 成本与延迟控制

Agentic RAG每多一轮工具调用,就多一次LLM调用,Token开销成倍增长。一个需要3轮检索的复杂问题,往往要花掉5到8次模型交互,而传统RAG只需要一次。

控制成本有几个实操技巧:

  • 设置硬性最大步数,5轮还出不了结果的直接降级成普通RAG回答,别让系统无限跑。
  • 轻量意图路由用小的分类模型,只有真正需要复杂推理的问题才进入完整Agent循环。
  • 缓存高频问题的检索结果。同一个查询内容,如果向量结果一致性很高,就可以直接复用上一轮的工具输出,不用再调一次模型来判断。

我见过有人把Agentic RAG的Effectiveness和Cost混为一谈,觉得“能搜就多搜几次”,导致单个请求成本比普通RAG高好几倍,最后项目被叫停。先把成本兜住,再谈效果,才是落地的思路。

6. 给新手的几条上手建议

不要一上来就追求“全知全能的Agent”。我的建议是,先动手写一个最简单的循环:一个工具、一个模型、一个判断分支,能回答一个问题就行。在这个基础上,再逐步加入路由、改写、多路召回。每加一个模块,就回归一次之前踩过的Case,守住质量的底线。

我曾经用整整两周时间,只做了一个“查询改写+子问题分解”的Agent流程,没有加任何复杂框架。那两周的收获比后来两周研究新架构更多,因为我真正理解了每一步里数据是怎么流动的、模型为什么要这样决策,以及哪些环节可以交给代码规则去控制。

还有一个经验想多说一句:Agentic RAG本质上是工程问题,不是算法问题。很多效果不佳的Case,根源不在模型不够聪明,而在路由规则混乱、工具接口模糊、检索片段质量参差。把工程的坑填好,复杂度已经解决大半。

最后分享一个小技巧:在每个工具函数内部,记录一条结构化日志,内容包括调用参数、返回数量、耗时、是否空结果。这个日志平时看着不起眼,但当线上反馈出现问题时,它能帮你快速定位是路由跳错、检索不到、还是生成发散。我靠着这套日志,在模拟项目和线上项目里排查问题的时间减少了一半以上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 13:13:05

open-code-review:可版本控制的代码审查范式

1. “open-code-review”不是新工具,而是代码审查范式的悄然迁移最近在几个技术群和开源项目讨论区里,反复看到“open-code-review”这个词被提起——它既不像 GitHub 的 Pull Request Review 那样具象,也不像 SonarQube 那样有明确的 UI 和 …

作者头像 李华
网站建设 2026/10/19 13:12:18

工业物联网平台架构设计与实操落地:从设备接入到业务闭环的完整指南

1. 工业物联网平台到底在解决什么问题第一次接触“工业物联网平台”这个词,很多人脑子里浮现的可能是“把设备连上网”这么简单。但真到车间里走一圈就会发现,设备联网只是最表层的一步,真正难的是联网之后怎么办。一台数控机床每分钟产生几千…

作者头像 李华
网站建设 2026/10/19 13:12:17

电商售后AI客服实践:KoalaQA如何将重复咨询量降低78%

前几天翻后台数据,KoalaQA 上线第三个月的报表里,重复性咨询占比从上线前的 41% 掉到了 9%,整体重复性咨询量环比少了 78%。我在几个同行的社群里同步了这个数字,大家第一反应都是“是不是把用户都气走了”。其实不是,…

作者头像 李华
网站建设 2026/10/19 13:12:13

Hadoop生态核心组件详解:存储、计算、调度与数据管理

第一次系统性接触Hadoop生态,大多数人都会被那一长串工具名吓到:HDFS、YARN、MapReduce、Spark、Hive、HBase、ZooKeeper、Flume、Sqoop、Oozie……我当年也是这样,光是搞明白“Hadoop到底是一个东西还是一堆东西”就花了不少时间。说白了&am…

作者头像 李华
网站建设 2026/10/19 13:11:10

open-code-review:基于Git+CLI+LLM的开放协作式代码审查范式

1. 什么是 open-code-review:一个被严重低估的开发者协作新范式open-code-review 不是一个工具名,也不是某个开源项目的代号,而是一套正在快速成型的、以“开放”为内核的代码审查实践体系。它不是替代传统 PR Review 的流程,而是…

作者头像 李华
网站建设 2026/10/19 13:11:05

墙面瓷砖缺陷检测数据集:裂缝与脱落识别实战

墙面瓷砖出了裂缝或者脱落这种事,住进去再发现就已经晚了,施工方和业主来回扯皮,返工成本高到离谱。而现有的人工验收,靠的是监理拿肉眼蹲在墙根下一块砖一块砖地看,效率低不说,漏检率还高得看当天光线和心…

作者头像 李华