递归顾问
什么是递归顾问?
递归顾问是一种特殊类型的顾问,它可以多次遍历下游的顾问链。这种模式在需要反复调用 LLM 直到满足某个条件时非常有用,例如:
-
在循环中执行工具调用,直到不再需要调用任何工具
-
验证结构化输出,如果验证失败则重试
-
实现评估逻辑,包含对请求的修改
-
实现重试逻辑,包含对请求的修改
CallAdvisorChain.copy(CallAdvisor after) 方法是实现递归 Advisor 模式的关键工具。它创建一个新的 Advisor 链,其中仅包含原始链中位于指定 Advisor 之后的所有 Advisor,并允许递归 Advisor 根据需要调用这个子链。这种方法确保了:
-
递归顾问可以在链中循环遍历剩余的顾问
-
链中的其他顾问可以观察并拦截每次迭代
-
顾问链保持正确的排序和可观察性
-
递归顾问不会重新执行其之前的顾问
内置递归建议器
Spring AI 提供了两个内置的递归顾问(recursive advisor)来演示这种模式:
ToolCallAdvisor
ToolCallAdvisor 将工具调用循环作为 advisor 链的一部分来实现,而不是依赖模型的内部工具执行机制。这使得链中的其他 advisor 能够拦截并观察工具调用过程。
主要功能:
-
通过设置
setInternalToolExecutionEnabled(false)来禁用模型的内部工具执行 -
循环遍历顾问链,直到不再出现工具调用
-
支持“直接返回”功能——当工具执行设置了
returnDirect=true时,它会中断工具调用循环,并将工具执行结果直接返回给客户端应用程序,而不是将其发送回给 LLM -
使用
callAdvisorChain.copy(this)为递归调用创建子链 -
包含空安全检查,以处理聊天响应可能为空的情况
示例用法:
var toolCallAdvisor = ToolCallAdvisor.builder()
.toolCallingManager(toolCallingManager)
.advisorOrder(BaseAdvisor.HIGHEST_PRECEDENCE + 300)
.build();
var chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(toolCallAdvisor)
.build();
返回直接功能
"return direct" 功能允许工具绕过 LLM,将结果直接返回给客户端应用程序。这在以下场景中尤为实用:
-
该工具的输出即为最终答案,无需LLM处理
-
为避免额外的LLM调用,需要降低延迟
-
工具结果应原样返回,无需解释
当工具执行具有 returnDirect=true 时,ToolCallAdvisor 将:
-
正常执行工具调用
-
检测
ToolExecutionResult中的returnDirect标志 -
跳出工具调用循环
-
将工具执行结果直接作为
ChatResponse返回给客户端应用程序,其中工具的输出作为生成内容
StructuredOutputValidationAdvisor
StructuredOutputValidationAdvisor 会根据生成的 JSON 模式验证结构化的 JSON 输出,如果验证失败,将在指定的尝试次数内重试调用。
关键特性:
-
根据期望的输出类型自动生成 JSON 模式
-
根据模式验证 LLM 响应
-
如果验证失败,会重试调用,最多可配置尝试次数
-
在重试时,通过向提示中添加验证错误信息来帮助 LLM 纠正其输出
-
使用
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();