乐于分享
好东西不私藏

Spring AI 2.0.0 发布

Spring AI 2.0.0 发布

Spring AI 2.0.0 发布

Spring AI 2.0.0 正式版终于来了!这是一个具有里程碑意义的重大更新,带来了架构层面的优化、API的统一和性能的提升。下面让我们详细聊聊这五个最重要的变化。

准备

pom.xml 修改 Spring AI 版本号为 2.0.0

<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>2.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

注意:Spring AI 2.0.0 基于 Spring Boot 4.0 构建,确保你的项目使用对应的 Spring Boot 版本。

1. 工具调用彻底重构:移至 Advisor

这是 2.0.0 最重大的架构变更。

统一工具执行: 所有 ChatModel(OpenAI、Anthropic、Ollama、MistralAI、DeepSeek、Bedrock Proxy、MiniMax)中的内置工具执行循环调用。工具执行现在必须通过 ChatClient 配合 ToolCallingAdvisor(推荐)或通过ChatModel用户控制的 DefaultToolCallingManager 循环来处理。

ToolSearchToolCallingAdvisor 新增: 新增了 ToolSearchToolCallingAdvisor,支持三种 ToolIndex 实现(向量存储、Lucene、正则表达式),让 LLM 能够按需发现和调用工具,而不需要预先加载所有工具定义。

API 变更:

  • • ToolCallAdvisor 重命名为 ToolCallingAdvisor(旧类保留为已弃用的子类)
  • • 移除了 toolNames() API 和 SpringBeanToolCallbackResolver,必须使用显式的 ToolCallback Bean
  • • ChatClient.prompt().tools(...) 现在直接接受 ToolCallbackToolCallbackProvider、集合和数组
  • • 内存 Advisor 默认放置在 ToolCallingAdvisor 外部,内存顾问只存储最终的用户/AI消息,不将工具调用消息写入 ChatMemoryRepository

旧代码示例:

// 1.x 版本 - 工具调用内置在模型中ChatClientclient= ...;Stringresponse= client.prompt("查一下今天的天气")    .toolNames("weatherTool")    .call()    .content();

新代码示例:

// 2.0 版本 - 通过 ToolCallingAdvisor 处理ChatClientclient= ...;Stringresponse= client.prompt("查一下今天的天气")    .tools(newWeatherTool())    .call()    .content();

ToolSearchToolCallingAdvisor 按需搜索工具// 添加依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-tool-search-advisor</artifactId></dependency>
@BeanToolIndex regexToolIndex() {returnnewRegexToolIndex();}ToolSearchToolCallingAdvisorsmartToolRetrieverAdvisor= ToolSearchToolCallingAdvisor.builder()                .toolIndex(toolIndex)                .build();

2. 必须使用 conversationId

在 2.0.0 中,conversationId 对于内置 ChatMemoryAdvisor 来说不再是可选的。ChatMemory.CONVERSATION_ID 成为必须使用的标识,每次调用都必须通过上下文提供。

变更原因: 随着工具调用移至 Advisor 层,ToolCallingAdvisor 需要管理自己的中间对话历史。为了避免混乱,现在要求显式使用 conversationId 来标识不同的对话会话。

使用示例:

ChatClientchatClient= ChatClient.builder(chatModel)    .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())    .build();chatClient.prompt()    .user("Hello!")    .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "my-session"))    .call()    .content();

3. 模型调用改用官方 SDK

从 2.0.0-M5 开始,Spring AI 开始使用各模型厂商的官方 SDK。

OpenAI: 使用官方 openai-java SDK 处理所有 OpenAI 模型(Chat、Embeddings、Image、Audio Speech、Audio Transcription、Moderation)

Anthropic: 从 REST/WebClient 实现迁移到官方 Anthropic Java SDK

好处:

  • • 更好的兼容性和稳定性
  • • 更快获得新功能支持
  • • 更完善的错误处理
  • • 无需担心 API 变更导致的兼容性问题

迁移平滑: 对于 spring-ai-openai 模块的现有用户,过渡是无缝的,所有属性、构建器和选项保持完整。

注意:OpenAI接口,在1.x版本中,Spring AI通过completionsPath附加了/v1/chat/completions,使用新的SDK后,客户端期望base URL已经包含/v1,只附加chat/completions。

4. 取消温度默认值,使用模型厂商默认

重要变更: Spring AI 不再为温度(temperature)等参数设置默认值。未设置的选项现在会直接使用底层模型厂商的默认值。

原因: 这消除了一类微妙的 Bug——之前 Spring AI 的默认值可能会无声地覆盖模型厂商的值,导致行为不符合预期。

代码示例:

// 1.x 版本 - Spring AI 设置了默认温度 0.7ChatOptionsopts= OpenAiChatOptions.builder()    .build(); // 可能使用 Spring AI 的默认值,而不是 OpenAI 的// 2.0 版本 - 不设置则使用模型厂商默认varcustomizer= OpenAiChatOptions.builder(); // 不设置温度,使用 OpenAI 默认// 或者显式设置varcustomizer= OpenAiChatOptions.builder()    .temperature(0.7); // 显式设置才会覆盖

5. ChatOptions 处理方式变更

当使用ChatClient时,.options() / .defaultOptions() 方法现在接受一个ChatOptions.Builder(或任何特定提供者的子类型)而不是一个完全构建的ChatOptions实例。

旧代码:

// 1.x 版本ChatClientclient= ...;ChatOptionsopts= AnthropicChatOptions.builder()    .maxTokens(100)    .temperature(0.7)    .build();Stringresponse= client.prompt("Tell me a joke")    .options(opts)    .call()    .content();

新代码:

// 2.0 版本ChatClientclient= ...;varcustomizer= AnthropicChatOptions.builder()    .maxTokens(100)    .temperature(0.7);Stringresponse= client.prompt("Tell me a joke")    .options(customizer)    .call()    .content();

其他重要更新

  • • Jackson 3 迁移: Spring AI 现在使用 Jackson 3(tools.jackson 包)而不是 Jackson 2(com.fasterxml.jackson 包)
  • • MCP 注解移入核心: MCP 注解从 org.springaicommunity.mcp 移至 org.springframework.ai.mcp.annotation
  • • 日志框架统一: 替换 SLF4J 为 org.apache.commons.logging.LogFactory,与 Spring 生态保持一致
  • • 结构化输出增强: 为 ChatClient.entity() 添加了 EntityParamSpec,支持每次调用配置结构化输出

最后

Spring AI 2.0.0 是一次重大的架构升级,虽然带来了一些破坏性变更,但这些变化让框架更加统一、灵活和可维护。建议大家在升级前仔细阅读 官方升级文档

如果你有任何问题,欢迎在评论区留言!