收藏本站,收获最前沿的人工智能与编程资讯!!

Spring AI 递归顾问 Recursive Advisors

技术文档 45℃ 0

递归顾问

什么是递归顾问?

递归顾问是一类特殊的顾问,能够多次循环遍历下游的顾问链。当你需要重复调用大语言模型(LLM)直至满足特定条件时,这种模式非常实用,典型场景包括:

  • 循环执行工具调用,直到无需再调用任何工具
  • 校验结构化输出,若校验失败则重新尝试
  • 实现附带请求修改的评估逻辑
  • 实现附带请求修改的重试逻辑

CallAdvisorChain.copy(CallAdvisor after) 方法是实现递归顾问模式的核心工具。它会创建一个新的顾问链,该子链仅包含原链中指定顾问之后的所有顾问,并允许递归顾问根据需要调用这个子链。这种方案能够保证:

  • 递归顾问可以循环遍历链中剩余的顾问
  • 链中的其他顾问能够监听并拦截每一次循环迭代
  • 顾问链保持正确的执行顺序和可观测性
  • 递归顾问不会重新执行其自身之前的顾问

内置递归顾问

Spring AI 提供了两个内置的递归顾问,用于演示该模式:

ToolCallAdvisor(工具调用顾问)

ToolCallAdvisor 将工具调用循环作为顾问链的一部分实现,而非依赖模型内部的工具执行能力。这使得链中的其他顾问可以拦截并监听工具调用的全过程。

核心特性:

  • 通过设置 setInternalToolExecutionEnabled(false) 禁用模型内部的工具执行
  • 循环遍历顾问链,直到不存在待执行的工具调用
  • 支持“直接返回”功能——当工具执行配置 returnDirect=true 时,会中断工具调用循环,并将工具执行结果直接返回给客户端应用,而非回传给大语言模型
  • 使用 callAdvisorChain.copy(this) 创建子链以实现递归调用
  • 包含空值安全校验,处理聊天响应可能为空的场景
  • 支持通过 conversationHistoryEnabled 配置会话历史管理

使用示例:

var toolCallAdvisor = ToolCallAdvisor.builder()
    .toolCallingManager(toolCallingManager)
    .advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 300)
    .build();

var chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(toolCallAdvisor)
    .build();

会话历史管理

ToolCallAdvisor 包含一个配置选项,用于控制工具调用迭代过程中会话历史的管理方式。

默认情况下(conversationHistoryEnabled=true),该顾问会在工具调用迭代期间内部维护完整的会话历史。这意味着工具调用循环中每一次后续的大语言模型调用,都会包含所有历史消息(用户消息、助手响应、工具响应)。

可通过 .disableMemory() 方法禁用内部会话历史管理。禁用后,仅会将最后一条工具响应消息传递给下一次迭代。适用于以下场景:

  • 你已在顾问链中注册了聊天内存顾问,由其负责管理会话历史
  • 你希望避免重复管理历史,减少令牌消耗
  • 你需要与外部会话内存系统集成

禁用会话历史的示例:

var toolCallAdvisor = ToolCallAdvisor.builder()
    .toolCallingManager(toolCallingManager)
    .disableMemory()  // 禁用内部历史管理 - 交由 ChatMemory 处理
    .advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 300)
    .build();

var chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory)
    .advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 200)  // 优先级高于 ToolCallAdvisor
    .build();

var chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(chatMemoryAdvisor, toolCallAdvisor)
    .build();

直接返回功能

“直接返回”特性允许工具绕过大语言模型,将结果直接返回给客户端应用。适用于以下场景:

  • 工具输出即为最终答案,无需大语言模型处理
  • 你希望避免额外的大语言模型调用,降低延迟
  • 工具结果需要原样返回,无需二次解析

当工具执行配置 returnDirect=true 时,ToolCallAdvisor 会执行以下逻辑:

  1. 正常执行工具调用
  2. ToolExecutionResult 中检测到 returnDirect 标记
  3. 跳出工具调用循环
  4. 将工具执行结果直接以 ChatResponse 形式返回给客户端应用,工具输出作为生成内容

StructuredOutputValidationAdvisor(结构化输出校验顾问)

StructuredOutputValidationAdvisor 会根据生成的 JSON 模式校验大语言模型输出的结构化 JSON 数据,若校验失败则重新调用模型,最多重试指定次数。

核心特性:

  • 根据预期输出类型自动生成 JSON 模式
  • 基于 JSON 模式校验大语言模型的响应
  • 校验失败时重新调用模型,支持配置最大重试次数
  • 重试时将校验错误信息追加到提示词中,帮助大语言模型修正输出
  • 使用 callAdvisorChain.copy(this) 创建子链以实现递归调用
  • 可选支持自定义 ObjectMapper 用于 JSON 处理

使用示例:

var validationAdvisor = StructuredOutputValidationAdvisor.builder()
    .outputType(MyResponseType.class)
    .maxRepeatAttempts(3)
    .advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 1000)
    .build();

var chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(validationAdvisor)
    .build();

相关推荐