中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

如何(he)在(zai) Spring Boot 應用中(zhong)配置多個 Spring AI 的(de) LLM 客戶端

1. 概述

越來越多的(de)(de)現(xian)代應用開始集成大型(xing)語言模型(xing)(LLM),以(yi)構建更智能的(de)(de)功能。如何使(shi)用Spring AI快速整合LLM能力(li)到自己的(de)(de)Spring Boot應用,在之(zhi)前的(de)(de)博文中有過很(hen)多篇關于。雖(sui)然一(yi)個(ge) LLM 能勝任(ren)多種任(ren)務(wu),但只依賴單一(yi)模型(xing)并(bing)不總是最優。

不(bu)同模(mo)型各(ge)有側重:有的(de)擅長技(ji)術分(fen)析(xi),有的(de)更(geng)適合創意寫作。簡單任(ren)務更(geng)適合輕(qing)量、性價比(bi)高的(de)模(mo)型;復雜任(ren)務則交給更(geng)強(qiang)大(da)的(de)模(mo)型。

本(ben)文將演示如何借助 Spring AI,在 Spring Boot 應用(yong)中(zhong)集成多(duo)個 LLM。

我們既(ji)會配置來自不同供應(ying)商(shang)的(de)模(mo)型,也會配置同一供應(ying)商(shang)下(xia)的(de)多個模(mo)型。隨(sui)后基于這些配置,構建一個具(ju)備彈性的(de)聊天機器人(ren),在故障時可自動在模(mo)型間切(qie)換。

2. 配置不同供應商的 LLM

我們先在應用(yong)中配置來自不同供應商(shang)的兩(liang)個(ge) LLM。

在本文示例中,我們將使用 OpenAI 和 Anthropic 作為 AI 模型提供商

2.1. 配置主 LLM

我們先將一個 OpenAI 模型配置為(wei)主(zhu) LLM。

首先,在項目的 pom.xml 文件中(zhong)添加所需依(yi)賴(lai):

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
    <version>1.0.2</version>
</dependency>

該 是對  的(de)封裝,使我們能夠在應(ying)用(yong)中與 OpenAI 模(mo)型交互(hu)。

接著,在 application.yaml 中配(pei)置我們的 OpenAI API Key 和聊天(tian)模型:

spring:
  ai:
    open-ai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: ${PRIMARY_LLM}
          temperature: 1

我們使用 ${} 屬性占位符從環境變量中加載屬性值。另外,我們將溫度設置為 1,因為較新的(de) OpenAI 模型。

在完成上述屬性配置后,Spring AI 會自動創建一個 OpenAiChatModel 類型的 bean。我們使用它來定義一個 ChatClient bean,作為與 LLM 交互的主要入口

@Configuration
class ChatbotConfiguration {

    @Bean
    @Primary
    ChatClient primaryChatClient(OpenAiChatModel chatModel) {
        return ChatClient.create(chatModel);
    }
}

ChatbotConfiguration 類中,我們使用 OpenAiChatModel bean 創建了主 LLM 的 ChatClient

我們使用 @Primary 注解標記該 bean。當在組件中注入 ChatClient 且未使用 Qualifier 時,Spring Boot 會自動注入它。

2.2. 配置次級 LLM

現(xian)在(zai),我們將配置一個來(lai)自(zi) Anthropic 的模型作為(wei)次級(ji) LLM。

首先,在 pom.xml 中添加 :

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-anthropic</artifactId>
    <version>1.0.2</version>
</dependency>

該依賴是(shi)對 的(de)封裝,提(ti)供了(le)與 Anthropic 模型建立(li)連接并交互所需(xu)的(de)類。

接著,為次(ci)級模(mo)型(xing)定義配置屬(shu)性:

spring:
  ai:
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
      chat:
        options:
          model: ${SECONDARY_LLM}

與主(zhu) LLM 的配置類似,我們從環(huan)境(jing)變量中加(jia)載 和模型 ID。

最后,為次級模型創建一個專用的 ChatClient bean

@Bean
ChatClient secondaryChatClient(AnthropicChatModel chatModel) {
    return ChatClient.create(chatModel);
}

這里,我們使用 Spring AI 自動配置的 AnthropicChatModel bean 創建了 secondaryChatClient

3. 配置同一供應商的多個 LLM

很多時候,我們需要配置的多個 LLM 可能來自同一 AI 供應商

Spring AI 并不原生支持這種場景,其自動配置每個供應商只會創建一個 ChatModel bean。因此,對于額外的模型,我們需要手動定義 ChatModel bean。

讓我們來看看具體過程,并在應用中配置第二個 Anthropic 模型

spring:
  ai:
    anthropic:
      chat:
        options:
          tertiary-model: ${TERTIARY_LLM}

application.yaml 的 Anthropic 配置下,我們添加了一個自定義屬性來保存第三個(tertiary)LLM 的模型名稱

接(jie)著,為第三個 LLM 定義必要的 bean:

@Bean
ChatModel tertiaryChatModel(
    AnthropicApi anthropicApi,
    AnthropicChatModel anthropicChatModel,
    @Value("${spring.ai.anthropic.chat.options.tertiary-model}") String tertiaryModelName
) {
    AnthropicChatOptions chatOptions = anthropicChatModel.getDefaultOptions().copy();
    chatOptions.setModel(tertiaryModelName);
    return AnthropicChatModel.builder()
      .anthropicApi(anthropicApi)
      .defaultOptions(chatOptions)
      .build();
}

@Bean
ChatClient tertiaryChatClient(@Qualifier("tertiaryChatModel") ChatModel tertiaryChatModel) {
    return ChatClient.create(tertiaryChatModel);
}

首先,為創建自定義的 ChatModel bean,我們注入自動配置的 AnthropicApi bean、用于創建次級 LLM 的默認 AnthropicChatModel bean,并通過 @Value 注入第三個(ge)模型的名稱屬性(xing)。

我們復制現有 AnthropicChatModel 的默認選項,并僅覆蓋其中的模型名稱

該設置假定兩個 Anthropic 模型共享同一個 API Key 及其他配置。如果需要不同的屬性,可以進一步自定義 AnthropicChatOptions

最后,我們使用自定義的 tertiaryChatModel 在配置類中創建第三個 ChatClient bean。

4. 探索一個實用用例

在完成多模型配置后,讓我們實現一個實用用例。我們將構建一個具備彈性的聊天機器人,當主模型出現故障時可按順序自動回退到替代模型

4.1. 構建具備彈性的聊天機器人

為實現回退邏輯,我們(men)將(jiang)使用(yong) Spring Retry。

創建一個新的 ChatbotService 類,并注入我們定義的三個 ChatClient。接著,定(ding)義一個入口方法使(shi)用主 LLM:

@Retryable(retryFor = Exception.class, maxAttempts = 3)
String chat(String prompt) {
    logger.debug("Attempting to process prompt '{}' with primary LLM. Attempt #{}",
        prompt, RetrySynchronizationManager.getContext().getRetryCount() + 1);
    return primaryChatClient
      .prompt(prompt)
      .call()
      .content();
}

這里,我們創建了一個使用 primaryChatClientchat() 方法。該方法使用 @Retryable 注解,在遇(yu)到(dao)任(ren)意 Exception 時最(zui)多(duo)重(zhong)試(shi)三次。

接(jie)著,定義一(yi)個恢復方法:

@Recover
String chat(Exception exception, String prompt) {
    logger.warn("Primary LLM failure. Error received: {}", exception.getMessage());
    logger.debug("Attempting to process prompt '{}' with secondary LLM", prompt);
    try {
        return secondaryChatClient
          .prompt(prompt)
          .call()
          .content();
    } catch (Exception e) {
        logger.warn("Secondary LLM failure: {}", e.getMessage());
        logger.debug("Attempting to process prompt '{}' with tertiary LLM", prompt);
        return tertiaryChatClient
          .prompt(prompt)
          .call()
          .content();
    }
}

使用 @Recover 注解標記的重載 chat() 方法將作為原始 chat() 方法失敗并耗盡重試后的回退處理

我們首先嘗試通過 secondaryChatClient 獲取響應;如果仍失敗,則最后再嘗試使用 tertiaryChatClient

這里使(shi)用了(le)簡(jian)單(dan)的 try-catch 實現,因為 Spring Retry 每個方(fang)法簽(qian)名只允(yun)許(xu)一個恢復(fu)方(fang)法。但在生產(chan)應用中,我(wo)們應考慮使(shi)用更完善的方(fang)案,例如 Resilience4j。

在完成服務層實現后,我們再對外暴露一個 REST API

@PostMapping("/api/chatbot/chat")
ChatResponse chat(@RequestBody ChatRequest request) {
    String response = chatbotService.chat(request.prompt);
    return new ChatResponse(response);
}

record ChatRequest(String prompt) {}
record ChatResponse(String response) {}

這里定義了一個 POST 接口 /api/chatbot/chat,接收 prompt,將其傳遞到服務層,最后把 response 包裝在 ChatResponse record 中返回。

4.2. 測試我們的聊天機器人

最后,我們來測試聊天機器人,驗證回退機制是否正常工作

通過環境變量啟動應用:為(wei)主、次級 LLM 設(she)置無效(xiao)模(mo)型名稱(cheng),同(tong)時為(wei)第三個 LLM 設(she)置一(yi)個有效(xiao)的模(mo)型名稱(cheng):

OPENAI_API_KEY=.... \
ANTHROPIC_API_KEY=.... \
PRIMARY_LLM=gpt-100 \
SECONDARY_LLM=claude-opus-200 \
TERTIARY_LLM=claude-3-haiku-20240307 \
mvn spring-boot:run

在上述命令中,gpt-100claude-opus-200 是無效的模型名稱,會導致 API 錯誤;而 是 Anthropic 提供的有效模型

接著,使用(yong) HTTPie CLI 調用(yong)接口,與(yu)聊天機器(qi)人(ren)交(jiao)互:

http POST :8080/api/chatbot/chat prompt="What is the capital of France?"

這里我們向聊天(tian)機器人發送(song)一個簡單(dan)的提(ti)示詞,看(kan)看(kan)返(fan)回(hui)結果:

{
    "response": "The capital of France is Paris."
}

可以看到,盡管主、次級 LLM 的配置為無效模型,聊天機器人仍返回了正確響應,這驗證了系統成功回退到了第三個 LLM

為了更直觀(guan)地看到回退(tui)邏輯的執行(xing)過程,我們再來看一下應用日志:

[2025-09-30 12:56:03] [DEBUG] [com.baeldung.multillm.ChatbotService] - Attempting to process prompt 'What is the capital of France?' with primary LLM. Attempt #1
[2025-09-30 12:56:05] [DEBUG] [com.baeldung.multillm.ChatbotService] - Attempting to process prompt 'What is the capital of France?' with primary LLM. Attempt #2
[2025-09-30 12:56:06] [DEBUG] [com.baeldung.multillm.ChatbotService] - Attempting to process prompt 'What is the capital of France?' with primary LLM. Attempt #3
[2025-09-30 12:56:07] [WARN] [com.baeldung.multillm.ChatbotService] - Primary LLM failure. Error received: HTTP 404 - {
    "error": {
        "message": "The model `gpt-100` does not exist or you do not have access to it.",
        "type": "invalid_request_error",
        "param": null,
        "code": "model_not_found"
    }
}
[2025-09-30 12:56:07] [DEBUG] [com.baeldung.multillm.ChatbotService] - Attempting to process prompt 'What is the capital of France?' with secondary LLM
[2025-09-30 12:56:07] [WARN] [com.baeldung.multillm.ChatbotService] - Secondary LLM failure: HTTP 404 - {"type":"error","error":{"type":"not_found_error","message":"model: claude-opus-200"},"request_id":"req_011CTeBrAY8rstsSPiJyv3sj"}
[2025-09-30 12:56:07] [DEBUG] [com.baeldung.multillm.ChatbotService] - Attempting to process prompt 'What is the capital of France?' with tertiary LLM

日(ri)志清晰地展示了請求的(de)執行流程。

可以看到,主 LLM 連續三次嘗試失敗;隨后服務嘗試使用次級 LLM,仍然失敗;最終調用第三個 LLM 處理提示詞并返回了我們看到的響應

這表(biao)明回退機制(zhi)按設計正常工作,即使(shi)多個(ge) LLM 同(tong)時失敗,聊天機器(qi)人(ren)仍(reng)保(bao)持可用。

5. 小結

本(ben)文(wen)探討了如何(he)在(zai)單個 Spring AI 應(ying)用中集成多(duo)(duo)個 LLM。首先,我們(men)演示了 Spring AI 的(de)抽象層如何(he)簡化(hua)來自不同(tong)(tong)供(gong)應(ying)商(shang)(如 OpenAI 與(yu) Anthropic)的(de)模(mo)(mo)型(xing)(xing)配(pei)置(zhi)。隨后,我們(men)解(jie)決(jue)了更復(fu)雜的(de)場景:在(zai)同(tong)(tong)一(yi)(yi)供(gong)應(ying)商(shang)下配(pei)置(zhi)多(duo)(duo)個模(mo)(mo)型(xing)(xing),并(bing)在(zai) Spring AI 的(de)自動配(pei)置(zhi)不夠用時(shi)創(chuang)建自定(ding)義 bean。最后,我們(men)利用多(duo)(duo)模(mo)(mo)型(xing)(xing)配(pei)置(zhi)構建了一(yi)(yi)個具有高可(ke)用性(xing)(xing)的(de)彈性(xing)(xing)聊(liao)天機器(qi)人。借助 Spring Retry,我們(men)實(shi)現了級(ji)聯(lian)回退模(mo)(mo)式,在(zai)發生故障時(shi)可(ke)在(zai)不同(tong)(tong) LLM 間(jian)自動切換。

posted @ 2025-10-10 20:26  程序猿DD  閱讀(1049)  評論(0)    收藏  舉報