1. 概述

随着人工智能技术的快速发展,现代应用越来越多地集成大型语言模型来增强智能化能力。虽然单一LLM能够处理多种任务,但在实际生产环境中,依赖单个模型往往不是最优选择。

不同模型在技术专长、响应质量和成本效益方面各有侧重:某些模型擅长技术分析和代码生成,而另一些则在创意写作和对话交互方面表现更佳。对于简单查询任务,轻量级模型能够提供更好的性价比;而对于复杂推理需求,则需要调用更强大的模型来处理。

本文将详细演示如何利用Spring AI框架,在Spring Boot应用中集成多个LLM提供者。我们将涵盖跨供应商模型配置以及同一供应商内多模型管理的实现方案,并在此基础上构建具备故障自动切换能力的弹性聊天机器人系统。

2. 配置不同供应商的LLM

2.1. 主LLM配置

首先配置OpenAI作为主要语言模型提供者。在项目pom.xml中添加必要的依赖:

xml

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

该starter依赖封装了OpenAI Chat Completions API,为应用与OpenAI模型的交互提供了便捷的接入方式。

在application.yaml中配置相关参数:

yaml

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

我们使用属性占位符从环境变量加载敏感配置,并将温度参数设置为1,以适配新版OpenAI模型的默认要求。

完成基础配置后,Spring AI会自动创建OpenAiChatModel实例。基于此,我们定义主ChatClient bean:

java

@Configuration
class ChatbotConfiguration {

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

通过@Primary注解标记该bean,确保在未显式指定Qualifier时,Spring会自动注入此主聊天客户端。

2.2. 次级LLM配置

接下来配置Anthropic作为备用模型提供者。首先添加对应依赖:

xml

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

该依赖封装了Anthropic Message API,提供了与Anthropic系列模型交互的必要组件。

配置次级模型参数:

yaml

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

创建专用的次级ChatClient:

java

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

3. 配置同一供应商的多个LLM

在实际场景中,经常需要配置同一供应商的多个模型实例。Spring AI的自动配置机制默认每个供应商只创建单一ChatModel bean,因此需要手动配置额外实例。

首先在配置文件中定义第三个模型参数:

yaml

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

然后手动创建对应的ChatModel和ChatClient bean:

java

@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);
}

此配置假设多个Anthropic模型共享相同的API密钥和基础配置。如需差异化配置,可进一步自定义AnthropicChatOptions中的各项参数。

4. 实践应用:构建弹性聊天机器人

4.1. 实现故障切换机制

利用Spring Retry实现模型的自动故障切换。创建ChatbotService并注入配置好的多个ChatClient实例:

java

@Retryable(retryFor = Exception.class, maxAttempts = 3)
String chat(String prompt) {
    logger.debug("正在使用主LLM处理提示'{}',尝试次数#{}",
        prompt, RetrySynchronizationManager.getContext().getRetryCount() + 1);
    return primaryChatClient
      .prompt(prompt)
      .call()
      .content();
}

chat方法通过@Retryable注解配置了异常重试机制,在遇到任何Exception时最多重试三次。

定义恢复处理方法:

java

@Recover
String chat(Exception exception, String prompt) {
    logger.warn("主LLM处理失败,错误信息: {}", exception.getMessage());
    logger.debug("正在尝试使用次级LLM处理提示'{}'", prompt);
    try {
        return secondaryChatClient
          .prompt(prompt)
          .call()
          .content();
    } catch (Exception e) {
        logger.warn("次级LLM处理失败: {}", e.getMessage());
        logger.debug("正在尝试使用第三LLM处理提示'{}'", prompt);
        return tertiaryChatClient
          .prompt(prompt)
          .call()
          .content();
    }
}

使用@Recover注解标记的恢复方法在主方法耗尽重试次数后接管处理。系统会依次尝试次级和第三LLM,确保服务的连续性。

暴露REST API接口:

java

@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接口接收用户提示,通过服务层处理并返回格式化响应。

4.2. 系统验证测试

通过环境变量启动应用,模拟故障场景:

bash

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

在此配置中,前两个模型名称设置为无效值,第三个模型使用有效的Anthropic模型。

使用HTTP客户端测试接口:

bash

http POST :8080/api/chatbot/chat prompt="法国的首都是哪里?"

系统返回正确响应:

json

{
    "response": "法国的首都是巴黎。"
}

观察应用日志可见完整的故障切换流程:

text

[DEBUG] 正在使用主LLM处理提示'法国的首都是哪里?',尝试次数#1
[DEBUG] 正在使用主LLM处理提示'法国的首都是哪里?',尝试次数#2  
[DEBUG] 正在使用主LLM处理提示'法国的首都是哪里?',尝试次数#3
[WARN] 主LLM处理失败,错误信息: HTTP 404 - {"error":{"message":"模型`gpt-100`不存在或您无权访问"}}
[DEBUG] 正在尝试使用次级LLM处理提示'法国的首都是哪里?'
[WARN] 次级LLM处理失败: HTTP 404 - {"type":"error","error":{"type":"not_found_error","message":"model: claude-opus-200"}}
[DEBUG] 正在尝试使用第三LLM处理提示'法国的首都是哪里?'

日志清晰展示了系统的弹性机制:主模型重试失败后,自动切换到次级模型,最终通过第三模型成功处理请求。

5. 总结

本文详细探讨了在Spring AI应用中集成多个LLM的技术方案。通过Spring AI的抽象层,我们简化了不同供应商模型的集成复杂度,并实现了同一供应商内多实例的配置管理。

基于此基础架构,我们构建了具备故障自动切换能力的弹性聊天机器人,通过Spring Retry实现了模型的降级恢复机制。这种设计模式确保了系统在部分组件故障时仍能保持服务可用性,为生产环境提供了可靠的保障。

多模型架构不仅提升了系统的容错能力,还为企业提供了根据业务需求灵活调配计算资源的可能性,在成本控制和性能优化之间找到了最佳平衡点。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐