很多团队一开始只接一个模型,比如 GPT-4 或通义千问,觉得够用了。但真正上线之后,问题很快暴露:
简单问答用 GPT-4,成本高得离谱
代码生成任务丢给通用模型,质量差强人意
主模型服务挂了,整个系统直接不可用
单一模型没法兼顾成本、性能、可用性三件事。多模型路由的核心思路很简单:根据请求的特征,动态选择最合适的模型来响应。简单任务用便宜模型,复杂推理走高配模型,主模型故障时自动降级。
本文会从配置到路由策略,一步步讲清楚 Spring AI 里怎么落地这件事。
ChatClient 是 Spring AI 的高阶 API,采用构建者模式,支持链式调用,封装了 Prompt 构建和响应处理的细节。理解它的创建方式是实现多模型路由的前提。
2.1 单模型场景
2.2 多模型场景(本文重点)
<?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>
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固定配置多个 ChatClient 只是第一步。真正的动态路由需要在运行时决定用哪个模型。Spring AI 提供了几个关键扩展点。
3.1 策略模式:按业务规则分流
最直接的方式是用策略模式,根据请求特征选择模型。典型的特征包括文本长度、任务类型、用户等级等。
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); }}
说了这么多路由技术,最终还是要回到“选哪个模型”这个根本问题。以下是一个简洁的决策框架,可以直接用在项目中。
按任务类型选:
按成本敏感度选:
按可用性要求选:
一个实用的起点配置:
默认模型:GPT-4o-mini(成本低,通用能力够用)
代码任务:Claude Sonnet(质量优先)
降级模型:Ollama + Mistral(本地兜底,零依赖)
Spring AI 的多模型支持已经比较成熟。核心操作路径是:
禁用自动配置,手动创建多个 ChatClient Bean
用 @Primary 标记默认模型,其他用 @Qualifier 区分
在业务层实现路由逻辑,策略模式适合规则明确的场景,RouterChatModel 适合需要灵活组合的场景
加一层故障转移,让多模型架构发挥真正的容灾价值
下一步如果想继续深入,可以研究 Spring AI Alibaba 的多智能体路由模式,以及 LLM 路由 Agent 在复杂意图识别场景中的应用。
【温馨提示】
点赞+关注,私信回复「205」,即可免费获取【multi-platform-and-model-demo.zip】这个项目源码包哦。有任何建议或意见,欢迎评论区留言或私信飞哥,100%人工回复,感谢支持!