当前位置:首页>排行榜>Spring AI 多模型怎么选?ChatClient 动态路由与选型实战

Spring AI 多模型怎么选?ChatClient 动态路由与选型实战

  • 更新时间 2026-10-03 08:06:22
Spring AI 多模型怎么选?ChatClient 动态路由与选型实战
1 为什么需要多模型?

很多团队一开始只接一个模型,比如 GPT-4 或通义千问,觉得够用了。但真正上线之后,问题很快暴露:

简单问答用 GPT-4,成本高得离谱

代码生成任务丢给通用模型,质量差强人意

主模型服务挂了,整个系统直接不可用

单一模型没法兼顾成本、性能、可用性三件事。多模型路由的核心思路很简单:根据请求的特征,动态选择最合适的模型来响应。简单任务用便宜模型,复杂推理走高配模型,主模型故障时自动降级。

本文会从配置到路由策略,一步步讲清楚 Spring AI 里怎么落地这件事。

2 ChatClient 基础:多模型的第一入口

ChatClient 是 Spring AI 的高阶 API,采用构建者模式,支持链式调用,封装了 Prompt 构建和响应处理的细节。理解它的创建方式是实现多模型路由的前提。

2.1 单模型场景

方式一:直接指定使用哪个ChatClient。
方式二:直接使用ChatModel

2.2 多模型场景(本文重点)

pom.xml文件内容
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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>4.1.1</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>com.fgljs</groupId>    <artifactId>multi-platform-and-model-demo</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>multi-platform-and-model-demo</name>    <description>multi-platform-and-model-demo</description>    <properties>        <java.version>17</java.version>        <spring-ai.version>2.0.0</spring-ai.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-webmvc</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-webmvc-test</artifactId>            <scope>test</scope>        </dependency>        <!-- 接入Deepseek的依赖  -->        <dependency>            <groupId>org.springframework.ai</groupId>            <artifactId>spring-ai-starter-model-deepseek</artifactId>        </dependency>        <!-- 接入Ollama的依赖  -->        <dependency>            <groupId>org.springframework.ai</groupId>            <artifactId>spring-ai-starter-model-ollama</artifactId>        </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></project>
application.yml配置文件
spring:  application:    name: spring-ai-ollama-demo  ai:    # Ollama相关配置    ollama:      base-url: http://192.168.0.102:11434      chat:        model: deepseek-r1:7b    # Deepseek相关配置    deepseek:      api-key: ${DEEP_SEEK_KEY}      chat:        # 配置模型名称        model: deepseek-v4-flash        # 配置默认温度        temperature: 0.7        # 最大token数(字数上限)        max-tokens: 400        #stop:        #  - "\n" # 只想要一行        #  - "。" # 只想要一句话        #  - "政治" # 违禁词

MultiPlatformAndModelController.java

package com.fgljs.multiplatformandmodeldemo.controller;import com.fgljs.multiplatformandmodeldemo.pojo.MultiPlatformAndModelOptions;import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.chat.model.ChatModel;import org.springframework.ai.chat.prompt.ChatOptions;import org.springframework.ai.deepseek.DeepSeekChatModel;import org.springframework.ai.ollama.OllamaChatModel;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import reactor.core.publisher.Flux;import java.util.HashMap;@RestControllerpublic class MultiPlatformAndModelController {    HashMap<String, ChatModel> platforms = new HashMap<>();    public MultiPlatformAndModelController(DeepSeekChatModel deepSeekChatModel,                                           OllamaChatModel ollamaChatModel){        platforms.put("ollama", ollamaChatModel);        platforms.put("deepseek", deepSeekChatModel);    }    /**     * 如果不加produces,前端浏览器访问会出现乱码     */    @GetMapping(value = "/chat", produces = "text/stream;charset=UTF-8")    public Flux<String> chat(String message, MultiPlatformAndModelOptions options){        String platform = options.getPlatform();        ChatModel chatModel = platforms.get(platform);        ChatClient.Builder builder = ChatClient.builder(chatModel);        ChatClient chatClient = builder.defaultOptions(                ChatOptions.builder()                        .temperature(options.getTemperature())                        .model(options.getModel())        ).build();        return chatClient.prompt().user(message).stream().content();    }}
访问测试:
浏览器输入:http://localhost:8080/chat?message=%E4%BD%A0%E5%A5%BD&platform=ollama&model=deepseek-r1:7b&temperature=0.8
3 动态路由的核心思路

固定配置多个 ChatClient 只是第一步。真正的动态路由需要在运行时决定用哪个模型。Spring AI 提供了几个关键扩展点。

3.1 策略模式:按业务规则分流

最直接的方式是用策略模式,根据请求特征选择模型。典型的特征包括文本长度、任务类型、用户等级等。

当然除了这种方式,还有3.2和3.3的模式。

3.2 RouterChatModel:Spring AI 内置的路由抽象

Spring AI Core 1.0+ 引入了 RouterChatModel,可以组合多个子模型并配合 RoutingStrategy 使用。它提供了更标准的抽象,适合需要灵活组合路由规则的场景。

核心接口大致是这样的思路:

public class CustomRoutingStrategy implements RoutingStrategy {    @Override    public String selectModel(Prompt prompt) {        String text = prompt.getInstructions().get(0).getText();        // 根据 prompt 内容决定使用哪个模型        if (text.contains("代码") || text.contains("编程")) {            return "claude";        }        if (text.length() > 2000) {            return "gemini"; // 长文本走大上下文模型        }        return "gpt-4o-mini"; // 默认走低成本模型    }}

然后把这个策略注册到 RouterChatModel 中,由它统一管理模型的分发。

3.3 基于配置的运行时切换

对于需要在不停机的情况下切换模型的场景,可以把路由决策做成配置驱动。GitHub 上 Spring AI 社区有一个典型的讨论:如何在不重启进程的情况下动态切换 ChatClient 实现。方案是创建两个 ChatClient Bean,在运行时根据配置或参数做条件判断。

@Servicepublic class DynamicModelService {    private final ChatClient openAiClient;    private final ChatClient anthropicClient;    @Value("${model.router.default:openai}")    private String defaultModel;    public DynamicModelService(            @Qualifier("openAiChatClient") ChatClient openAiClient,            @Qualifier("anthropicChatClient") ChatClient anthropicClient) {        this.openAiClient = openAiClient;        this.anthropicClient = anthropicClient;    }    public ChatClient getClient(String modelName) {        return "anthropic".equalsIgnoreCase(modelName) ? anthropicClient : openAiClient;    }    public ChatClient getDefaultClient() {        return getClient(defaultModel);    }}
4 选型决策框架

说了这么多路由技术,最终还是要回到“选哪个模型”这个根本问题。以下是一个简洁的决策框架,可以直接用在项目中。

按任务类型选:

  • 代码生成与调试 → Claude 系列(代码能力公认最强)或 DeepSeek

  • 通用对话与内容创作 → GPT-4o 或通义千问

  • 轻量问答与分类 → 本地 Ollama 模型(如 Mistral 7B),零 API 成本

  • 长文档分析 → Gemini(支持超长上下文)

按成本敏感度选:

  • 成本优先 → 简单请求走本地模型,降低 50%-70% 的 API 费用

  • 质量优先 → 复杂推理走顶级模型,其余走中等模型

按可用性要求选:

  • 生产环境至少配置两个不同提供商的模型(如 OpenAI + Anthropic,或云端 + 本地)

  • 单一提供商的多个模型不算真正的容灾,因为提供商整体故障时会全部不可用

一个实用的起点配置:

默认模型:GPT-4o-mini(成本低,通用能力够用)

代码任务:Claude Sonnet(质量优先)

降级模型:Ollama + Mistral(本地兜底,零依赖)

5 小结

Spring AI 的多模型支持已经比较成熟。核心操作路径是:

  1. 禁用自动配置,手动创建多个 ChatClient Bean

  2. 用 @Primary 标记默认模型,其他用 @Qualifier 区分

  3. 在业务层实现路由逻辑,策略模式适合规则明确的场景,RouterChatModel 适合需要灵活组合的场景

  4. 加一层故障转移,让多模型架构发挥真正的容灾价值

下一步如果想继续深入,可以研究 Spring AI Alibaba 的多智能体路由模式,以及 LLM 路由 Agent 在复杂意图识别场景中的应用。

【温馨提示】

点赞+关注,私信回复「205」,即可免费获取【multi-platform-and-model-demo.zip】这个项目源码包哦。
有任何建议或意见,欢迎评论区留言或私信飞哥,100%人工回复,感谢支持!
予人玫瑰,手有余香,感谢观看!!!

随机文章