升级说明

升级到 1.0.0-SNAPSHOT

概览

1.0.0-SNAPSHOT 版本对 Artifact ID、包名和模块结构进行了重大更改。本节提供了使用 SNAPSHOT 版本的具体指导。

添加 Snapshot 仓库

要使用 1.0.0-SNAPSHOT 版本,您需要将 Snapshot 仓库添加到构建文件中。有关详细说明,请参阅入门指南中的Snapshot - 添加 Snapshot 仓库部分。

更新依赖管理

在您的构建配置中将 Spring AI BOM 版本更新到 1.0.0-SNAPSHOT。有关配置依赖管理的详细说明,请参阅入门指南中的依赖管理部分。

Artifact ID、包名和模块更改

1.0.0-SNAPSHOT 版本包含了 Artifact ID、包名和模块结构的更改。

有关详细信息,请参阅: - 通用 Artifact ID 更改 - 通用包名更改 - 通用模块结构

升级到 1.0.0-RC1

破坏性更改

Watson AI 模型已移除,因为它基于较旧的文本生成技术,而现在有了新的聊天生成模型,该旧技术被认为已过时。希望 Watson 在 Spring AI 的未来版本中能重新出现。

升级到 1.0.0-M8

您可以使用 OpenRewrite Recipe 自动升级到 1.0.0-M8。此 Recipe 有助于应用此版本所需的许多代码更改。您可以在 Arconia Spring AI Migrations 找到该 Recipe 和使用说明。

破坏性更改

从 Spring AI 1.0 M7 升级到 1.0 M8 时,之前注册过工具回调的用户会遇到破坏性更改,导致工具调用功能静默失败。这尤其影响使用了已弃用 tools() 方法的代码。

示例

以下是 M7 中可以工作但在 M8 中不再按预期工作的代码示例

// Old code in M7 - no longer works correctly in M8
chatClient.prompt("What day is tomorrow?")
    .tools(toolCallback)
    .call()
    .content();

如何修改您的代码

要在升级到 M8 时解决此问题,您需要更新代码以使用新的 toolCallbacks() 方法

// Updated code for M8
chatClient.prompt("What day is tomorrow?")
    .toolCallbacks(toolCallback)
    .call()
    .content();

为何进行此更改

Spring AI 团队重命名了重载的 tools() 方法,以提高清晰度并防止方法分派中的歧义。之前的 API 设计导致 Java 编译器根据参数类型在多个重载方法之间进行选择时出现混淆。

从 M7 到 M8 的方法映射

以下是旧方法与其新对应方法的映射关系

  1. tools(String…​ toolNames)toolNames(String…​ toolNames)

    • 在引用在其他地方注册的工具时使用(例如,通过带有 @Description@Bean

  2. tools(ToolCallback…​ toolCallbacks)toolCallbacks(ToolCallback…​ toolCallbacks)

    • 用于内联工具回调注册

  3. tools(List<ToolCallback> toolCallbacks)toolCallbacks(List<ToolCallback> toolCallbacks)

    • 在您拥有一组工具回调时使用

  4. tools(ToolCallbackProvider…​ toolCallbackProviders)toolCallbacks(ToolCallbackProvider…​ toolCallbackProviders)

    • 用于实现 ToolCallbackProvider 接口的对象

  5. tools(Object…​ toolObjects) 保持不变

    • 仅用于带有 @Tool 注解的方法的对象

改进的错误处理

此 PR 现已合并 (spring-projects/spring-ai#2964) 中,当提供的对象上未找到 @Tool 方法时,tools(Object…​ toolObjects) 方法现在将抛出异常,而不再静默失败。这有助于开发人员立即识别迁移问题。

迁移总结

如果您从 M7 升级到 M8

  1. 将所有对 .tools(toolCallback) 的调用替换为 .toolCallbacks(toolCallback)

  2. 将所有对 .tools(toolCallbackProvider) 的调用替换为 .toolCallbacks(toolCallbackProvider)

  3. 将所有对 .tools("toolName") 的调用替换为 .toolNames("toolName")

这些更改将确保您的工具调用功能在升级到 Spring AI 1.0 M8 后继续正常工作。

聊天客户端

  • ChatClient 已得到增强,解决了用户和系统 prompt 在顾问中使用之前未渲染时出现的一些不一致性或不良行为。新行为确保用户和系统 prompt 在执行顾问链之前始终被渲染。作为此增强的一部分,AdvisedRequestAdvisedResponse API 已被弃用,取而代之的是 ChatClientRequestChatClientResponse。顾问现在作用于包含在 ChatClientRequest 中的完整构建的 Prompt 对象,而不是 AdvisedRequest 中使用的解构格式,这保证了一致性和完整性。

例如,如果您有一个自定义顾问在 before 方法中修改请求 prompt,您可以将其重构如下

// --- Before (using AdvisedRequest) ---
@Override
public AdvisedRequest before(AdvisedRequest advisedRequest) {
    // Access original user text and parameters directly from AdvisedRequest
    String originalUserText = new PromptTemplate(advisedRequest.userText(), advisedRequest.userParams()).render();

    // ... retrieve documents, create augmented prompt text ...
    List<Document> retrievedDocuments = ...;
    String augmentedPromptText = ...; // create augmented text from originalUserText and retrievedDocuments

    // Copy existing context and add advisor-specific data
    Map<String, Object> context = new HashMap<>(advisedRequest.adviseContext());
    context.put("retrievedDocuments", retrievedDocuments); // Example key

    // Use the AdvisedRequest builder pattern to return the modified request
    return AdvisedRequest.from(advisedRequest)
        .userText(augmentedPromptText) // Set the augmented user text
        .adviseContext(context)        // Set the updated context
        .build();
}

// --- After (using ChatClientRequest) ---
@Override
public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain chain) {
    String originalUserText = chatClientRequest.prompt().getUserMessage().getText(); // Access prompt directly

    // ... retrieve documents ...
    List<Document> retrievedDocuments = ...;
    String augmentedQueryText = ...; // create augmented text

    // Initialize context with existing data and add advisor-specific data
    Map<String, Object> context = new HashMap<>(chatClientRequest.context()); (1)
    context.put("retrievedDocuments", retrievedDocuments); // Example key
    context.put("originalUserQuery", originalUserText);   // Example key

    // Use immutable operations
    return chatClientRequest.mutate()
        .prompt(chatClientRequest.prompt()
            .augmentUserMessage(augmentedQueryText) (2)
        )
        .context(context) (3)
        .build();
}
1 使用来自传入请求 (chatClientRequest.context()) 的数据初始化上下文 Map,以保留来自先前顾问的上下文,然后添加新数据。
2 使用诸如 prompt.augmentUserMessage() 之类的方法安全地修改 prompt 内容。
3 传递更新的上下文 Map。此 Map 成为 ChatClientRequest 的一部分,稍后可通过 after 方法中的 ChatClientResponse.responseContext() 访问。
  • 顾问链可以使用有用的数据填充执行上下文。例如,在执行检索增强生成时,可以将检索到的文档添加到上下文中。现在可以从 ChatClient 调用中返回一个 ChatClientResponse 对象,其中包含执行上下文。因此,除了 content()chatResponse() 方法之外,您现在可以使用 chatClientResponse() 终止 ChatClient 调用,该方法允许您访问 ChatResponse 和执行上下文。

除了直接使用 augmentUserMessage(String) 替换用户消息文本之外,您还可以提供一个函数来更精细地修改现有的 UserMessage

Prompt originalPrompt = new Prompt(new UserMessage("Tell me about Large Language Models."));

// Example: Append context or modify properties using a Function
Prompt augmentedPrompt = originalPrompt.augmentUserMessage(userMessage ->
    userMessage.mutate()
        .text(userMessage.getText() + "\n\nFocus on their applications in software development.")
        // .media(...) // Potentially add/modify media
        // .metadata(...) // Potentially add/modify metadata
        .build()
);

// 'augmentedPrompt' now contains the modified UserMessage

这种方法在您需要有条件地更改 UserMessage 的部分内容或处理其媒体和元数据时提供了更多控制,而不是仅仅替换文本内容。

  • ChatClient prompt 构建器 API 中重载的 tools 方法已重命名,以提高清晰度并避免基于参数类型的方法分派中的歧义。

  • ChatClient.PromptRequestSpec#tools(String…​ toolNames) 已重命名为 ChatClient.PromptRequestSpec#toolNames(String…​ toolNames)。使用此方法指定模型允许调用的工具函数名称(在其他地方注册,例如通过带有 @Description@Bean 定义)。

  • ChatClient.PromptRequestSpec#tools(ToolCallback…​ toolCallbacks) 已重命名为 ChatClient.PromptRequestSpec#toolCallbacks(ToolCallback…​ toolCallbacks)。使用此方法提供内联的 ToolCallback 实例,其中包括函数实现、名称、描述和输入类型定义。

此更改解决了 Java 编译器可能无法根据提供的参数选择预期重载的潜在混淆。

Prompt 模板化和顾问

与 prompt 创建和顾问定制相关的几个类和方法已被弃用,转而采用使用构建器模式和 TemplateRenderer 接口的更灵活的方法。有关新 API 的详细信息,请参阅PromptTemplate

PromptTemplate 弃用

PromptTemplate 类已弃用了一些与旧的 templateFormat 枚举和直接变量注入相关的构造函数和方法

  • 构造函数:PromptTemplate(String template, Map<String, Object> variables)PromptTemplate(Resource resource, Map<String, Object> variables) 已弃用。

  • 字段:templatetemplateFormat 已弃用。

  • 方法:getTemplateFormat()getInputVariables()validate(Map<String, Object> model) 已弃用。

迁移:使用 PromptTemplate.builder() 模式创建实例。通过 .template() 提供模板字符串,并通过 .renderer() 可选地配置自定义 TemplateRenderer。使用 .variables() 传递变量。

// Before (Deprecated)
PromptTemplate oldTemplate = new PromptTemplate("Hello {name}", Map.of("name", "World"));
String oldRendered = oldTemplate.render(); // Variables passed at construction

// After (Using Builder)
PromptTemplate newTemplate = PromptTemplate.builder()
    .template("Hello {name}")
    .variables(Map.of("name", "World")) // Variables passed during builder configuration
    .build();
Prompt prompt = newTemplate.create(); // Create prompt using baked-in variables
String newRendered = prompt.getContents(); // Or use newTemplate.render()

QuestionAnswerAdvisor 弃用

QuestionAnswerAdvisor 已弃用了依赖简单 userTextAdvise 字符串的构造函数和构建器方法

  • 接受 userTextAdvise String 参数的构造函数已弃用。

  • 构建器方法:userTextAdvise(String userTextAdvise) 已弃用。

迁移:使用 .promptTemplate(PromptTemplate promptTemplate) 构建器方法提供一个完全配置好的 PromptTemplate 对象,用于自定义如何合并检索到的上下文。

// Before (Deprecated)
QuestionAnswerAdvisor oldAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
    .userTextAdvise("Context: {question_answer_context} Question: {question}") // Simple string
    .build();

// After (Using PromptTemplate)
PromptTemplate customTemplate = PromptTemplate.builder()
    .template("Context: {question_answer_context} Question: {question}")
    .build();

QuestionAnswerAdvisor newAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
    .promptTemplate(customTemplate) // Provide PromptTemplate object
    .build();

聊天记忆

  • 当使用 Spring AI 模型启动器之一时,将为您自动配置一个 ChatMemory bean。默认情况下,它使用 MessageWindowChatMemory 实现,并将对话历史记录存储在内存中。

  • ChatMemory API 已得到增强,以支持更灵活和可扩展的对话历史管理方式。存储机制已与 ChatMemory 接口解耦,现在由新的 ChatMemoryRepository 接口处理。ChatMemory API 现在可用于实现不同的记忆策略,而无需绑定到特定的存储机制。默认情况下,Spring AI 提供了一个 MessageWindowChatMemory 实现,该实现维护一个最大指定大小的消息窗口。

  • ChatMemory 中的 get(String conversationId, int lastN) 方法已弃用,取而代之的是在需要将消息保留在内存中达到一定限制时使用 MessageWindowChatMemoryget(String conversationId) 方法现在是从记忆中检索消息的首选方法,而 ChatMemory 的具体实现可以决定过滤、处理和返回消息的策略。

  • JdbcChatMemory 已弃用,取而代之的是结合 ChatMemory 实现(如 MessageWindowChatMemory)使用 JdbcChatMemoryRepository。如果您之前依赖于自动配置的 JdbcChatMemory bean,现在可以通过自动装配一个 ChatMemory bean 来替换它,该 bean 在相关依赖项位于 classpath 中时会被自动配置以在内部使用 JdbcChatMemoryRepository 来存储消息。

  • spring.ai.chat.memory.jdbc.initialize-schema 属性已弃用,取而代之的是 spring.ai.chat.memory.repository.jdbc.initialize-schema

  • 有关新 API 及如何使用的更多详细信息,请参阅新的聊天记忆文档。

  • MessageWindowChatMemory.get(String conversationId, int lastN) 方法已弃用。窗口大小现在根据实例化时提供的配置在内部管理,因此只应使用 get(String conversationId)

Prompt 模板化

  • PromptTemplate API 已重新设计,以支持更灵活和可扩展的 prompt 模板化方式,依赖于新的 TemplateRenderer API。作为此更改的一部分,getInputVariables()validate() 方法已弃用,如果调用它们将抛出 UnsupportedOperationException。任何特定于模板引擎的逻辑都应通过 TemplateRenderer API 提供。

类包重构

为了更好地组织,一些类已被移到不同的模块和包中

  • 评估类移动

    • org.springframework.ai.evaluation.FactCheckingEvaluator 已移至 spring-ai-client-chat 模块中的 org.springframework.ai.chat.evaluation 包。

    • org.springframework.ai.evaluation.RelevancyEvaluator 已移至 spring-ai-client-chat 模块中的 org.springframework.ai.chat.evaluation 包。

    • org.springframework.ai.evaluation.EvaluationRequest, EvaluationResponse, 和 Evaluator 已从 spring-ai-client-chat 模块移至 spring-ai-commons 模块中的 org.springframework.ai.evaluation 包下。

  • 输出转换器类移动

    • org.springframework.ai.converter 包中的类(例如,BeanOutputConverter, ListOutputConverter, MapOutputConverter, StructuredOutputConverter 等)已从 spring-ai-client-chat 模块移至 spring-ai-model 模块。

  • Transformer 类移动

    • org.springframework.ai.chat.transformer.KeywordMetadataEnricher 已移至 spring-ai-model 模块中的 org.springframework.ai.model.transformer.KeywordMetadataEnricher

    • org.springframework.ai.chat.transformer.SummaryMetadataEnricher 已移至 spring-ai-model 模块中的 org.springframework.ai.model.transformer.SummaryMetadataEnricher

  • 工具类移动

    • org.springframework.ai.util.PromptAssert 已从 spring-ai-client-chat 模块移至 spring-ai-rag 模块中的 org.springframework.ai.rag.util.PromptAssert

请相应地更新您的导入。

可观测性

  • spring.ai.client 可观测性的更改

    • spring.ai.chat.client.tool.function.namesspring.ai.chat.client.tool.function.callbacks 属性已弃用,取而代之的是一个新的 spring.ai.chat.client.tool.names 属性,该属性包含传递给 ChatClient 的所有工具的名称,无论用于定义它们的底层机制如何。

    • spring.ai.chat.client.advisor.params 属性已弃用,并且没有替代品。原因是存在暴露敏感信息或破坏 instrumentation 的风险,因为顾问上下文中的条目用于在顾问之间传递任意 Java 对象,并且不一定可序列化。之前此处导出的对话 ID 现在可通过专用的 spring.ai.chat.client.conversation.id 属性获得。如果您需要将顾问上下文中的其他一些参数导出到可观测性系统,可以通过定义一个 ObservationFilter 并明确决定导出哪些参数来实现。您可以参考 ChatClientPromptContentObservationFilter 作为参考。

    • 通过 ChatClient API 指定的 prompt 内容之前可选地包含在 spring.ai.client 可观测性中,分解为几个属性:spring.ai.chat.client.user.text, spring.ai.chat.client.user.params, spring.ai.chat.client.system.text, spring.ai.chat.client.system.params。所有这些属性现在都已弃用,取而代之的是一个单一的 gen_ai.prompt 属性,该属性包含 prompt 中的所有消息,解决了影响已弃用属性(其中部分 prompt 未包含在可观测性中)的问题,并与 ChatModel API 中使用的可观测性对齐。这个新属性可以通过 spring.ai.chat.observations.include-prompt 配置属性启用,而之前的 spring.ai.chat.observations.include-input 配置属性已弃用。

  • spring.ai.advisor 可观测性的更改

    • spring.ai.advisor.type 属性已弃用。在以前的版本中,Advisor API 根据顾问类型(before, after, around)进行分类。这种区别不再适用,这意味着所有顾问现在都是同一种类型(around)。

检索增强生成

  • 引入了 DocumentPostProcessor API,用于在模块化 RAG 架构中实现检索后组件,取代了现已弃用的 DocumentCompressor, DocumentRanker, DocumentSelector API。

升级到 1.0.0-M7

变更概览

Spring AI 1.0.0-M7 是 RC1 和 GA 版本之前的最后一个里程碑版本。它引入了对 Artifact ID、包名和模块结构的几项重要更改,这些更改将在最终版本中保留。

Artifact ID、包名和模块更改

1.0.0-M7 包含与 1.0.0-SNAPSHOT 相同的结构更改。

有关详细信息,请参阅: - 通用 Artifact ID 更改 - 通用包名更改 - 通用模块结构

MCP Java SDK 升级到 0.9.0

Spring AI 1.0.0-M7 现在使用 MCP Java SDK 0.9.0 版本,该版本包含了与之前版本相比的重大更改。如果您在应用程序中使用了 MCP,则需要更新代码以适应这些更改。

主要更改包括

接口重命名

  • ClientMcpTransportMcpClientTransport

  • ServerMcpTransportMcpServerTransport

  • DefaultMcpSessionMcpClientSessionMcpServerSession

  • 所有 *Registration 类 → *Specification

服务器创建更改

  • 使用 McpServerTransportProvider 而不是 ServerMcpTransport

// Before
ServerMcpTransport transport = new WebFluxSseServerTransport(objectMapper, "/mcp/message");
var server = McpServer.sync(transport)
    .serverInfo("my-server", "1.0.0")
    .build();

// After
McpServerTransportProvider transportProvider = new WebFluxSseServerTransportProvider(objectMapper, "/mcp/message");
var server = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .build();

处理程序签名更改

现在所有处理程序都将 exchange 参数作为其第一个参数

// Before
.tool(calculatorTool, args -> new CallToolResult("Result: " + calculate(args)))

// After
.tool(calculatorTool, (exchange, args) -> new CallToolResult("Result: " + calculate(args)))

通过 Exchange 进行客户端交互

以前在服务器上可用的方法现在通过 exchange 对象访问

// Before
ClientCapabilities capabilities = server.getClientCapabilities();
CreateMessageResult result = server.createMessage(new CreateMessageRequest(...));

// After
ClientCapabilities capabilities = exchange.getClientCapabilities();
CreateMessageResult result = exchange.createMessage(new CreateMessageRequest(...));

根更改处理程序

// Before
.rootsChangeConsumers(List.of(
    roots -> System.out.println("Roots changed: " + roots)
))

// After
.rootsChangeHandlers(List.of(
    (exchange, roots) -> System.out.println("Roots changed: " + roots)
))

有关迁移 MCP 代码的完整指南,请参阅 MCP 迁移指南

启用/禁用模型自动配置

之前用于启用/禁用模型自动配置的配置属性已被移除

  • spring.ai.<provider>.chat.enabled

  • spring.ai.<provider>.embedding.enabled

  • spring.ai.<provider>.image.enabled

  • spring.ai.<provider>.moderation.enabled

默认情况下,如果在 classpath 中找到模型提供者(例如 OpenAI、Ollama),则会启用其相应模型类型(聊天、嵌入等)的自动配置。如果存在同一模型类型的多个提供者(例如,同时存在 spring-ai-openai-spring-boot-starterspring-ai-ollama-spring-boot-starter),您可以使用以下属性来选择哪个提供者的自动配置应该处于活动状态,从而有效地禁用其他提供者针对该特定模型类型的自动配置。

要完全禁用特定模型类型的自动配置,即使只有一个提供者存在,也要将相应的属性设置为一个与 classpath 中任何提供者都不匹配的值(例如,nonedisabled)。

您可以参考 SpringAIModels 枚举,获取已知提供者值的列表。

  • spring.ai.model.audio.speech=<model-provider|none>

  • spring.ai.model.audio.transcription=<model-provider|none>

  • spring.ai.model.chat=<model-provider|none>

  • spring.ai.model.embedding=<model-provider|none>

  • spring.ai.model.embedding.multimodal=<model-provider|none>

  • spring.ai.model.embedding.text=<model-provider|none>

  • spring.ai.model.image=<model-provider|none>

  • spring.ai.model.moderation=<model-provider|none>

使用 AI 自动化升级

您可以使用 Claude Code CLI 工具和提供的 prompt 自动化升级到 1.0.0-M7 的过程

  1. 下载 Claude Code CLI 工具

  2. update-to-m7.txt 文件复制 prompt

  3. 将 prompt 粘贴到 Claude Code CLI 中

  4. AI 将分析您的项目并进行必要的更改

自动化升级 prompt 目前可以处理 artifact ID 更改、包位置更改和模块结构更改,但尚未包含升级到 MCP 0.9.0 的自动化更改。如果您使用 MCP,需要根据 MCP Java SDK 升级部分的指导手动更新代码。

跨版本的通用更改

Artifact ID 更改

Spring AI starter artifact 的命名模式已更改。您需要根据以下模式更新您的依赖项

  • 模型启动器:spring-ai-{model}-spring-boot-starterspring-ai-starter-model-{model}

  • 向量存储启动器:spring-ai-{store}-store-spring-boot-starterspring-ai-starter-vector-store-{store}

  • MCP 启动器:spring-ai-mcp-{type}-spring-boot-starterspring-ai-starter-mcp-{type}

示例

  • Maven

  • Gradle

<!-- BEFORE -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

<!-- AFTER -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
// BEFORE
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
implementation 'org.springframework.ai:spring-ai-redis-store-spring-boot-starter'

// AFTER
implementation 'org.springframework.ai:spring-ai-starter-model-openai'
implementation 'org.springframework.ai:spring-ai-starter-vector-store-redis'

Spring AI 自动配置 Artifact 的更改

Spring AI 自动配置已从单一的整体式 artifact 更改为按模型、向量存储和其他组件划分的独立自动配置 artifact。进行此更改是为了最大限度地减少不同版本依赖库冲突的影响,例如 Google Protocol Buffers、Google RPC 等。通过将自动配置分离到特定组件的 artifact 中,可以避免引入不必要的依赖项并降低应用程序中版本冲突的风险。

原始的整体式 artifact 不再可用

<!-- NO LONGER AVAILABLE -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-spring-boot-autoconfigure</artifactId>
    <version>${project.version}</version>
</dependency>

取而代之的是,每个组件现在都有自己的自动配置 artifact,遵循以下模式

  • 模型自动配置:spring-ai-autoconfigure-model-{model}

  • 向量存储自动配置:spring-ai-autoconfigure-vector-store-{store}

  • MCP 自动配置:spring-ai-autoconfigure-mcp-{type}

新自动配置 Artifact 示例

  • 模型

  • 向量存储

  • MCP

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-model-openai</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-model-anthropic</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-model-vertex-ai</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-vector-store-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-vector-store-pgvector</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-vector-store-chroma</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-mcp-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-mcp-server</artifactId>
</dependency>
在大多数情况下,您不需要显式添加这些自动配置依赖项。使用相应的 starter 依赖项时,它们会作为传递性依赖项包含进来。

包名更改

您的 IDE 应该有助于重构到新的包位置。

  • KeywordMetadataEnricherSummaryMetadataEnricher 已从 org.springframework.ai.transformer 移至 org.springframework.ai.chat.transformer

  • Content, MediaContent, 和 Media 已从 org.springframework.ai.model 移至 org.springframework.ai.content

模块结构

项目的模块和 artifact 结构发生了重大变化。以前,spring-ai-core 包含了所有核心接口,但现在已拆分为专门的领域模块,以减少应用程序中不必要的依赖项。

Spring AI Dependencies

spring-ai-commons

基础模块,不依赖于其他 Spring AI 模块。包含: - 核心领域模型(Document, TextSplitter) - JSON 工具类和资源处理 - 结构化日志和可观测性支持

spring-ai-model

提供 AI 能力抽象: - 接口,如 ChatModel, EmbeddingModel, 和 ImageModel - 消息类型和 prompt 模板 - 函数调用框架(ToolDefinition, ToolCallback) - 内容过滤和可观测性支持

spring-ai-vector-store

统一的向量数据库抽象: - 用于相似性搜索的 VectorStore 接口 - 支持 SQL 样表达式的高级过滤 - 用于内存使用的 SimpleVectorStore - 对 embeddings 的批处理支持

spring-ai-client-chat

高级对话式 AI API: - ChatClient 接口 - 通过 ChatMemory 进行对话持久化 - 使用 OutputConverter 进行响应转换 - 基于顾问的拦截 - 同步和响应式流支持

spring-ai-advisors-vector-store

连接聊天与向量存储,用于 RAG: - QuestionAnswerAdvisor:将上下文注入到 prompts 中 - VectorStoreChatMemoryAdvisor:存储/检索对话历史记录

spring-ai-model-chat-memory-cassandra

Apache Cassandra 对 ChatMemory 的持久化支持: - CassandraChatMemory 实现 - 使用 Cassandra 的 QueryBuilder 进行类型安全的 CQL ==== spring-ai-model-chat-memory-neo4j

Neo4j 图数据库对聊天对话的持久化支持。

spring-ai-rag

检索增强生成 (Retrieval Augmented Generation) 的综合框架: - RAG 管道的模块化架构 - RetrievalAugmentationAdvisor 作为主要入口点 - 采用可组合组件的函数式编程原则

依赖结构

依赖层次结构可以总结如下

  • spring-ai-commons (基础)

  • spring-ai-model (依赖于 commons)

  • spring-ai-vector-storespring-ai-client-chat (都依赖于 model)

  • spring-ai-advisors-vector-storespring-ai-rag (都依赖于 client-chat 和 vector-store)

  • spring-ai-model-chat-memory-* 模块 (依赖于 client-chat)

ToolContext 更改

ToolContext 类已得到增强,支持显式和隐式工具解析。现在工具可以是

  1. 显式包含:在 prompt 中显式请求并包含在对模型的调用中的工具。

  2. 隐式可用:在运行时动态解析时可用的工具,但除非显式请求,否则永远不会包含在对模型的任何调用中。

从 1.0.0-M7 开始,工具只有在 prompt 中显式请求或在调用中显式包含时才包含在对模型的调用中。

此外,ToolContext 类现在已被标记为 final,不能再被继承。它原本就不应该被子类化。在实例化 ToolContext 时,您可以以 Map<String, Object> 的形式添加所有您需要的上下文数据。更多信息请查阅[文档](docs.spring.io/spring-ai/reference/api/tools.html#_tool_context)。

升级到 1.0.0-M6

Usage 接口和 DefaultUsage 实现的变更

Usage 接口及其默认实现 DefaultUsage 已进行以下变更:

  1. 方法重命名

    • getGenerationTokens() 现在是 getCompletionTokens()

  2. 类型变更

    • DefaultUsage 中的所有 token 计数字段从 Long 变更为 Integer

      • promptTokens

      • completionTokens (之前是 generationTokens)

      • totalTokens

所需操作

  • 将所有对 getGenerationTokens() 的调用替换为 getCompletionTokens()

  • 更新 DefaultUsage 构造函数调用

// Old (M5)
new DefaultUsage(Long promptTokens, Long generationTokens, Long totalTokens)

// New (M6)
new DefaultUsage(Integer promptTokens, Integer completionTokens, Integer totalTokens)
有关 Usage 处理的更多信息,请参考此处

JSON 序列化/反序列化变更

虽然 M6 保持了 generationTokens 字段的 JSON 反序列化向后兼容性,但该字段将在 M7 中移除。任何使用旧字段名持久化的 JSON 文档应更新为使用 completionTokens

新 JSON 格式示例

{
  "promptTokens": 100,
  "completionTokens": 50,
  "totalTokens": 150
}

工具调用的 FunctionCallingOptions 使用变更

每个 ChatModel 实例在构造时接受一个可选的 ChatOptionsFunctionCallingOptions 实例,可用于配置调用模型的默认工具。

1.0.0-M6 之前

  • 通过默认 FunctionCallingOptions 实例的 functions() 方法传递的任何工具都会包含在对该 ChatModel 实例进行的每次模型调用中,可能会被运行时选项覆盖。

  • 通过默认 FunctionCallingOptions 实例的 functionCallbacks() 方法传递的任何工具仅可用于运行时动态解析(参见 工具解析),除非明确请求,否则不会包含在对模型的任何调用中。

从 1.0.0-M6 开始

  • 现在,通过默认 FunctionCallingOptions 实例的 functions() 方法或 functionCallbacks() 传递的任何工具都以相同的方式处理:它们会包含在对该 ChatModel 实例进行的每次模型调用中,可能会被运行时选项覆盖。这样,工具包含在模型调用中的方式保持一致,并避免了由于 functionCallbacks() 和所有其他选项之间的行为差异而引起的任何混淆。

如果您希望某个工具可用于运行时动态解析,并且只在明确请求时才将其包含在对模型的聊天请求中,您可以使用 工具解析 中描述的策略之一。

1.0.0-M6 引入了处理工具调用的新 API。旧 API 在所有场景下都保持向后兼容性,但上述场景除外。旧 API 仍然可用,但已被标记为弃用,并将在 1.0.0-M7 中移除。

移除弃用的 Amazon Bedrock 聊天模型

从 1.0.0-M6 开始,Spring AI 过渡到在 Spring AI 中使用 Amazon Bedrock 的 Converse API 来实现所有聊天对话。所有 Amazon Bedrock 聊天模型都被移除,Cohere 和 Titan 的 Embedding 模型除外。

有关使用聊天模型的说明,请参考 Bedrock Converse 文档。

依赖管理变更为使用 Spring Boot 3.4.2

Spring AI 更新为使用 Spring Boot 3.4.2 进行依赖管理。您可以参考 此处 了解 Spring Boot 3.4.2 管理的依赖项。

所需操作

  • 如果您正在升级到 Spring Boot 3.4.2,请务必参考 文档了解配置 REST 客户端所需的更改。特别是,如果您的 classpath 中没有 HTTP 客户端库,这可能会导致使用 JdkClientHttpRequestFactory,而之前会使用 SimpleClientHttpRequestFactory。要切换回使用 SimpleClientHttpRequestFactory,您需要设置 spring.http.client.factory=simple

  • 如果您正在使用不同版本的 Spring Boot(例如 Spring Boot 3.3.x)并且需要特定版本的依赖项,可以在构建配置中覆盖它。

Vector Store API 变更

在 1.0.0-M6 版本中,VectorStore 接口中的 delete 方法已修改为 void 操作,不再返回 Optional<Boolean>。如果您的代码之前检查了删除操作的返回值,您需要移除此检查。如果删除失败,该操作现在会抛出异常,提供更直接的错误处理。

1.0.0-M6 之前

Optional<Boolean> result = vectorStore.delete(ids);
if (result.isPresent() && result.get()) {
    // handle successful deletion
}

在 1.0.0-M6 及之后

vectorStore.delete(ids);
// deletion successful if no exception is thrown

升级到 1.0.0.M5

  • Vector Builders 已重构以保持一致性。

  • 当前的 VectorStore 实现构造函数已被弃用,请使用 Builder 模式。

  • VectorStore 实现包已移至唯一的包名下,避免跨 Artifact 冲突。例如,从 org.springframework.ai.vectorstore 移至 org.springframework.ai.pgvector.vectorstore

升级到 1.0.0.RC3

  • 可移植聊天选项(frequencyPenaltypresencePenaltytemperaturetopP)的类型已从 Float 变更为 Double

升级到 1.0.0.M2

  • Chroma Vector Store 的配置前缀已从 spring.ai.vectorstore.chroma.store 变更为 spring.ai.vectorstore.chroma,以与其他 Vector Store 的命名约定保持一致。

  • Vector Store 中能够初始化 schema 的 initialize-schema 属性的默认值现在设置为 false。这意味着如果期望在应用程序启动时创建 schema,应用程序现在需要明确选择加入(opt-in)对支持的 Vector Store 进行 schema 初始化。并非所有 Vector Store 都支持此属性。更多详情请参阅相应的 Vector Store 文档。以下是当前不支持 initialize-schema 属性的 Vector Store:

    1. Hana

    2. Pinecone

    3. Weaviate

  • 在 Bedrock Jurassic 2 中,聊天选项 countPenaltyfrequencyPenaltypresencePenalty 已重命名为 countPenaltyOptionsfrequencyPenaltyOptionspresencePenaltyOptions。此外,聊天选项 stopSequences 的类型已从 String[] 变更为 List<String>

  • 在 Azure OpenAI 中,聊天选项 frequencyPenaltypresencePenalty 的类型已从 Double 变更为 Float,与其他所有实现保持一致。

升级到 1.0.0.M1

在迈向发布 1.0.0 M1 的过程中,我们进行了一些破坏性变更。抱歉,但这是为了更好地发展!

ChatClient 变更

进行了一项重大变更,将“旧的” ChatClient 的功能移至 ChatModel。“新的” ChatClient 现在接受一个 ChatModel 实例。这样做是为了支持一种流畅的 API,以便以类似于 Spring 生态系统中其他客户端类(如 RestClientWebClientJdbcClient)的方式创建和执行 prompt。有关流畅 API 的更多信息,请参阅 JavaDoc,完整的参考文档即将发布。

我们将“旧的” ModelClient 重命名为 Model,并重命名了实现类,例如 ImageClient 重命名为 ImageModelModel 实现代表了在 Spring AI API 和底层 AI 模型 API 之间进行转换的可移植层。

适应变更

ChatClient 类现在位于 org.springframework.ai.chat.client 包中

方法一

现在,您将不再获得自动配置的 ChatClient 实例,而是获得一个 ChatModel 实例。重命名后的 call 方法签名保持不变。为了适应您的代码,您应该重构代码,将 ChatClient 类型的使用更改为 ChatModel。以下是更改前现有代码的示例:

@RestController
public class OldSimpleAiController {

    private final ChatClient chatClient;

    public OldSimpleAiController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/ai/simple")
    Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", this.chatClient.call(message));
    }
}

更改后将如下所示:

@RestController
public class SimpleAiController {

    private final ChatModel chatModel;

    public SimpleAiController(ChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/simple")
    Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", this.chatModel.call(message));
    }
}
重命名也适用于以下类:* StreamingChatClientStreamingChatModel * EmbeddingClientEmbeddingModel * ImageClientImageModel * SpeechClientSpeechModel * 以及其他类似的 <XYZ>Client

方法二

在此方法中,您将使用“新的” ChatClient 上提供的新流畅 API

以下是更改前现有代码的示例:

@RestController
class OldSimpleAiController {

    ChatClient chatClient;

    OldSimpleAiController(ChatClient chatClient) {
        this.chatClient = chatClient;
	}

	@GetMapping("/ai/simple")
	Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
		return Map.of(
                "generation",
				this.chatClient.call(message)
        );
	}
}

更改后将如下所示:

@RestController
class SimpleAiController {

    private final ChatClient chatClient;

    SimpleAiController(ChatClient.Builder builder) {
      this.chatClient = builder.build();
    }

    @GetMapping("/ai/simple")
    Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of(
                "generation",
				this.chatClient.prompt().user(message).call().content()
        );
    }
}
通过自动配置,您可以获取到 ChatModel 实例。

方法三

GitHub 仓库中有一个名为 v1.0.0-SNAPSHOT-before-chatclient-changes 的标签,您可以 checkout 并进行本地构建,以避免更新任何代码,直到您准备好迁移您的代码库。

git checkout tags/v1.0.0-SNAPSHOT-before-chatclient-changes

./mvnw clean install -DskipTests

Artifact 名称变更

POM Artifact 名称已重命名:- spring-ai-qdrant → spring-ai-qdrant-store - spring-ai-cassandra → spring-ai-cassandra-store - spring-ai-pinecone → spring-ai-pinecone-store - spring-ai-redis → spring-ai-redis-store - spring-ai-qdrant → spring-ai-qdrant-store - spring-ai-gemfire → spring-ai-gemfire-store - spring-ai-azure-vector-store-spring-boot-starter → spring-ai-azure-store-spring-boot-starter - spring-ai-redis-spring-boot-starter → spring-ai-starter-vector-store-redis

升级到 0.8.1

spring-ai-vertex-ai 已重命名为 spring-ai-vertex-ai-palm2spring-ai-vertex-ai-spring-boot-starter 已重命名为 spring-ai-vertex-ai-palm2-spring-boot-starter

因此,您需要将依赖项从

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-vertex-ai</artifactId>
</dependency>

更改为

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-vertex-ai-palm2</artifactId>
</dependency>

并且 Palm2 模型相关的 Boot starter 已从

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-vertex-ai-spring-boot-starter</artifactId>
</dependency>

更改为

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-vertex-ai-palm2-spring-boot-starter</artifactId>
</dependency>
  • 类重命名 (2024年3月1日)

    • VertexAiApi → VertexAiPalm2Api

    • VertexAiClientChat → VertexAiPalm2ChatClient

    • VertexAiEmbeddingClient → VertexAiPalm2EmbeddingClient

    • VertexAiChatOptions → VertexAiPalm2ChatOptions

升级到 0.8.0

2024年1月24日更新

  • promptmessagesmetadata 包移至 org.springframework.ai.chat 的子包中

  • 新增功能是文本转图片客户端。类包括 OpenAiImageModelStabilityAiImageModel。请参阅集成测试了解用法,文档即将发布。

  • 新增一个 model 包,其中包含接口和基类,支持为任意输入/输出数据类型组合创建 AI Model 客户端。目前,chat 和 image model 包已实现了这一点。我们很快会将 embedding 包更新到这个新模型。

  • 新的“可移植选项”设计模式。我们希望在不同基于聊天的 AI 模型之间尽可能地提高 ModelCall 的可移植性。有一组通用的生成选项,然后还有一些特定于模型提供商的选项。采用了一种类似“鸭子类型”的方法。model 包中的 ModelOptions 是一个标记接口,表明此类的实现将为模型提供选项。请参阅 ImageOptions,它是一个子接口,定义了所有 text→image ImageModel 实现的可移植选项。然后 StabilityAiImageOptionsOpenAiImageOptions 提供了特定于每个模型提供商的选项。所有选项类都通过流畅的 API Builder 创建,都可以传递给可移植的 ImageModel API。这些选项数据类型用于 ImageModel 实现的自动配置/配置属性。

2024年1月13日更新

以下 OpenAi 自动配置聊天属性已变更:

  • spring.ai.openai.model 变更为 spring.ai.openai.chat.options.model

  • spring.ai.openai.temperature 变更为 spring.ai.openai.chat.options.temperature

查找有关 OpenAi 属性的更新文档:docs.spring.io/spring-ai/reference/api/chat/openai-chat.html

2023年12月27日更新

合并 SimplePersistentVectorStore 和 InMemoryVectorStore 到 SimpleVectorStore * 用 SimpleVectorStore 替换 InMemoryVectorStore

2023年12月20日更新

重构 Ollama 客户端及相关类和包名

  • 将 org.springframework.ai.ollama.client.OllamaClient 替换为 org.springframework.ai.ollama.OllamaModelCall。

  • OllamaChatClient 方法签名已更改。

  • 将 org.springframework.ai.autoconfigure.ollama.OllamaProperties 重命名为 org.springframework.ai.model.ollama.autoconfigure.OllamaChatProperties,并将后缀更改为:spring.ai.ollama.chat。部分属性也已更改。

2023年12月19日更新

AiClient 及相关类和包名重命名

  • 将 AiClient 重命名为 ChatClient

  • 将 AiResponse 重命名为 ChatResponse

  • 将 AiStreamClient 重命名为 StreamingChatClient

  • 将 org.sf.ai.client 包重命名为 org.sf.ai.chat

重命名 Artifact ID:

  • transformers-embedding 重命名为 spring-ai-transformers

将 Maven 模块从顶级目录和 embedding-clients 子目录全部移至单个 models 目录下。

2023年12月1日

我们正在转换项目的 Group ID

  • org.springframework.experimental.ai

  • org.springframework.ai

Artifacts 将继续托管在如下所示的 snapshot 仓库中。

主分支将迁移到版本 0.8.0-SNAPSHOT。它将在未来一两周内不稳定。如果您不想使用最新版本,请使用 0.7.1-SNAPSHOT。

您可以像以前一样访问 0.7.1-SNAPSHOT Artifacts,并仍然访问 0.7.1-SNAPSHOT 文档

0.7.1-SNAPSHOT 依赖项

  • Azure OpenAI

    <dependency>
        <groupId>org.springframework.experimental.ai</groupId>
        <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
        <version>0.7.1-SNAPSHOT</version>
    </dependency>
  • OpenAI

    <dependency>
        <groupId>org.springframework.experimental.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        <version>0.7.1-SNAPSHOT</version>
    </dependency>