Agent RAG 流水线设计:工具增强检索与多跳推理

· 系列: Agent Knowledge and Grounding · 阅读时间: 25 分钟

⚡ 30 秒核心要点

  • Agent RAG ≠ 传统 RAG:Agent 是检索的主动消费者,能调用工具、规划多步推理,而非被动查询。
  • 工具增强检索:通过 API 调用、数据库查询、代码执行等工具,突破静态知识库的限制,获取实时与结构化数据。
  • 多跳推理:将复杂问题分解为多个子查询,每跳结合工具结果进行推理,形成可追踪的推理链。
  • 工程化要点:工具集设计、错误处理、性能监控与上下文管理是 Agentic RAG 落地的四大支柱。

Agent RAG 与传统 RAG 的核心区别

传统 RAG(Retrieval-Augmented Generation)通常是一个 被动、单向 的流水线:用户查询 → 向量检索 → 拼接上下文 → 生成回答。整个过程是静态的,检索结果完全依赖于预先索引的知识库。而 Agent RAG 将 LLM Agent 置于核心位置,Agent 不仅消费检索结果,还能主动决定 何时检索、检索什么、以及如何利用工具进一步获取信息

一个典型区别在于 迭代性和动态性。传统 RAG 无法处理"如果第一轮检索结果不足怎么办"的问题;而 Agent RAG 可以发起多轮查询,甚至调用外部工具来验证假设或获取缺失信息。例如,用户询问"对比 2025 年 Q3 和 Q4 的销售数据,并分析增长原因",传统 RAG 只能从文档中找静态片段,而 Agent RAG 可以调用数据库工具、执行 SQL 查询、再结合知识库中的业务背景进行综合推理。

传统 RAG 流程: query → embed → vector search → top-k chunks → LLM generate

Agentic RAG 流程: query → agent planner → [retrieve | call_tool | compute] → reason → ... → final answer

对于 AI/ML 工程师而言,理解这一区别至关重要,因为它彻底改变了系统设计范式。你需要从"构建一个检索器"转变为"构建一个 推理代理,它具备检索、工具使用和规划能力"。这也意味着你的架构必须支持动态循环、状态管理和工具调用的失败恢复。

深度阅读:若想进一步了解 Agent 如何利用记忆机制增强检索上下文,可参考 Agent 记忆系统设计

工具增强检索的核心概念

工具增强检索(Tool-Augmented Retrieval) 是指 Agent 在检索过程中调用外部工具来获取 非结构化知识库 之外的信息。这些工具可以是:

  • API 调用:如天气查询、股票价格、地图服务。
  • 数据库查询:通过 SQL 或 NoSQL 访问实时业务数据。
  • 代码解释器:执行 Python 代码进行数值计算或数据分析。
  • 搜索 API:调用 Bing/Google 搜索获取最新网页内容。
  • 知识图谱查询:从图数据库检索实体关系。

核心价值在于 弥补静态索引的不足。知识库无法覆盖所有实时或私有数据,而工具提供了按需获取的能力。设计工具增强检索时,关键在于 工具的描述与参数定义。Agent 需要理解每个工具的功能、适用场景和参数格式,才能正确调用。

// 工具定义示例 (JSON Schema)
{
  "name": "query_sales_db",
  "description": "查询销售数据库,支持按季度、产品类别筛选",
  "parameters": {
    "type": "object",
    "properties": {
      "quarter": { "type": "string", "enum": ["Q1", "Q2", "Q3", "Q4"] },
      "category": { "type": "string", "description": "产品类别,例如 Electronics" }
    },
    "required": ["quarter"]
  }
}

在实现上,需要将工具封装为函数,并注册到 Agent 的可用工具列表中。检索流程不再是单一的向量搜索,而是 混合决策:Agent 根据问题判断是直接向量检索,还是先调用工具获取数据,再将数据作为上下文。这要求流水线具备 动态路由 能力。

想了解工具调用的底层设计模式,请参阅 Agent 工具设计

多跳推理架构设计

多跳推理(Multi-Hop Reasoning) 要求 Agent 将复杂问题分解为多个子问题,逐步检索和推理,最终汇聚答案。每个"跳"(hop)可能涉及一次检索、一次工具调用或一次逻辑推导。架构设计上,通常采用 规划-执行-反思 循环。

1. 规划 (Plan)

Agent 分析问题,生成推理路径。例如:"先查询用户最近的订单,再查询物流状态,最后结合退货政策给出建议"。

2. 执行 (Execute)

按计划调用工具或检索器,收集每跳的结果。每步结果可能成为下一步的输入。

3. 反思 (Reflect)

Agent 检查中间结果是否满足需求,必要时修正计划,重新执行或终止。

实现多跳推理的关键技术是 中间状态管理。你需要维护一个"工作记忆"(working memory),存储已获取的信息、已执行的操作和当前推理状态。这通常通过上下文窗口或外部记忆模块实现。例如,使用一个 JSON 结构保存中间变量:

{
  "current_hop": 2,
  "plan": ["fetch_user_profile", "query_recent_orders", "check_refund_policy"],
  "results": {
    "user_id": "U12345",
    "orders": ["ORD-987", "ORD-988"],
    "policy": "30-day return window"
  },
  "next_action": "synthesize_answer"
}

这种架构的挑战在于 错误传播:如果某一跳的工具返回错误或信息不完整,后续推理可能失败。因此,设计时需要引入 校验节点,在每个跳后验证结果质量。此外,设定最大跳数(如 5 跳)防止无限循环。

关于上下文管理的更深入讨论,请参考 Agent 上下文窗口管理

Agent 工具集的设计与管理

工具集是 Agent RAG 流水线的"武器库"。设计不良的工具集会导致 Agent 无法有效检索或推理。以下是关键设计原则:

4.1 工具粒度与抽象

工具不宜过细(如"获取用户名字"),也不宜过粗(如"处理所有数据")。推荐粒度是 业务可理解的操作,例如"获取用户最近订单"、"计算退货截止日期"。每个工具应有清晰的描述和参数约束,减少 Agent 的误用。

4.2 工具注册与 Schema

使用 JSON Schema 定义工具,并维护一个工具清单。Agent 在每次推理前会看到所有可用工具的描述。为了节省 Token,可以考虑 动态工具子集选择:根据查询意图,只暴露相关的工具。

tools = [
  Tool(name="search_web", description="搜索最新网页内容", parameters={...}),
  Tool(name="query_internal_docs", description="检索内部知识库", parameters={...}),
  Tool(name="run_sql", description="执行只读 SQL 查询", parameters={...}),
  Tool(name="calculate", description="执行数学计算", parameters={...})
]

4.3 工具调用的权限与安全

在生产环境,工具调用可能访问敏感数据。必须实现 细粒度权限控制:每个工具定义允许的角色或数据范围。同时,对于写操作(如发送邮件)需要二次确认机制。建议添加 审计日志,记录每次工具调用的输入输出,便于追溯。

4.4 工具版本与兼容性

工具 API 会升级,Agent 的提示词可能依赖旧工具的描述。建议采用 工具版本管理,在 Agent 配置中锁定工具版本。当工具行为变化时,需要重新评估 Agent 的推理质量。

更全面的工具设计模式,请阅读 Agent 工具设计

端到端 Agentic RAG Pipeline 实战

现在,我们将概念落地为一个可运行的端到端流水线。以下是一个简化但完整的 Python 示例,展示了 Agent 如何结合检索与工具调用。

from typing import List, Dict
import json

class AgenticRAGPipeline:
    def __init__(self, llm, vector_store, tools):
        self.llm = llm
        self.vector_store = vector_store
        self.tools = {t.name: t for t in tools}
        self.max_hops = 4

    def run(self, query: str) -> str:
        plan = self.plan(query)
        context = []
        for hop in range(self.max_hops):
            action = self.choose_action(query, plan, context)
            if action['type'] == 'retrieve':
                docs = self.vector_store.search(action['query'])
                context.append({'hop': hop, 'type': 'retrieve', 'data': docs})
            elif action['type'] == 'tool':
                tool = self.tools[action['tool_name']]
                result = tool.execute(action['params'])
                context.append({'hop': hop, 'type': 'tool', 'data': result})
            elif action['type'] == 'answer':
                return self.llm.generate(query, context)
            else:
                return "Unable to answer"
        return "Max hops reached"

    def plan(self, query):
        # 实际应用中通过 LLM 生成计划
        return ["retrieve_initial", "maybe_tool"]

    def choose_action(self, query, plan, context):
        # 简化决策:根据上下文状态选择动作
        if len(context) == 0:
            return {'type': 'retrieve', 'query': query}
        elif len(context) == 1:
            return {'type': 'tool', 'tool_name': 'search_web', 'params': {'q': query}}
        else:
            return {'type': 'answer'}

这个示例虽然简化,但体现了核心循环:Agent 在每步决定是检索、调用工具还是直接回答。实际生产系统中,你需要使用更强大的规划器(如 ReAct 或 Plan-and-Solve 模式),并且将每个步骤的 输入输出记录到日志 中。

5.1 关键实现细节

  • 查询重写:在每跳开始时,使用 LLM 将原始查询改写为更具体的子查询。
  • 结果融合:将工具结果与向量检索结果合并,去重并排序。
  • 上下文压缩:由于 Token 限制,每跳结果需要压缩,只保留关键信息。
  • 停止条件:当 Agent 认为已有足够信息回答时,停止循环。

上下文协议设计对于 Agent 与工具之间的数据交换至关重要,推荐阅读 Agent 上下文协议设计

性能优化与错误处理

Agentic RAG 流水线的性能瓶颈通常在于 延迟Token 消耗。多跳推理意味着多次 LLM 调用和工具调用,需要系统性优化。

6.1 延迟优化

  • 并行工具调用:如果多跳之间无依赖,可以并行调用工具。
  • 缓存:对相同的工具请求(如重复查询)进行缓存。
  • 模型选择:使用快速小模型进行规划,用大模型进行最终答案生成。

6.2 Token 成本控制

  • 上下文压缩:只保留检索片段中的关键句子。
  • 动态工具集:避免每次请求都发送所有工具的描述。
  • 最大跳数限制:设置合理的最大推理步数。

6.3 错误处理策略

错误类型处理策略
工具超时重试一次,若仍失败,尝试替代工具或告知用户
工具返回格式错误解析异常时,将原始输出附加到上下文,让 LLM 判断
检索结果为空触发工具调用(如搜索 API)补充信息
推理陷入循环设置最大步数,超时后返回部分答案

实现健壮的错误处理,需要为每个工具定义 失败回调。例如,当 SQL 查询失败时,Agent 可以自动切换到文档检索。

常见陷阱与最佳实践

根据多个生产项目的经验,以下是 Agentic RAG 最常见的陷阱以及对应的最佳实践。

⚠️ 陷阱一:工具描述不准确

Agent 选错工具或参数错误。最佳实践:为每个工具编写多轮测试用例,确保 LLM 能正确调用。

✅ 最佳实践:工具描述中加入"何时使用"

例如:"当用户询问天气时,使用此工具;否则不要使用。" 这能显著提高工具选择准确率。

⚠️ 陷阱二:忽略中间结果验证

多跳推理中,某一跳的错误结果会污染后续推理。最佳实践:每个跳后增加简单的验证步骤。

✅ 最佳实践:引入"反思"步骤

在每跳后让 LLM 评估"当前信息是否足够?" 如果不够,则继续检索。

⚠️ 陷阱三:上下文爆炸

每跳都追加完整结果,导致 Token 超限。最佳实践:使用滑动窗口或摘要技术压缩历史。

✅ 最佳实践:设置上下文预算

为每跳分配固定的 Token 预算,超限则截断或摘要。

此外,强烈建议在开发环境中使用 可观测性工具,追踪每次工具调用的输入输出、延迟和 Token 消耗。这有助于快速定位问题。

企业级落地方案

在企业环境中,Agentic RAG 需要满足安全性、可扩展性和治理要求。以下是关键落地考量:

8.1 安全与合规

  • 敏感数据脱敏:工具返回的数据需经过脱敏处理,例如隐藏身份证号。
  • 审计追踪:记录所有 Agent 的工具调用,便于合规审查。
  • 隔离环境:对于高权限工具(如删除操作),使用单独的环境运行。

8.2 可扩展性架构

将流水线设计为 无状态服务,使用消息队列(如 Kafka)处理大量请求。Agent 的状态(如当前推理步骤)存储在 Redis 中,实现水平扩展。

# 伪代码:可扩展的 Agent 服务
def handle_request(request_id, query):
    state = redis.get_state(request_id)
    if not state:
        state = init_state(query)
    while not state.is_finished():
        action = agent.decide(state)
        result = execute_action(action)
        state.update(result)
        redis.save_state(request_id, state)
    return state.final_answer

8.3 监控与告警

  • 核心指标:平均跳数、工具成功率、端到端延迟、Token 消耗。
  • 质量指标:人工评估回答准确率,定期抽样。
  • 告警规则:当工具失败率超过 5% 或平均跳数超过 3 时触发告警。

在多 Agent 协作场景中,每个 Agent 可能拥有不同的 RAG 配置,此时需要协调机制。可参考 多 Agent 编排

常见问题

Q1: Agent RAG 和传统 RAG 的检索结果有何不同?

传统 RAG 只返回知识库中的静态片段;Agent RAG 可以返回工具调用结果(如实时数据库记录)、多轮检索的聚合信息,以及经过推理生成的中间结论。这使得 Agent RAG 能回答需要实时数据或跨文档综合的复杂问题。

Q2: 如何决定使用工具还是向量检索?

经验法则是:如果问题需要 实时数据私有业务数据计算,优先使用工具;如果问题是 常识性、文档型 问题,使用向量检索。更高级的做法是让 LLM 根据问题描述自动选择,但需要精心设计工具描述。

Q3: 多跳推理会不会导致 Token 消耗过高?

会的。优化方法包括:限制最大跳数(通常 3-5 跳)、使用小模型进行规划、压缩每跳的上下文、缓存重复的工具结果。另外,可以设置"提前停止"策略,当答案置信度足够高时停止推理。

Q4: 工具调用失败时,Agent 应如何恢复?

推荐采用 降级策略:首先重试一次;若仍失败,则尝试替代工具(如从数据库查询改为文档检索);如果所有替代方案都失败,Agent 应明确告知用户"暂时无法获取该信息",而不是编造答案。

Q5: 如何评估 Agentic RAG 流水线的质量?

建议从三个维度评估:最终答案准确率(人工评分)、工具调用正确率(是否选对工具、参数是否正确)、推理效率(平均跳数和延迟)。可以构建一个包含 200+ 个问题的评测集,覆盖不同难度。

Q6: Agent RAG 适合所有场景吗?

不一定。对于简单的事实性问题,传统 RAG 更快速、成本更低。Agent RAG 适合需要 多步骤分析、实时数据、工具交互 的复杂场景。建议在架构中设计"路由层",根据查询复杂度决定是否启用 Agent 模式。

下一步阅读

你已经掌握了 Agentic RAG 流水线的核心设计。接下来,建议按以下路径深入学习与实践:

  • 1. 构建最小原型

    使用 Python + LangChain 或自研代码,实现一个包含 2-3 个工具的多跳 RAG 流水线。

  • 2. 扩展工具集

    添加数据库查询、API 调用等真实工具,并设计工具评估集。

  • 3. 深度阅读相关主题

    阅读 Agent 记忆设计上下文协议,完善知识体系。

  • 4. 性能优化与监控

    实现缓存、并行调用、日志追踪,并建立质量评估体系。