Spring AI 1.x 系列【61】Spring AI 2.0 升级指南

文章目录

  • [1. 概述](#1. 概述)
  • [2. Advisor 变更](#2. Advisor 变更)
    • [2.1 模块重命名](#2.1 模块重命名)
    • [2.2 ToolSearchToolCallingAdvisor 独立为专用模块](#2.2 ToolSearchToolCallingAdvisor 独立为专用模块)
    • [2.3 Advisor 优先级默认值调整](#2.3 Advisor 优先级默认值调整)
  • [3. Tool Calling 变更](#3. Tool Calling 变更)
    • [3.1 移除 internalToolExecutionEnabled](#3.1 移除 internalToolExecutionEnabled)
    • [3.2 移除 ToolExecutionEligibilityPredicate](#3.2 移除 ToolExecutionEligibilityPredicate)
    • [3.3 新增 spring.ai.chat.client.tool-calling.enabled 属性](#3.3 新增 spring.ai.chat.client.tool-calling.enabled 属性)
    • [3.4 移除 streamToolCallResponses](#3.4 移除 streamToolCallResponses)
  • [4. Options 及配置变更](#4. Options 及配置变更)
    • [4.1 Options 严格不可变](#4.1 Options 严格不可变)
    • [4.2 默认值移至 Options 构造函数](#4.2 默认值移至 Options 构造函数)
    • [4.3 配置属性扁平化](#4.3 配置属性扁平化)
    • [4.4 N() 重命名为 n()](#4.4 N() 重命名为 n())
    • [4.5 ChatClient Options 现在接受 Builder](#4.5 ChatClient Options 现在接受 Builder)
    • [4.6 移除默认 Temperature 配置](#4.6 移除默认 Temperature 配置)
  • [5. JSON 工具类重构](#5. JSON 工具类重构)
    • [5.1 新增 JsonHelper](#5.1 新增 JsonHelper)
    • [5.2 JsonParser 废弃](#5.2 JsonParser 废弃)
    • [5.3 ModelOptionsUtils JSON 方法移除](#5.3 ModelOptionsUtils JSON 方法移除)
    • [5.4 McpJsonParser 删除](#5.4 McpJsonParser 删除)
  • [6. MCP SDK 变更](#6. MCP SDK 变更)
    • [6.1 Elicitation API:TypeReference 替换](#6.1 Elicitation API:TypeReference 替换)
    • [6.2 构造器必填字段](#6.2 构造器必填字段)
    • [6.3 Builder API 废弃](#6.3 Builder API 废弃)
    • [6.4 MCP 注解迁移至 Spring AI](#6.4 MCP 注解迁移至 Spring AI)
    • [6.5 MCP Spring Transport 模块迁移](#6.5 MCP Spring Transport 模块迁移)
    • [6.6 MCP Client Customizer API 统一](#6.6 MCP Client Customizer API 统一)
    • [6.7 服务端工具输入校验默认开启](#6.7 服务端工具输入校验默认开启)
    • [6.8 `Tool.inputSchema` 返回类型变更](#6.8 Tool.inputSchema 返回类型变更)
    • [6.9 MCP WebMvc Transport Header 小写标准化](#6.9 MCP WebMvc Transport Header 小写标准化)
  • [7. Chat Memory 变更](#7. Chat Memory 变更)
    • [7.1 Conversation ID 现在必填](#7.1 Conversation ID 现在必填)
    • [7.2 `getConversationId` 签名变更](#7.2 getConversationId 签名变更)
    • [7.3 PromptChatMemoryAdvisor 删除](#7.3 PromptChatMemoryAdvisor 删除)
    • [7.4 JDBC Chat Memory 新增 `sequence_id` 列](#7.4 JDBC Chat Memory 新增 sequence_id 列)
    • [7.5 MongoDB Chat Memory 排序修正](#7.5 MongoDB Chat Memory 排序修正)
    • [7.6 Conversation History 从 ToolContext 移除](#7.6 Conversation History 从 ToolContext 移除)
  • [8. 模型模块变更](#8. 模型模块变更)
    • [8.1 Anthropic 模块:切换至官方 Java SDK](#8.1 Anthropic 模块:切换至官方 Java SDK)
    • [8.2 Ollama:属性重命名](#8.2 Ollama:属性重命名)
    • [8.3 OpenAI:切换至官方 openai-java SDK](#8.3 OpenAI:切换至官方 openai-java SDK)
    • [8.4 Minimax、Azure OpenAI、OpenAI SDK、OCI GenAI 模块删除](#8.4 Minimax、Azure OpenAI、OpenAI SDK、OCI GenAI 模块删除)
    • [8.5 `buildRequestPrompt` 从公开 API 移除](#8.5 buildRequestPrompt 从公开 API 移除)
    • [8.6 Model 内部方法访问级别变更](#8.6 Model 内部方法访问级别变更)
  • [9. 模块及依赖变更](#9. 模块及依赖变更)
    • [9.1 移除的模块](#9.1 移除的模块)
    • [9.2 OpenSearch 依赖升级](#9.2 OpenSearch 依赖升级)
    • [9.3 Development-time Services](#9.3 Development-time Services)
  • [10. 其他变更](#10. 其他变更)
    • [10.1 Google GenAI Embedding 包变更](#10.1 Google GenAI Embedding 包变更)
    • [10.2 ChatClient 自动注册 ToolCallingAdvisor](#10.2 ChatClient 自动注册 ToolCallingAdvisor)
    • [10.3 移除 ToolSpec Consumer API](#10.3 移除 ToolSpec Consumer API)
    • [10.4 Spring Bean Tool Resolution 删除](#10.4 Spring Bean Tool Resolution 删除)
    • [10.5 BeanOutputConverter JSON Schema 变更](#10.5 BeanOutputConverter JSON Schema 变更)
    • [10.6 Observability 属性调整](#10.6 Observability 属性调整)
    • [10.7 统一缓存用量指标](#10.7 统一缓存用量指标)
    • [10.8 AbstractFilterExpressionConverter 变更](#10.8 AbstractFilterExpressionConverter 变更)
    • [10.9 MethodToolCallbackProvider 异常类型变更](#10.9 MethodToolCallbackProvider 异常类型变更)
    • [10.10 MCP Sealed 接口移除](#10.10 MCP Sealed 接口移除)
    • [10.11 Builder.customizeRequest() 删除](#10.11 Builder.customizeRequest() 删除)

基于官方 Spring AI 2.0.0 Upgrade Notes 翻译整理。


1. 概述

Spring AI 2.0 的底座绑定 Spring Boot 4.0Spring Framework 7.0,全面落地 Jakarta EE 11,与 Boot 3.x 的向后兼容彻底断开。还在 3.x 上的项目需先完成底座迁移,然后才轮到 AI 层。

Java 版本 :最低仍是 Java 17,但 AI 场景推荐 Java 25AI 应用以密集 I/O 阻塞为主(调用大模型 API、处理流式响应),Java 25 的虚拟线程在此场景下吞吐量提升明显,并发长连接流式响应尤其受益。


2. Advisor 变更

2.1 模块重命名

旧名称 新名称
spring-ai-advisors-vector-store spring-ai-vector-store-advisor

2.2 ToolSearchToolCallingAdvisor 独立为专用模块

项目 旧值 新值
Artifact spring-ai-tool-search-tool spring-ai-tool-search-advisor
包名 org.springframework.ai.tool.toolsearch.advisor org.springframework.ai.chat.client.advisor.toolsearch

同时新增自动配置(spring-ai-autoconfigure-tool-search-advisor)和 Starter(spring-ai-starter-tool-search-advisor)。启用后,ToolSearchToolCallingAdvisor 会替换默认的 ToolCallingAdvisor,每次调用只发送最相关的工具定义给 LLM

xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-tool-search-advisor</artifactId>
</dependency>
properties 复制代码
spring.ai.chat.client.tool-search-advisor.enabled=true
spring.ai.chat.client.tool-search-advisor.tool-index-type=regex  # regex | lucene | vector

2.3 Advisor 优先级默认值调整

Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDERHIGHEST_PRECEDENCE + 1000 改为 HIGHEST_PRECEDENCE + 200,将 Memory Advisor 置于 ToolCallingAdvisor+300)之前。

ToolCallingAdvisor 现在默认在工具调用迭代期间自行管理对话历史,Memory Advisor 只保存最终的用户/助手对话交换,不再写入工具调用消息。如需在循环内使用 Memory(如 InMemoryChatMemoryRepository),需显式设置优先级并禁用内部历史:

java 复制代码
var toolCallingAdvisor = ToolCallingAdvisor.builder()
    .disableInternalConversationHistory()
    .build();
var chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory)
    .advisorOrder(Ordered.HIGHEST_PRECEDENCE + 400)
    .build();

3. Tool Calling 变更

3.1 移除 internalToolExecutionEnabled

ToolCallingChatOptions 及所有 providerChatOptions 中移除。对应的配置属性 spring.ai.<provider>.chat.internal-tool-execution-enabled 也一并移除。

迁移 :删除所有 .internalToolExecutionEnabled(...) 调用。

推荐方案:

  • 通过 ChatClient + ToolCallingAdvisor(推荐)--- 有工具时自动注册,无需任何标志位。
  • 通过 ChatModel 手动控制循环 --- 直接调用 ChatModel,检查 chatResponse.hasToolCalls() 自行驱动循环。
java 复制代码
// Before
ChatOptions options = ToolCallingChatOptions.builder()
    .toolCallbacks(ToolCallbacks.from(new MyTools()))
    .internalToolExecutionEnabled(false)   // 删除此行
    .build();

// After
ChatOptions options = ToolCallingChatOptions.builder()
    .toolCallbacks(ToolCallbacks.from(new MyTools()))
    .build();

3.2 移除 ToolExecutionEligibilityPredicate

已被 ToolExecutionEligibilityCheckerFunction<ChatResponse, Boolean>)替代,通过 ToolCallingAdvisor.Builder 设置:

java 复制代码
ToolCallingAdvisor advisor = ToolCallingAdvisor.builder()
    .toolExecutionEligibilityChecker(response ->
        response != null && response.hasToolCalls()
        && !"stop".equals(response.getResult().getMetadata().getFinishReason()))
    .build();

Spring Boot 用户可声明 ToolExecutionEligibilityChecker Bean,自动配置会拾取。

3.3 新增 spring.ai.chat.client.tool-calling.enabled 属性

默认 true,设为 false 可全局禁用工具调用的自动执行(工具定义仍发送给模型,但工具调用结果不会自动执行)。

3.4 移除 streamToolCallResponses

从所有 Advisor Builder 和自动配置属性中移除。原因:当设为 true 时,中间工具调用请求块会被流式传输,但对应的 ToolResponseMessage 不会,导致下游 Memory Advisor 记录的对话历史损坏。该设计缺陷无法在不破坏 ChatClientResponse 的前提下修复。

迁移 :删除所有 .streamToolCallResponses(...) 调用。如需观察工具调用循环的每次迭代,使用手动循环:

java 复制代码
ToolCallingManager toolCallingManager = ToolCallingManager.builder().build();
ChatOptions chatOptions = ToolCallingChatOptions.builder()
    .toolCallbacks(ToolCallbacks.from(new WeatherTools()))
    .build();

ChatClientResponse response = chatClient.prompt()
    .user("What is the weather in Amsterdam and Paris?")
    .options(chatOptions)
    .advisors(AdvisorParams.toolCallingAdvisorAutoRegister(false))
    .call().chatClientResponse();

while (response.chatResponse() != null && response.chatResponse().hasToolCalls()) {
    ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, response.chatResponse());
    prompt = new Prompt(result.conversationHistory(), chatOptions);
    response = chatClient.prompt()
        .messages(result.conversationHistory())
        .options(chatOptions)
        .advisors(AdvisorParams.toolCallingAdvisorAutoRegister(false))
        .call().chatClientResponse();
}

4. Options 及配置变更

4.1 Options 严格不可变

所有 Options 类(ChatOptionsEmbeddingOptions 等)现在严格不可变。集合字段(toolCallbacksstopSequences 等)存储为不可修改集合,且使用 nullable 集合替代空集合。

  • ChatOptions#copy()*Options#fromOptions(*) 已移除
  • 修改 getter 返回的集合将抛出 UnsupportedOperationException

迁移 :使用 mutate() 替代 copy() / fromOptions()

java 复制代码
// Before
OllamaChatOptions options = originalOptions.copy();
options.setFoo("...");

// After
OllamaChatOptions options = originalOptions.mutate().foo("...").build();

4.2 默认值移至 Options 构造函数

默认值从 Model 实现和 *Properties 配置类移至 Options 构造函数。

  • ChatModel#getDefaultOptions() 废弃,改用 getOptions()
  • *Properties 类中不再重复定义默认值

4.3 配置属性扁平化

所有模型的配置属性不再使用 .options 前缀:

properties 复制代码
# Before
spring.ai.openai.embedding.options.model=text-embedding-3-small

# After
spring.ai.openai.embedding.model=text-embedding-3-small
java 复制代码
// Before
String model = properties.getOptions().getModel();
OpenAiEmbeddingOptions options = properties.getOptions().toOptions();

// After
String model = properties.getModel();
OpenAiEmbeddingOptions options = properties.toOptions();

4.4 N() 重命名为 n()

Builder 中的 N() 方法重命名为 n() 以符合 Java 命名规范。

java 复制代码
// Before
OpenAiChatOptions.builder().N(1).build();

// After
OpenAiChatOptions.builder().n(1).build();

4.5 ChatClient Options 现在接受 Builder

ChatClient.options() / .defaultOptions() 现在接受 ChatOptions.Builder 而非已构建的 ChatOptions 实例。Builder 会在首个 Advisor 调用前与模型默认 Options 合并。

java 复制代码
// Before
ChatOptions opts = AnthropicChatOptions.builder().maxTokens(100).temperature(0.7).build();
chatClient.prompt("Tell me a joke").options(opts).call().content();

// After
chatClient.prompt("Tell me a joke")
    .options(AnthropicChatOptions.builder().maxTokens(100).temperature(0.7))
    .call().content();

注意:直接调用 ChatModel.call(Prompt) 时仍需传入已构建的 ChatOptions 实例,ChatModel 层不做合并。

4.6 移除默认 Temperature 配置

Spring AI 不再为 Chat Model 自动配置提供默认 temperature 值(之前为 0.7),改为使用各 AI provider 的原生默认值。

如需保持旧行为,显式配置:

properties 复制代码
spring.ai.openai.chat.temperature=0.7
spring.ai.anthropic.chat.temperature=0.7

5. JSON 工具类重构

5.1 新增 JsonHelper

新增 JsonHelper 类(位于 spring-ai-commons),作为 JSON 序列化/反序列化的标准入口。可实例化并接受自定义 JsonMapper

JacksonUtils 新增 getDefaultJsonMapper() 静态方法,返回共享的预配置 JsonMapper 实例。

java 复制代码
// 默认 --- 使用 JacksonUtils 的共享 JsonMapper
JsonHelper jsonHelper = new JsonHelper();

// 自定义
JsonMapper myMapper = JsonMapper.builder().addModule(new JavaTimeModule()).build();
JsonHelper customHelper = new JsonHelper(myMapper);

5.2 JsonParser 废弃

Before After
JsonParser.getJsonMapper() JacksonUtils.getDefaultJsonMapper()
JsonParser.fromJson(json, MyType.class) jsonHelper.fromJson(json, MyType.class)
JsonParser.toJson(object) jsonHelper.toJson(object)
JsonParser.toTypedObject(value, type) jsonHelper.convertToTypedObject(value, type)

5.3 ModelOptionsUtils JSON 方法移除

移除的成员 替代
ModelOptionsUtils.JSON_MAPPER JacksonUtils.getDefaultJsonMapper()
ModelOptionsUtils.jsonToMap(String) jsonHelper.fromJsonToMap(json)
ModelOptionsUtils.toJsonString(Object) jsonHelper.toJson(object)
ModelOptionsUtils.getJsonSchema(Type) JsonSchemaUtils.getJsonSchema(type)

5.4 McpJsonParser 删除

Before After
McpJsonParser.toMap(object) jsonHelper.convertToMap(object)
McpJsonParser.fromMap(map, MyType.class) jsonHelper.convertFromMap(map, MyType.class)

6. MCP SDK 变更

6.1 Elicitation API:TypeReference 替换

McpAsyncRequestContextMcpSyncRequestContextelicit(...) 方法中,JacksonTypeReference 替换为 SpringParameterizedTypeReference

java 复制代码
// Before
import tools.jackson.core.type.TypeReference;
context.elicit(e -> e.message("Please fill in the form"),
    new TypeReference<Map<String, Object>>() {});

// After
import org.springframework.core.ParameterizedTypeReference;
context.elicit(e -> e.message("Please fill in the form"),
    new ParameterizedTypeReference<Map<String, Object>>() {});

6.2 构造器必填字段

以下构造器现在通过 Assert.notNull() 强制必填参数:

类型 变更
CreateMessageResult model 字段现在必填
CreateMessageRequest maxTokens 字段现在必填
java 复制代码
// Before
CreateMessageResult.builder().content(new TextContent(response)).build();
// After
CreateMessageResult.builder(Role.ASSISTANT, response, modelHint).build();

// Before
CreateMessageRequest.builder().messages(messages).build();
// After
CreateMessageRequest.builder(messages, 500).build();

6.3 Builder API 废弃

以下无参构造器和 builder() 方法废弃,替换为需要必填参数的工厂方法:

废弃 替代
new TextContent(text) TextContent.builder(text).build()
new ReadResourceResult(contents) ReadResourceResult.builder(contents).build()
LoggingMessageNotification.builder() LoggingMessageNotification.builder(level, data)
ElicitRequest.builder() ElicitRequest.builder(message, requestedSchema)
CallToolRequest.builder() CallToolRequest.builder(name)

6.4 MCP 注解迁移至 Spring AI

org.springaicommunity:mcp-annotations 外部库已移除,其类现在属于 Spring AI 自身。所有包名从 org.springaicommunity.mcp.* 迁移到 org.springframework.ai.mcp.*

旧包 新包
org.springaicommunity.mcp.annotation.* org.springframework.ai.mcp.annotation.*
org.springaicommunity.mcp.method.* org.springframework.ai.mcp.annotation.method.*
org.springaicommunity.mcp.provider.* org.springframework.ai.mcp.annotation.provider.*

可使用 OpenRewrite 自动迁移:

bash 复制代码
mvn org.openrewrite.maven:rewrite-maven-plugin:6.32.0:run \
  -Drewrite.configLocation=https://raw.githubusercontent.com/spring-projects/spring-ai/refs/heads/main/src/rewrite/migrate-to-2-0-0-M3.yaml \
  -Drewrite.activeRecipes=org.springframework.ai.migration.M3MigrateMcpAnnotations \
  -Dmaven.compiler.failOnError=false

6.5 MCP Spring Transport 模块迁移

mcp-spring-webfluxmcp-spring-webmvc 传输模块从 MCP Java SDK 迁移到 Spring AI 项目。

Maven Group ID 变更:

xml 复制代码
<!-- Before -->
<dependency>
    <groupId>io.modelcontextprotocol.sdk</groupId>
    <artifactId>mcp-spring-webflux</artifactId>
</dependency>

<!-- After -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>mcp-spring-webflux</artifactId>
</dependency>

Java 包重定位:

旧包 新包
WebFluxSseServerTransportProvider io.modelcontextprotocol.server.transport org.springframework.ai.mcp.server.webflux.transport
WebMvcSseServerTransportProvider io.modelcontextprotocol.server.transport org.springframework.ai.mcp.server.webmvc.transport
WebFluxSseClientTransport io.modelcontextprotocol.client.transport org.springframework.ai.mcp.client.webflux.transport

6.6 MCP Client Customizer API 统一

McpAsyncClientCustomizerMcpSyncClientCustomizer 合并为单一泛型接口 McpClientCustomizer<B>

java 复制代码
// Before
@Bean
public McpSyncClientCustomizer mySyncCustomizer() {
    return (name, spec) -> spec.requestTimeout(Duration.ofSeconds(30));
}

// After
@Bean
public McpClientCustomizer<McpClient.SyncSpec> mySyncCustomizer() {
    return (name, spec) -> spec.requestTimeout(Duration.ofSeconds(30));
}

6.7 服务端工具输入校验默认开启

MCP Server 现在默认对入参进行 JSON Schema 校验。

如需禁用:

java 复制代码
McpServer.sync(transportProvider)
    .validateToolInputs(false)
    .tool(myTool, handler)
    .build();

6.8 Tool.inputSchema 返回类型变更

JsonSchema record 变为 Map<String, Object>,以支持任意 JSON Schema 方言关键字。

java 复制代码
// Before
McpSchema.JsonSchema schema = tool.inputSchema();

// After
Map<String, Object> schema = tool.inputSchema();

6.9 MCP WebMvc Transport Header 小写标准化

WebMvcSseServerTransportProvider 等类中传给 securityValidator.validateHeaders(headers)Header 名称现在统一小写。

java 复制代码
// Before
headers.get("Authorization");

// After
headers.get("authorization");

7. Chat Memory 变更

7.1 Conversation ID 现在必填

内置 Memory AdvisorMessageChatMemoryAdvisorVectorStoreChatMemoryAdvisor)的 conversation ID 不再可选。每次调用必须通过 advisor context 提供 ChatMemory.CONVERSATION_ID,缺失或为空时抛出 IllegalArgumentException

  • ChatMemory.DEFAULT_CONVERSATION_ID 常量已删除
  • .conversationId() Builder 方法已移除
java 复制代码
// Before
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory)
        .conversationId("my-session").build())
    .build();

// After
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
    .build();

chatClient.prompt().user("Hello!")
    .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "my-session"))
    .call().content();

7.2 getConversationId 签名变更

BaseChatMemoryAdvisor.getConversationId(Map, String) 替换为 getConversationId(Map)(单参数,缺失时抛异常)。

7.3 PromptChatMemoryAdvisor 删除

使用 MessageChatMemoryAdvisor 替代。API 相同,区别在于不再将记忆作为纯文本注入 system prompt,而是将对话历史直接以 Chat Message 形式包含在 prompt 中。

7.4 JDBC Chat Memory 新增 sequence_id

解决了不同数据库 TIMESTAMP 精度不一致导致的排序不确定问题。新增 sequence_id BIGINT 列用于消息排序。

PostgreSQL 迁移:

sql 复制代码
ALTER TABLE SPRING_AI_CHAT_MEMORY ADD COLUMN sequence_id BIGINT;

WITH ordered AS (
  SELECT ctid, ROW_NUMBER() OVER (PARTITION BY conversation_id ORDER BY "timestamp") - 1 AS seq
  FROM SPRING_AI_CHAT_MEMORY
)
UPDATE SPRING_AI_CHAT_MEMORY t SET sequence_id = o.seq FROM ordered o WHERE t.ctid = o.ctid;

ALTER TABLE SPRING_AI_CHAT_MEMORY ALTER COLUMN sequence_id SET NOT NULL;

CREATE INDEX SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_SEQUENCE_ID_IDX
  ON SPRING_AI_CHAT_MEMORY(conversation_id, sequence_id);

7.5 MongoDB Chat Memory 排序修正

MongoChatMemoryRepository 现在返回按时间正序排列的消息(之前错误地返回了倒序)。需移除之前为纠正此 Bug 而编写的 Collections.reverse() 相关代码。

7.6 Conversation History 从 ToolContext 移除

ToolContext.TOOL_CALL_HISTORY 常量和 getToolCallHistory() 方法已删除。对话历史不再自动填充到 ToolContext。工具应基于参数运行,对话上下文由 Advisor 层管理。如需对话历史管理,使用 ToolCallingAdvisor

java 复制代码
ChatClient chatClient = ChatClient.builder()
    .defaultAdvisors(ToolCallingAdvisor.builder()
        .conversationHistoryEnabled(true)  // 默认开启
        .build())
    .build();

8. 模型模块变更

8.1 Anthropic 模块:切换至官方 Java SDK

spring-ai-anthropic 现在基于 com.anthropic:anthropic-java 构建。

主要影响:

  • org.springframework.ai.anthropic.api.AnthropicApi 及所有嵌套 record 类型已删除
  • AnthropicChatModel(AnthropicApi, ...) 构造器删除,使用 Builder
  • AnthropicChatOptions#maxTokens 默认值从 500 变为 4096
  • 缓存相关类移至 org.springframework.ai.anthropic 根包
  • CitationDocument 重命名为 AnthropicCitationDocument
java 复制代码
// Before
AnthropicApi anthropicApi = new AnthropicApi(apiKey);
AnthropicChatModel chatModel = new AnthropicChatModel(anthropicApi, options);

// After
AnthropicChatModel chatModel = AnthropicChatModel.builder()
    .apiKey(apiKey).defaultOptions(options).build();

新增 Chat Options:

Option 说明
Thinking Display SUMMARIZED / OMITTED,使用 thinking 预算但不暴露完整推理过程
Service Tier AUTO / STANDARD_ONLY,Anthropic 优先级容量层级
Web Search 内置 AnthropicWebSearchTool,让 Claude 在请求期间搜索网页
Inference Geo us / eu,数据驻留路由

8.2 Ollama:属性重命名

properties 复制代码
# Before
spring.ai.ollama.chat.think-option=true

# After
spring.ai.ollama.chat.think=true

8.3 OpenAI:切换至官方 openai-java SDK

spring-ai-openai 模块底层切换到官方 openai-java SDK。所有 spring.ai.openai.* 属性、BuilderOptions 保持不变,现有用户无需修改代码。

8.4 Minimax、Azure OpenAI、OpenAI SDK、OCI GenAI 模块删除

移除的模块 替代方案
Minimax 使用 Anthropic 支持,配置 https://api.minimax.io/anthropic 作为 base URL
spring-ai-azure-openai 使用 spring-ai-openai,去掉类名中的 Azure 前缀
spring-ai-openai-sdk 使用 spring-ai-openai,去掉类名中的 Sdk 后缀
spring-ai-oci-genai 迁移至 github.com/oracle/spring-cloud-oracle

8.5 buildRequestPrompt 从公开 API 移除

之前被错误暴露为 public,现已恢复为 private/package-private

8.6 Model 内部方法访问级别变更

所有 Model 类中的 internalCallinternalStream 方法改为 private

java 复制代码
// Before
ChatResponse response = model.internalCall(prompt, previousChatResponse);

// After
ChatResponse response = model.call(prompt);

9. 模块及依赖变更

9.1 移除的模块

模块 说明
spring-ai-hanadb-store 从 Spring AI 中移除
spring-ai-spring-cloud-bindings Cloud Bindings 集成已移除
spring-ai-azure-cosmos-db-store 由 Azure Cosmos DB 团队外部维护
spring-ai-model-chat-memory-repository-cosmos-db 同上

9.2 OpenSearch 依赖升级

依赖 旧版本 新版本
OpenSearch Java Client 2.23.0 3.6.0
OpenSearch Testcontainers 2.0.1 4.1.0

仅在直接使用原生 OpenSearch Client 时才需要修改代码,通过 VectorStore 接口使用则不受影响。

9.3 Development-time Services

MongoDB AtlasDocker ComposeTestcontainers 支持现在由 Spring Boot MongoDB 模块原生提供。无需再依赖 org.springframework.ai:spring-ai-spring-boot-testcontainers,使用 org.springframework.boot:spring-boot-testcontainers 即可。


10. 其他变更

10.1 Google GenAI Embedding 包变更

GoogleGenAiEmbeddingConnectionDetails 移至 org.springframework.ai.google.genai.embedding 包。

10.2 ChatClient 自动注册 ToolCallingAdvisor

ChatClient 现在始终在 Advisor 链中自动注册 ToolCallingAdvisor(除非显式禁用)。如已有显式注册的 ToolCallingAdvisor,需删除重复:

java 复制代码
// Before --- 手动注册
chatClient.prompt("What's the weather?")
    .tools(weatherTool)
    .advisors(ToolCallingAdvisor.builder().build())
    .call().content();

// After --- 自动注册处理
chatClient.prompt("What's the weather?")
    .tools(weatherTool)
    .call().content();

新增两个 Marker 接口:

  • ToolAdvisor --- 自定义 Advisor 实现此接口可防止重复自动注册
  • MemoryAdvisor --- 用于检测下游 Memory Advisor 并协调 ToolCallingAdvisor 的内部历史

10.3 移除 ToolSpec Consumer API

ChatClienttools(Consumer<ToolSpec>) / defaultTools(Consumer<ToolSpec>) API 已删除。tools(Object...) 现在直接接受 ToolCallbackToolCallbackProvider@Tool 注解的 POJO 等类型。toolContext() 用于单独设置上下文。

java 复制代码
// Before
chatClient.prompt()
    .tools(t -> t.callbacks(myCallback).context("tenantId", "acme"))
    .call().content();

// After
chatClient.prompt()
    .tools(myCallback)
    .toolContext(Map.of("tenantId", "acme"))
    .call().content();

10.4 Spring Bean Tool Resolution 删除

SpringBeanToolCallbackResolver 和通过 toolNames() 引用 bean 名称的方式已删除。需显式声明 ToolCallback Bean。

java 复制代码
// Before
@Bean @Description("Get the weather in location")
Function<WeatherRequest, WeatherResponse> currentWeather() {
    return weatherService::getWeather;
}

// After
@Bean
ToolCallback currentWeather() {
    return FunctionToolCallback.builder("currentWeather", weatherService::getWeather)
        .description("Get the weather in location")
        .inputType(WeatherRequest.class)
        .build();
}

10.5 BeanOutputConverter JSON Schema 变更

  • Kotlin 可选属性不再出现在 required 数组
  • @JsonProperty(required = false) 注解的属性不再视为 required
  • 生成的 Schema 包含 OpenAPI 风格的 format 提示
  • postProcessSchema(JsonNode) 扩展点删除,改用 generateSchema()

10.6 Observability 属性调整

变更 旧值 新值
Span 名称 tool_call <name> execute_tool <name>
gen_ai.operation.name framework execute_tool
新增属性 --- spring.ai.tool.typespring.ai.tool.call.id

10.7 统一缓存用量指标

Usage 接口新增两个默认方法 getCacheReadInputTokens()getCacheWriteInputTokens()AnthropicBedrock ConverseOpenAIGoogle GenAI 均已实现。

10.8 AbstractFilterExpressionConverter 变更

doSingleValue(Object value, StringBuilder context) 从具体方法变为抽象方法。自定义 Vector StoreFilterExpressionConverter 必须显式实现。

10.9 MethodToolCallbackProvider 异常类型变更

MethodToolCallbackProvider 在两个场景下抛出 IllegalArgumentException(替代 IllegalStateException):

  • 工具对象没有 @Tool 注解的方法
  • 多个工具对象产生重名的回调

10.10 MCP Sealed 接口移除

JSONRPCMessageRequestResultNotificationContent 等接口不再是 sealed 类型。依赖 sealed 层级实现穷举 switch 的代码需添加 default 分支。

10.11 Builder.customizeRequest() 删除

替换为 httpRequestCustomizer()(同步)或 asyncHttpRequestCustomizer()(异步):

java 复制代码
// Before
HttpClientSseClientTransport.builder(baseUrl)
    .customizeRequest(req -> req.header("Authorization", "Bearer token")).build();

// After
HttpClientSseClientTransport.builder(baseUrl)
    .httpRequestCustomizer(req -> req.header("Authorization", "Bearer token")).build();
相关推荐
Luhui Dev1 小时前
几何图,现在可以用 API 一句话生成
人工智能·数学·luhuidev
咕咕AI学堂1 小时前
大模型应用开发:Prompt Engineering 从经验法则到工程化实践
人工智能
名不经传的养虾人1 小时前
从0到1:企业级AI项目迭代日记 Vol.47|从“能说”到“能上手”
大数据·人工智能·ai编程·企业ai·多agent协作
邵宇然2 小时前
Rust Unsafe 安全规范:从避免未定义行为到构建安全抽象的工程实践
人工智能
TYUT_xiaoming2 小时前
yolo模型训练
人工智能·python·yolo
2301_780789662 小时前
零信任架构中,身份感知防火墙(IAFW)的部署要点与最佳实践
linux·运维·服务器·人工智能·tcp/ip·架构
MicroTech20252 小时前
业绩披露|微算法科技(MLGO)2025年净利润1.27亿元
大数据·人工智能·科技