Agent架构师从0出发(第9篇):从RAG到Agent——检索增强与行动决策的融合与边界

20 阅读10分钟

一、引言

走到第8篇,RAG初级阶段的8篇文章画上了句号。从分块策略的隐性代价,到检索优化的工程代价,再到RAG技术演进、KV Cache、Prefix Caching,最后到检索质量优化的系统方法论,这条技术曲线已经完整覆盖了传统向量RAG(NativeRAG)从架构设计到质量优化的全链路。

但它不是终点。在实际的金融投研场景中,一个很现实的问题反复出现:如果RAG已经能回答问题,为什么还需要Agent?

答案在于,RAG解决的是“知道什么”,Agent解决的是“能做什么”。一个典型的投研任务,比如“分析某公司近三年毛利率变化并对比同行”,需要Agent规划步骤、依次调用多个工具、汇总生成报告——RAG无法独立完成。RAG是知识增强,Agent是行动决策。二者不是替代关系,而是互补关系。

本文开启Agent阶段。主线有三条:厘清RAG与Agent的本质关系,复盘Function Calling的生产级实践,给出工程检查清单。

二、RAG与Agent的本质关系:金融投研场景下的分工

2.1 工程误区一:把Agent当成“会调用工具的RAG”

常见认知是:Agent = RAG + Function Calling。

在金融投研场景中,这个认知很快会碰壁。RAG是“知识检索与生成”,Agent是“多步骤决策与行动编排”。一个典型投研任务需要Agent先规划步骤,再依次调用工具,最后汇总生成报告。例如分析某公司近三年毛利率变化并对比同行,需要先查财报数值,再查研报观点,再拉行情数据,最后做对比分析。这个流程中,RAG只能完成其中“查研报观点”这一步,无法独立完成整个任务。

2.2 工程误区二:以为RAG可以替代Agent的推理能力

另一个常见认知是:只要知识库够全,RAG就能回答一切。

在金融投研场景中,这个认知的瓶颈也很明显。RAG无法执行动作,比如拉行情、调估值模型;无法多轮规划;无法根据中间结果调整策略。例如某公司财报缺失时,Agent可以改用其他数据源或调整分析维度,RAG只能返回“未找到”。这种动态调整能力,是Agent区别于RAG的核心。

2.3 正确的关系模型:RAG是Agent的“知识工具”,Agent是RAG的“行动编排者”

RAG为Agent提供私有知识、实时信息、长尾事实。Agent为RAG提供多步推理、工具编排、动态决策、人机协同。融合形态是Agentic RAG:Agent自主决定何时检索、检索什么、如何整合检索结果。

在这个关系模型下,RAG本身也在分化,形成三种形态,它们与Agent的关系各不相同。

NativeRAG,也常被称为NaiveRAG或传统向量RAG,是最原始的RAG形态。它的流程是线性的:文档分块、Embedding、向量入库、检索TopK、拼入Prompt、生成答案。它没有查询改写,没有多轮检索,没有质量评估。它适合事实型问题,比如“某公司CEO是谁”“某产品市场占有率多少”。在Agent体系中,NativeRAG是Agent最基础的知识工具,负责“查事实”。

AgenticRAG是在NativeRAG基础上增加了Agent决策循环的形态。Agent自主判断是否需要检索、检索什么、要不要补充检索、信息是否充分。它不是一次检索定生死,而是边查边想,不够再查。在Agent体系中,AgenticRAG本身就是Agent的一种工作模式,是Agent编排检索能力的体现。

GraphRAG是在检索层增加了知识图谱的形态。它先抽取实体和关系构建图谱,再沿图结构做多跳推理。它适合处理关系密集型问题,比如“A公司营收下滑是否受其子公司B拖累,B的亏损如何传导到母公司”。在Agent体系中,GraphRAG是Agent工具箱里的一种关系推理工具,Agent判断需要关系推理时调用它,需要事实检索时调用NativeRAG,需要精确数值时调用Text-to-SQL。

三者不是替代关系,而是包含关系。AgenticRAG可以调用NativeRAG,也可以调用GraphRAG,也可以调用Text-to-SQL。GraphRAG是Agent工具箱里的一种专业工具,而NativeRAG是Agent工具箱里最基础的事实检索工具。

关于AgenticRAG和GraphRAG现在只大概提一下,引出一个概念,后续会有专门的文章进行说明

三、工具调用的生产级契约设计:从“能跑通”到“可信赖”

3.1 工具描述过于笼统,模型不知道何时调用

常见写法是description写“天气相关功能”。在金融投研场景中,对应的问题是query_financial_metrics(查财报数值)与search_research_reports(查研报观点)语义重叠。用户问“某公司最近业绩怎么样”,模型在边界输入下可能选错。

生产实践是在description中明确互斥场景,比如“问具体数值用前者,问分析师观点用后者”,或者在上层增加意图识别节点。

3.2 参数类型设计与业务约束脱节

常见写法是时间范围参数定义为"type": "string",description写“格式为YYYY-MM-DD”。在金融投研场景中,真实问题是模型有时返回"2024-01-01",有时返回"去年",有时返回时间戳。Pydantic校验通过,但业务层解析失败。

生产实践是能用enum约束的绝不用string;时间范围使用结构化设计,比如start_dateend_date;系统注入参数如tenant_id不暴露给模型。

3.3 工具返回值设计忽视Token预算

常见写法是工具返回什么就原样回填。在金融投研场景中,真实问题是query_financial_metrics返回某公司近5年20个季度全部财务数据,回填后Token预算被占满,模型无法生成有效分析。

生产实践是工具返回值必须做截断或摘要;结构化返回值优于大段文本;大数据量查询返回分页令牌;工具注册表增加max_output_tokens元数据。

3.4 消息历史完整性:协议契约不可妥协

常见错误是只追加了tool结果,忘记先把assistant消息(含tool_calls)加入历史。错误现象是"messages with role 'tool' must have a preceding assistant message with tool_calls"

金融投研场景中多轮工具调用是常态,比如查财报、查行情、查研报、生成报告,消息历史完整性更加关键。正确顺序是:system → user → assistant(含tool_calls) → tool(结果) → assistant(最终回复)

四、工具执行的可靠性设计:异常、重试与审计

4.1 错误分类与策略

瞬时错误如行情API超时、研报服务速率限制,由系统自动重试。LLM可恢复错误如参数解析失败、工具不存在,转为错误ToolMessage回填,让模型自行调整。用户可修复错误如缺失公司代码、时间范围不明确,暂停并等待人工介入。过度调用如模型反复查询同一数据,限制调用次数。

4.2 指数退避重试与幂等性

常见写法是工具抛异常直接中断,没有重试。生产实践是@retry_on_failure(max_retries=3, backoff_factor=1.0),使用functools.wraps保留元数据。

金融场景特别注意:行情和财报查询是幂等的,可安全重试;生成报告、发送邮件、提交订单等非幂等操作不应自动重试。

4.3 结构化错误返回

常见写法是直接返回"Error",模型无法自我修正。生产实践是错误信息必须包含statuscodemessageretryablesafe_to_answer_userdata_source。模型看到retryable: true会建议用户稍后再试;看到safe_to_answer_user: true知道可以转述。

4.4 审计日志:成功和失败都要记录

常见缺失是只记录成功,不记录失败,线上出问题无法定位。金融投研场景的审计日志必须记录request_iduser_idtool_nameargs_snapshotdata_sourceerror_typeduration_msfinal_status。核心价值是故障排查、合规审计、数据溯源。

4.5 调用次数限制防止死循环

常见场景是模型反复调用同一个失败工具,Token费用飙升。生产实践是设置MAX_TOOL_CALLS_PER_RUN = 10(投研任务通常需要更多步骤),超出后强制终止并返回友好提示。

五、并行调用与权限控制:性能与安全的平衡

5.1 并行工具调用

常见写法是只用顺序执行,没考虑并发。金融投研场景的价值在于同时查询多家公司的同一指标,顺序执行2.5秒,并行只需0.6秒。

生产实践是async with asyncio.TaskGroup() as tg创建任务组,await asyncio.to_thread(func, **arguments)将同步函数放入线程池。风险是下游数据API速率限制,需要设置并发上限5到10个;严格模式与并行调用不兼容,需设置parallel_tool_calls=False

5.2 权限控制:金融数据隔离

常见缺失是没有权限概念,任何用户都可以调用任何工具。金融投研生产实践必须引入RBAC,用户角色决定可调用工具列表。

角色与权限映射:admin可调用全部工具,analyst只读工具且无估值模型修改权限,guest仅公开信息查询。权限校验在路由层统一拦截;权限信息必须来自系统上下文即Token,绝不能来自模型输出。租户级数据隔离要求不同基金公司只能查询自己权限范围内的研报库。权限审计日志记录user_idroletool_nameallowedreason。拒绝比成功更需要审计。

六、工程检查清单

  • □工具返回值是否配置截断如max_output_tokens,是否标注数据来源和时间戳,大数据量查询是否返回分页令牌
  • □消息历史是否强制包含assistant(tool_calls)再追加tool结果,多轮对话中是否保留完整对话链
  • □重试机制是否区分幂等操作,非幂等操作如生成报告、发邮件是否有补偿机制或人工确认
  • □审计日志是否包含user_idrequest_idtool_nameargsdurationstatusdata_source,是否满足合规留存
  • □权限校验是否在路由层统一拦截,权限来源是否系统上下文而非模型输出,是否实现租户级数据隔离
  • □并行调用是否使用TaskGroup,是否在任务内捕获异常,是否设置并发上限与单工具超时

七、总结

第8篇为RAG画上阶段性句号,第9篇开启Agent工程化起点。

RAG与Agent在金融投研中的融合边界是:RAG是知识增强,Agent是行动决策;RAG作为Agent的工具,Agent编排RAG实现Agentic RAG。GraphRAG作为关系推理工具,在多跳推理、全局摘要、可解释路径、隐性关联识别上比原生RAG更有优势,是Agent工具箱中的重要补充。

核心心得是:模型只能“建议”,系统必须“守门”;模型输出永远不可信,边界校验和权限控制必须由宿主程序完成。