application.yml

----------------------------------------------------

默认的 Spring AI OpenAI 配置 (可选,如果您仍然需要一个默认实例)

Spring Boot 会根据此配置自动创建一个默认的 OpenAiChatModel 和 ChatClient bean

----------------------------------------------------

spring:
  ai:
    openai:
      chat:
        options:
          model: gpt-4o-mini # 默认模型
      api-key: sk-default-openai-key # 默认API Key
      base-url: https://api.openai.com/v1 # 默认Base URL

----------------------------------------------------

自定义配置:用于创建多个相同类型(OpenAI)的 AI 模型实例

我们使用 ‘app.ai.openai-configs’ 前缀来定义一个列表,每个元素代表一个模型配置

----------------------------------------------------

app:
  ai:
    openai-configs:
      # 第一个自定义模型配置
      - name: my-model-1 # 为这个模型实例指定一个名称
        api-key: sk-your-key-for-model1 # 替换为你的第一个API Key
        base-url: https://api.openai.com/v1 # 模型的服务地址
        options:
          model: gpt-3.5-turbo # 使用的模型名称
          temperature: 0.7 # 模型温度参数# 第二个自定义模型配置
      - name: my-model-2 # 为这个模型实例指定另一个名称
        api-key: sk-your-key-for-model2 # 替换为你的第二个API Key
        base-url: https://custom-endpoint.openai.com/v1 # 可以是不同的服务地址或代理地址
        options:
          model: gpt-4o # 使用的不同模型名称
          temperature: 0.9 # 不同的温度参数
          topP: 0.95 # 其他选项
// MultipleChatModelConfig.java
package com.example.springai.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Qualifier; // 用于注入特定名称的 Bean
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 这是一个 Spring 配置类,用于根据 YAML 配置创建多个 OpenAiChatModel 和 ChatClient 实例。
 */
 @Data
@Configuration
public class MultipleChatModelConfig {

    /**
     * 定义一个内部类,用于映射 YAML 中单个 OpenAI 模型配置的属性。
     */
    public static class OpenAiConfigProperties {
        private String name; // 模型的唯一名称
        private String apiKey; // API Key
        private String baseUrl; // Base URL
        private Map<String, Object> options; // 模型选项,如 model, temperature 等
 
    }

    /**
     * 定义一个内部类,用于绑定 `app.ai` 前缀下的所有自定义 AI 配置。
     * `openai-configs` 将被映射到一个 `OpenAiConfigProperties` 对象的列表。
     */
    @ConfigurationProperties(prefix = "app.ai")
    public static class AppAiProperties {
        private List<OpenAiConfigProperties> openaiConfigs;

        // Getters 和 Setters
        public List<OpenAiConfigProperties> getOpenaiConfigs() { return openaiConfigs; }
        public void setOpenaiConfigs(List<OpenAiConfigProperties> openaiConfigs) { this.openaiConfigs = openaiConfigs; }
    }

    /**
     * 将 AppAiProperties 注册为 Spring Bean,以便 Spring Boot 可以绑定 YAML 配置。
     * @return 绑定了配置的 AppAiProperties 实例
     */
    @Bean
    public AppAiProperties appAiProperties() {
        return new AppAiProperties();
    }

    /**
     * 根据 `AppAiProperties` 中定义的配置列表,动态创建并注册多个 ChatClient Bean。
     * 这些 ChatClient 将被存储在一个 Map 中,键是模型名称,值是对应的 ChatClient 实例。
     *
     * @param appAiProperties 包含所有自定义模型配置的属性对象
     * @return 一个 Map,其中包含所有命名 ChatClient 实例
     */
    @Bean
    public Map<String, ChatClient> namedChatClients(AppAiProperties appAiProperties) {
        // 如果没有配置,则返回一个空 Map
        if (appAiProperties.getOpenaiConfigs() == null) {
            System.out.println("未找到 app.ai.openai-configs 配置。");
            return Map.of();
        }

        System.out.println("正在创建自定义 ChatClient 实例...");
        return appAiProperties.getOpenaiConfigs().stream()
            .collect(Collectors.toMap(
                OpenAiConfigProperties::getName, // 使用配置中定义的 'name' 作为 Map 的键
                config -> {
                    System.out.println("  - 创建模型: " + config.getName() + " (Base URL: " + config.getBaseUrl() + ", Model: " + config.getOptions().get("model") + ")");

                    // 1. 创建 OpenAiApi 实例
                    OpenAiApi openAiApi = new OpenAiApi(config.getBaseUrl(), config.getApiKey());

                    // 2. 创建 OpenAiChatOptions 实例
                    // 从 Map 中提取选项,并转换为 OpenAiChatOptions 对象
                    OpenAiChatOptions.Builder optionsBuilder = OpenAiChatOptions.builder();
                    if (config.getOptions() != null) {
                        if (config.getOptions().containsKey("model")) {
                            optionsBuilder.withModel((String) config.getOptions().get("model"));
                        }
                        if (config.getOptions().containsKey("temperature")) {
                            Object temp = config.getOptions().get("temperature");
                            if (temp instanceof Number) {
                                optionsBuilder.withTemperature(((Number) temp).floatValue());
                            }
                        }
                        if (config.getOptions().containsKey("topP")) {
                            Object topP = config.getOptions().get("topP");
                            if (topP instanceof Number) {
                                optionsBuilder.withTopP(((Number) topP).floatValue());
                            }
                        }
                        // 如果有其他 ChatOptions,可以在这里继续添加映射
                    }
                    OpenAiChatOptions chatOptions = optionsBuilder.build();

                    // 3. 创建 OpenAiChatModel 实例
                    OpenAiChatModel chatModel = new OpenAiChatModel(openAiApi, chatOptions);

                    // 4. 创建并返回 ChatClient 实例
                    return ChatClient.builder(chatModel)
                        .defaultSystemPrompt("您是一个由 " + config.getName() + " 提供支持的有用助手。")
                        .build();
                }
            ));
    }
}
```java
// ChatClientService.java
package com.example.springai.service;

import org.springframework.stereotype.Service;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; // 虽然这里直接注入 Map,但理解 @Qualifier 对单个命名 Bean 很有用
import java.util.Map;

/**
 * 这是一个服务类,演示如何注入和使用多个命名 ChatClient 实例。
 */
@Service
public class ChatClientService {

    // 注入由 MultipleChatModelConfig 创建的 Map<String, ChatClient> Bean
    private final Map<String, ChatClient> namedChatClients;

    @Autowired
    public ChatClientService(Map<String, ChatClient> namedChatClients) {
        this.namedChatClients = namedChatClients;
        System.out.println("ChatClientService 已初始化,可用模型: " + namedChatClients.keySet());
    }

    /**
     * 根据模型名称生成聊天响应。
     * @param modelName 要使用的模型名称(例如:"my-model-1", "my-model-2")
     * @param userMessage 用户的消息
     * @return 模型的响应内容
     */
    public String generateResponse(String modelName, String userMessage) {
        ChatClient client = namedChatClients.get(modelName); // 从 Map 中获取对应的 ChatClient 实例
        if (client == null) {
            System.err.println("错误: 未找到名为 '" + modelName + "' 的 Chat 客户端。");
            return "错误: 未找到名为 '" + modelName + "' 的 Chat 客户端。请检查配置或模型名称。";
        }

        System.out.println("使用模型 '" + modelName + "' 生成响应...");
        try {
            // 使用 ChatClient 发送消息并获取响应
            return client.prompt()
                    .user(userMessage)
                    .call()
                    .content();
        } catch (Exception e) {
            System.err.println("使用模型 '" + modelName + "' 生成响应时发生错误: " + e.getMessage());
            return "生成响应时发生错误: " + e.getMessage();
        }
    }

    // ----------------------------------------------------
    // 您可以在 Spring Boot 应用的主类或控制器中调用此服务进行测试:
    // ----------------------------------------------------
    /*
    // 假设这是您的 Spring Boot 主应用类
    @SpringBootApplication
    public class MyApplication implements CommandLineRunner {

        @Autowired
        private ChatClientService chatClientService;

        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }

        @Override
        public void run(String... args) throws Exception {
            System.out.println("\n--- 测试模型 'my-model-1' ---");
            String response1 = chatClientService.generateResponse("my-model-1", "你好,请自我介绍一下。");
            System.out.println("Model 1 响应: " + response1);

            System.out.println("\n--- 测试模型 'my-model-2' ---");
            String response2 = chatClientService.generateResponse("my-model-2", "讲一个关于人工智能的简短笑话。");
            System.out.println("Model 2 响应: " + response2);

            System.out.println("\n--- 测试不存在的模型 ---");
            String response3 = chatClientService.generateResponse("non-existent-model", "这能工作吗?");
            System.out.println("不存在的模型响应: " + response3);
        }
    }
    */
}
// 如果您想快速测试,可以把这个放在一个简单的 Spring Boot 应用主类中
// SpringAiMultipleModelsApplication.java
package com.example.springai;

import com.example.springai.service.ChatClientService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication
public class SpringAiMultipleModelsApplication implements CommandLineRunner {

    @Autowired
    private ChatClientService chatClientService;

    public static void main(String[] args) {
        SpringApplication.run(SpringAiMultipleModelsApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("\n--- 测试模型 'my-model-1' ---");
        String response1 = chatClientService.generateResponse("my-model-1", "你好,请自我介绍一下。");
        System.out.println("模型 1 响应: " + response1);

        System.out.println("\n--- 测试模型 'my-model-2' ---");
        String response2 = chatClientService.generateResponse("my-model-2", "讲一个关于人工智能的简短笑话。");
        System.out.println("模型 2 响应: " + response2);

        System.out.println("\n--- 测试不存在的模型 ---");
        String response3 = chatClientService.generateResponse("non-existent-model", "这能工作吗?");
        System.out.println("不存在的模型响应: " + response3);
    }
}
<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version> <!-- 使用与 Spring AI 兼容的 Spring Boot 版本 -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-ai-multiple-models</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-ai-multiple-models</name>
    <description>Demo project for Spring AI multiple models</description>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>0.8.1</spring-ai.version> <!-- 确保使用与 Spring Boot 3.2.x 兼容的 Spring AI 版本 -->
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Spring AI OpenAI 依赖 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>


Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐