从朴素到智能:Agentic RAG如何重构复杂检索与数据工程实践
根据当前的市场反馈,多数公司的AI应用仍停留在使用Coze、Dify等平台搭建基础知识库的阶段。因此,若能深入掌握上述任一主题,在求职市场上便已具备显著优势。
然而,若希望进入专注于“真AI应用”的团队,或应对技术深度要求更高的面试,仅掌握单一知识点可能显得不足。此时,将Agent与RAG两者融合的 Agentic RAG 概念便应运而生,它能显著提升系统的智能化水平。
Agentic RAG 自诞生之初,便被视为一种更高级的解决方案,随之而来的一种常见论调是 “RAG已经过时”。
就在昨日的一次AI闭门讨论会上,这一观点再次出现:一位资深投资人士在推崇Agent的同时,不自觉地质疑RAG的价值。但若深入追问其参与过哪些深度RAG项目,往往又无法得到实质性的答案。
尽管如此,我们仍需厘清当前所谓的 “RAG过时论”究竟指什么。本质上,大语言模型仅具备输入和输出接口,任何在输入前对问题进行干预处理的过程,广义上均可被视作RAG的范畴。从这个角度看,RAG作为一种范式本身并不过时。
重新审视“RAG过时论”
技术迭代中,不好用的方法被淘汰是共识。这里所指的“过时”,通常是针对前几年兴起的 “朴素RAG” 模式: 进行一次向量检索,将Top-K的文本块直接塞入提示词,最终导致“垃圾进,垃圾出”。
这种模式最突出的问题是上下文割裂:在对原始文档进行分块时,破坏了文本的完整性,例如切分了表格、打断了论证逻辑,最终导致信息丢失。
于是,一个自然的疑问产生:既然分块导致问题,而如今模型上下文窗口极大(百万级上下文也即将普及),是否可以将整个文档直接交给模型,从而避免分块?
答案可能并非如此。虽然长上下文可以缓解因分段造成的语义割裂,但背后的检索效率与精度问题依然存在,因此分块仍是必要步骤,主要原因如下:
主流文本嵌入模型有其最佳的编码长度(通常是中等长度)。将一本数万令牌的书籍编码成一个向量,就如同用一句话概括全书,大量细节必然丢失,导致检索精度急剧下降。这一点或许需要进一步解释:
每个基座模型都提供嵌入接口,它并不关心输入量的大小,无论是200字还是2万字,最终都会将其压缩为一个向量。结果是:输入文本越长,承载信息越多,压缩就越剧烈,生成的向量往往更“平均化”,从而导致检索分辨率降低。
信息在传递过程中具有扩散和压缩的特性,并非越多越好,可参考下图:

正因如此,工程领域出现了许多技术进行“迁就”,例如《树搜索RAG系统:PageIndex》所介绍的方法。

然而,当文档结构化做到这种程度时,我们完全可以为每个子文档先归类,再为其生成一段摘要描述。当问题到来时,可先通过穷举匹配进入具体类型,再利用小型模型判断摘要的相关性,这种方法效率很高,有时甚至可以不再依赖向量数据库。
因此,在真实场景中,向量数据库并非唯一选择,多种技术常常混合使用。
随着智能体需求的激增,模型侧对智能体的基础支持进行了大量优化,包括提出了MCP、Skills等概念。可以说,工具链中最令人头痛的问题已得到相当程度的解决;明年,模型很可能在记忆侧发力,给出更优秀的工程策略。
举例来说,理想的知识数据处理流程是:将文档全量喂给某个智能知识库,当进行知识检索时,该智能知识库能够给出准确答案。过去,大家使用向量数据库进行语义检索,但效果不佳,需要叠加大量工程技术才能勉强实现。后来人们发现,小型模型配合结构化知识库也能完成语义检索,何必非用向量数据库?于是,整个工程范式发生了很大变化。
如何将这类复杂的工程技术内化并封装,如何将向量检索技术内置到模型黑盒中,这可能是下一代模型技术需要突破的命题之一。
在大致解释了何为“过时的RAG”(尽管我们并不完全清楚批评者具体所指)之后,让我们回归到Agentic RAG的主题。
Agentic RAG:定义与核心理念
为了获得更好的AI应用体验,我们在工程层面进行了诸多优化,包括:多源知识整合、更动态的上下文验证、与外部工具的深度融合等。
当Agent概念兴起后,大家发现可以利用计算成本(Token)来换取架构的简化,通过多次循环迭代的增量成本,来解决工作流泛化的工程难题。
于是,便有先行者思考,是否可以引入 Agentic RAG 的概念,使其能够进行精细的计划、多步骤推理,并充分利用外部工具来处理复杂问题。
总而言之,所有冠以“Agent”之名的技术,其出现都是为了降低工程复杂性,是一种用(计算)时间换取(系统)架构简化的范式。
Agentic RAG的核心工作是:在多个文档和数据源之间比对信息、提炼总结,从而产出全面且准确的答案。换言之,它实现了从被动检索到主动推理的转变,将静态的问答过程升级为动态、智能的知识探索过程……
注:可以看到,但凡沾上“Agent”字样,描述就显得颇为玄妙。
下图展示了传统RAG(上)与Agentic RAG(下)的流程对比:

Agentic RAG采用循环迭代流程:引入Agent对查询进行分析和决策,例如决定是查询内部知识库还是进行网络搜索,然后对检索结果的相关性进行评分。如果结果不理想,Agent会改写查询重新检索。如此反复,直到收集到足够有用的上下文,再由大语言模型生成可靠答案。
换句话说:Agentic RAG 是一种泛化能力很强的工作流架构,能够让模型自主获取更优质的数据。
我知道大家可能仍有些困惑,让我们看一个之前的实际案例。
从实践案例看传统RAG的局限
成都某大型律师事务所曾有一个需求:
在审阅一份800页的跨境并购协议时,需要快速定位数十个关键条款(如赔偿、终止、担保、知识产权转移等),并对每个条款的风险点进行初步分析。一位资深律师完成全面审阅需要40-50小时。
他们的负责人询问能否用10万元预算通过AI解决。我回答可以,并且付诸实践,也“解决了”问题。只不过,系统的可扩展性不高,毕竟10万元的预算不可能打造出一个Harvey(知名法律AI)级别的产品。
初期,我们尝试了一种基于Dify的标准方案:
- 文档处理:将PDF合同转换为文本,按固定长度(如512字符)进行重叠分块。
- 向量化:使用Dify的知识库功能自动处理分块与嵌入。
- 检索:用户提问时,召回相似度最高的Top-5个文本块。
- 生成:将文本块与问题拼接,提交给GPT-4生成答案。
实际效果堪称灾难:
一、关键条款信息丢失
一些“条款”可能跨越3-5页,包含定义、范围、限额、除外情形等多个部分。固定长度的分块会将其切割成5-6段,导致每段语义都不完整。
二、表格数据丢失
合同附录中包含大量表格,通常需要转换为Markdown格式。如果未做处理或处理不当,表格会被切碎,模型可能只看到表头或零星数据。
三、引用混乱
模型常常自信地引用“第523页第2段”,但实际上该页讨论的是完全不同的内容。甚至出现过引用页码超出了文档总页数的情况。
四、图片信息缺失
这一点无需多言,图片未经特殊处理(如转化为Markdown并添加描述),信息几乎全部丢失。
五、答案一致性差
针对同一问题在不同时间提问,得到的答案和引用来源完全不同,完全无法用于正式的法律意见书。只要错一处,律师便会怀疑所有结果的可靠性。
……
上述问题都有成熟的工程解法,而根源在于过于粗暴的数据处理流程:
原始文档(800页PDF)
↓
文本提取(800页纯文本)
↓
机械分块(每512字符切一块,共约1500个块)
↓
向量化(1500个向量存入向量数据库)
↓
流程结束。
实现Agentic RAG:一个结构化工作流示例
要让Agentic RAG效果出众,必须在数据输入侧下功夫。核心是不再将文档视为“一堆文字”,而是当作“有结构的对象”来处理。以下是一个概念性的数据结构示例:
# Agentic RAG 的数据存储本质上是层次化、多模态的
document_structure = {
“metadata”: {
“doc_id”: “contract_001”,
“title”: “并购协议”,
“total_pages”: 800,
“version”: “1.0”
},
# 第一层:目录(存储在关系型数据库中)
“toc”: [
{“chapter”: 1, “title”: “定义”, “pages”: “1-5”},
{“chapter”: 8, “title”: “赔偿条款”, “pages”: “45-62”},
{“chapter”: 8.2, “title”: “赔偿范围”, “pages”: “47-52”},
{“chapter”: 8.2.2, “title”: “间接损失”, “pages”: “48-50”},
{“chapter”: 8.3, “title”: “赔偿限额”, “pages”: “53-58”}
],
# 第二层:章节摘要(向量+文本混合存储)
“chapter_summaries”: {
“8.2.2”: {
“vector”: [0.12, 0.34, …], # 摘要的向量表示
“summary”: “本节规定间接损失的赔偿条件:需可合理预见且在30日内书面通知。”,
“key_entities”: [“间接损失”, “合理预见”, “30日”],
“relevance_score”: None # 在运行时计算
}
},
# 第三层:详细内容(按需进行向量化)
“detailed_chunks”: {
“8.2.2_para1”: {
“vector”: [0.45, 0.67, …], # 仅在查询时生成向量
“text”: “8.2.2 间接损失赔偿。尽管有第8.2.1条规定…”,
“page”: 48,
“chunk_type”: “正文”
},
“8.3_table1”: {
“vector”: None, # 表格不进行向量化,特殊处理
“type”: “table”,
“data”: [[“损失类型”, “上限比例”], [“间接损失”, “50%”], …],
“page”: 56
}
},
# 第四层:交叉引用图(存储在图数据库中)
“references”: {
“8.2.2”: [“8.1.6”, “8.3”, “8.4.3”], # 指向其他条款
“8.3”: [“8.2.2”, “附录D”]
}
}
可以看到,这种数据处理方式与前述的PageIndex有相似之处,但其维护成本极高。
简而言之,无论哪种RAG,要想效果好,都必须对数据进行精细处理。甚至80%的工作量都在数据处理环节,Agentic RAG 本身并无太多神秘之处。
换言之,如果Agentic RAG 不能最终解决数据处理成本过高的问题,那它也仅是空中楼阁。
这里需要补充一点:Agentic RAG的核心优势,在于数据已经得到良好处理的前提下,能够更充分地利用这些数据。理解这一点后,我们便能更客观地看待Agentic RAG的意义:在相同数据质量下,它能呈现出更优的表现,但基础的数据建设工作依然不可或缺,否则效果必然大打折扣。
在确保基础数据质量的前提下,便可真正实施Agentic RAG:即模拟真实律师工作的标准作业流程。
将SOP转化为Agentic RAG工作流
首先强调:Agentic RAG 并非简单的“再检索一次”,而是将“检索”打造成一个可控的、多步骤的流程。只要将此SOP跑通,便基本掌握了其精髓。因此,关键在于剖析真人如何工作,再用代码予以实现。
一位资深律师处理问题时,通常会遵循以下步骤: 澄清问题边界 → 定位相关章节 → 逐层深入细节 → 处理交叉引用 → 提取原文作为证据链 → 在最终撰写前核对证据 → 若证据不足则返回第二步继续查找,绝不凭空编造。
Agentic RAG 要做的,正是将上述SOP编码化。例如,可以将系统拆解为五个“角色”(或称Skills):
- 路由Agent:负责决策应先查看哪些章节或数据源(仅做决策,不生成答案)。
- 导航Agent:按照“章节 → 条款 → 段落”的层次逐级深入,缩小检索范围。
- 证据收集Agent:从缩小的范围内抽取带有精确定位信息(如页码、文本区间)的证据片段。
- 引用验证Agent:检查“引用是否存在、得出的结论是否被证据充分支持”。
- 写作Agent:将组织好的证据链转化为可供律师参考的结论与风险提示。
让我们以一个具体查询为例:“本协议对间接损失(indirect damages)是否赔偿?如果赔偿,条件是什么?是否有赔偿上限(cap/basket)?请提供可引用的页码。”
第一步:输入理解与问题拆解 首先将复杂问题拆解为3个子问题(这一步至关重要):
- Q1:间接损失是否被允许或排除?
- Q2:如果允许,具体的赔偿条件是什么?
- Q3:赔偿上限或门槛是多少?
第二步:第一轮路由决策 路由Agent不阅读正文,仅依据预存的结构化目录和摘要信息,输出一个简洁的决策:
{
“route”: [
{“node”: “8.2.2”, “why”: “直接命中间接损失规则”, “confidence”: 0.92},
{“node”: “8.3”, “why”: “上限/门槛通常在限额条款或表格中”, “confidence”: 0.88}
],
“stop_condition”: “证据必须覆盖 Q1-Q3,且每条结论均需有可引用来源”
}
这一步避免了传统向量检索的随机性,因为搜索空间被限制在“章节树”的特定分支上。
第三步:信息逐层下钻 进入“8.2.2”章节后,导航Agent将范围从“章节”缩小到具体的“可读段落”。
- 若8.2.2内容较短:直接提取全文。
- 若8.2.2仍然很长:继续按段落或子条款进行拆分。
此时,系统才会触发对
detailed_chunks中相关内容的按需向量化: - 仅对8.2.2章节内的段落生成嵌入向量(而非全量800页文档)。
- 同时,为每个段落带上精确的页码锚点(如page=48–50)。 由此得到候选证据片段:
- p48_s03:解释间接损失的范围。
- p49_s01:规定赔偿条件(如合理预见、30日内书面通知)。
- p50_s02:列出可能的例外情形。 这正是在输入侧做文章带来的收益:证据天然带有精确锚点,后续的引用不会“乱飞”。
第四步:补充与验证证据 对于Q3(上限/门槛),这类信息在合同中可能散落在正文或表格附件里。证据收集Agent需要明确的指令:对于数字型信息,优先查询表格附件,若未找到则查询正文。传统RAG在此处也是难点,它很难稳定地将表格中的某个特定单元格召回至Top-K结果中。
第五步:构建关系链
这是最为关键的一步,它决定了最终答案的全面性。Agent需要判断并检索原文中通过references引用的相关条款是否也需要被包含进来。
第六步:数据组装 最终,为LLM准备的结构化证据数据可能如下所示:
{
“evidence”: [
{“id”:”E1”,”node”:”8.2.2”,”page”:48,”span”:”p48_s03”,”text”:”…间接损失…”},
{“id”:”E2”,”node”:”8.2.2”,”page”:49,”span”:”p49_s01”,”text”:”…合理预见…30日内书面通知…”},
{“id”:”E3”,”node”:”8.3”,”page”:56,”span”:”8.3_table1_row2”,”text”:”间接损失 上限比例 50%”},
{“id”:”E4”,”node”:”8.3”,”page”:53,”span”:”p53_s02”,”text”:”…aggregate cap…”}
],
“coverage”: {“Q1”: true, “Q2”: true, “Q3”: true}
}
在数据准备充分后,交由写作Agent生成最终答案,此过程不再赘述。
总结与展望
撰写此文颇具挑战,因为在我们当初解决实际问题时,并未刻意使用“Agentic RAG”这一标签,而是应用了大量常规且复杂的工程技术。
事实上,笔者查阅了许多资料,试图寻找关于“什么是Agentic RAG”的清晰定义和典型案例,但发现合适的描述寥寥无几。与业内多位同行交流后,下图或许能较好地说明其工程发展方向:

Agentic RAG 的工程演进路径是:将数据接口做细 → 封装成一系列工具/技能(Skills/Agents) → 通过 ReAct 等框架让模型自主决定调用哪些技能及调用顺序。
其关键在于:将复杂的RAG流程拆解为一系列定义明确、功能单一的技能,然后通过一个协调框架(如ReAct),让大语言模型自身充当“调度员”,动态决定何时、以何种顺序调用这些技能来逐步解决查询。
这也可能是Agentic RAG当前面临的最大挑战或问题所在:这些技能本身可能是一个“黑盒”。例如,若一个医疗或法律领域的Agent需要对外提供API,其内部复杂的数据验证、证据链追溯等逻辑将变得非常复杂。
换言之,这类专业领域Agent工具的核心复杂度,不在于工具数量的多少,而在于工具必须提供可追溯、可校验的证据服务。现阶段,“Skills”是一个被广泛采纳的优秀实现范式,它解决了许多工程集成问题,值得开发者持续关注。