升級說明

升級到 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>