【Spring AI】 2.0升级指南一

发布时间:2026/7/19 19:13:12
【Spring AI】 2.0升级指南一 第一章Advisors顾问层重构Advisor 是 Spring AI 中用于在 ChatClient 调用前后插入横切逻辑的组件类似 AOP 中的拦截器。2.0.0 版本对 Advisor 的组织结构和行为进行了重要调整。1.1 模块更名与搬迁变更点原模块/类新模块/类原因spring-ai-advisors-vector-storespring-ai-vector-store-advisor统一命名规范ToolSearchToolCallingAdvisor位于spring-ai-tool-search-tool独立模块spring-ai-tool-search-advisor包路径变更为org.springframework.ai.chat.client.advisor.toolsearch职责分离更清晰的模块边界迁移操作!-- 更新依赖 --dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-tool-search-advisor/artifactId/dependency// 更新导入语句// 之前importorg.springframework.ai.tool.toolsearch.advisor.ToolSearchToolCallingAdvisor;// 之后importorg.springframework.ai.chat.client.advisor.toolsearch.ToolSearchToolCallingAdvisor;1.2 ToolSearchToolCallingAdvisor 自动配置登场2.0.0 为ToolSearchToolCallingAdvisor提供了全新的 Spring Boot 自动配置和 Starter使其能够自动替换默认的ToolCallingAdvisor实现按需筛选工具定义。工作原理是否用户提问ChatClient是否启用ToolSearchAdvisor?工具索引搜索仅将最相关的工具定义发送给LLM大语言模型发送所有工具定义开启方式# 启用 ToolSearchToolCallingAdvisor spring.ai.chat.client.tool-search-advisor.enabledtrue # 选择索引类型regex默认无需额外依赖、lucene、vector spring.ai.chat.client.tool-search-advisor.tool-index-typeregex索引类型说明类型依赖要求适用场景regex无基于关键词正则匹配轻量快速luceneorg.apache.lucene:lucene-core需要更强大的文本检索能力vectorVectorStoreBean spring-ai-vector-store语义相似度搜索最智能1.3 关键变更Advisor 执行顺序调整背景在一个典型的 AI 对话中ToolCallingAdvisor工具调用顾问和ChatMemoryAdvisor记忆顾问需要协同工作。如果顺序不当可能导致工具调用过程中的中间消息被错误地存入长期记忆。变更内容Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER从HIGHEST_PRECEDENCE 1000调整为HIGHEST_PRECEDENCE 200ToolCallingAdvisor的默认顺序为HIGHEST_PRECEDENCE 300执行顺序示意执行优先级ChatMemoryAdvisor优先级: -2147483348ToolCallingAdvisor优先级: -2147483248ChatMemoryAdvisor优先级: -2147483148注数值越小越先执行HIGHEST_PRECEDENCE -2147483648设计意图ToolCallingAdvisor现在默认在内部管理工具调用迭代期间的对话历史而ChatMemoryAdvisor只存储最终的用户/助手对话记录不会将工具调用消息写入ChatMemoryRepository。这是因为大多数存储实现不支持这些特殊消息类型。如果需要记忆工具调用过程例如使用InMemoryChatMemoryRepositoryvartoolCallingAdvisorToolCallingAdvisor.builder().disableInternalConversationHistory()// 关闭内部历史管理.build();varchatMemoryAdvisorMessageChatMemoryAdvisor.builder(chatMemory).advisorOrder(Ordered.HIGHEST_PRECEDENCE400)// 明确指定顺序.build();第二章工具调用Tool Calling机制革新工具调用是让 LLM 能够调用外部函数/API 的核心能力。2.0.0 对此机制进行了深度重构。2.1 移除internalToolExecutionEnabled——为何不再需要手动控制旧模式的问题在 1.x 中您可以通过internalToolExecutionEnabled(false)来退出框架的自动工具执行转而自己控制循环。但这种设计造成了困惑——框架既提供了自动执行又允许部分手动控制职责边界模糊。新设计哲学工具执行的自动/手动控制不再由ChatOptions中的标志位决定而是由是否使用ToolCallingAdvisor来区分手动模式 - 高级用户有工具调用无工具调用ChatModel.call检查 hasToolCallsToolCallingManager手动执行再次调用 ChatModel返回最终结果自动模式 - 推荐ChatClientToolCallingAdvisor自动注册工具自动执行循环由框架管理迁移方式// 之前——在选项中控制ChatOptionsoptionsToolCallingChatOptions.builder().toolCallbacks(ToolCallbacks.from(newMyTools())).internalToolExecutionEnabled(false)// ← 删除这一行.build();// 之后——通过 Advisor 控制// 自动模式什么都不用做ToolCallingAdvisor 自动生效// 手动模式不加 ToolCallingAdvisor自行驱动循环2.2 新增ToolExecutionEligibilityChecker——更灵活的执行条件判断用途决定在何种条件下继续执行工具调用循环。旧的ToolExecutionEligibilityPredicate结合了选项标志位检查和响应检查职责混杂。新的ToolExecutionEligibilityChecker是一个纯粹的函数式接口专注于判断响应是否应该触发下一轮工具调用。自定义检查器示例针对特定 Provider 的 finishReasonToolCallingAdvisoradvisorToolCallingAdvisor.builder().toolExecutionEligibilityChecker(response-response!nullresponse.hasToolCalls()!stop.equals(response.getResult().getMetadata().getFinishReason())).build();Spring Boot 用户可以直接声明一个 Bean自动配置会拾取它BeanToolExecutionEligibilityCheckermyChecker(){returnresponse-response!nullresponse.hasToolCalls();}2.3 新增全局开关spring.ai.chat.client.tool-calling.enabled# 全局禁用自动工具执行工具定义仍会发送给 AI但不会自动执行 spring.ai.chat.client.tool-calling.enabledfalse这与在每个调用上使用AdvisorParams.toolCallingAdvisorAutoRegister(false)效果相同但作用范围是全局的。2.4 移除streamToolCallResponses——修复设计缺陷问题根源当streamToolCallResponsestrue时工具调用请求的中间块会被流式下传但对应的ToolResponseMessage发回给 LLM 的响应却不会被流式下传。如果下游有记忆 Advisor 记录这些块就会收到有请求无响应的不完整历史导致对话记录损坏。修复方式直接移除该选项。如需观测工具调用的每一次迭代请手动控制循环// 禁用自动注册手动驱动循环ChatClientResponseresponsechatClient.prompt().user(question).options(chatOptions).advisors(AdvisorParams.toolCallingAdvisorAutoRegister(false)).call().chatClientResponse();while(response.chatResponse()!nullresponse.chatResponse().hasToolCalls()){// 在这里可以检查或转发工具调用块ToolExecutionResultresulttoolCallingManager.executeToolCalls(prompt,response.chatResponse());// ... 继续循环}