Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
🌱🌱个人主页:奋斗的明志
🌱🌱所属专栏:SpringAI
📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。


SprnigAI
- 了解
- 创建子工程
- 添加pom依赖(阿里云百炼平台)
- 添加配置
- 代码编写
- 多平台多模型动态配置大模型平台实战
-
- 配置类
- 接口
- 展示效果
- 定义3个ChatClient的bean
- 注意点
了解
ChatClient 基于ChatModel进行了封装提供了通用的 API,它适用所有的大模型, 使用ChatClient可以让你面向SpringAi通用的api 而无需面向为每一种不同的模型的api来进行编程,虽然您仍然可以使用 ChatModel 来实现某些模型更加个性化的操作(ChatModel更偏向于底层),但 ChatClient 提供了灵活、更全面的方法来构建您的客户端选项以与模型进行交互: 比如系统提示词、格式式化响应、聊天记忆 、tools 都更加易用和优雅,所以除非ChatClient无法实现,否则我们优先考虑用ChatClient。
所以我们后续基于ChatClient来进行学习应用。
基于ChatModel来学习源码,因为ChatClient底层依然还是ChatModel的封装。
创建子工程


添加pom依赖(阿里云百炼平台)
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 <parent> 7 <groupId>com.mingzhi.springai</groupId> 8 <artifactId>spring-ai-parent</artifactId> 9 <version>0.0.1-mz</version> 10 </parent> 11 12 <artifactId>chat-client</artifactId> 13 <description>chat-client学习-聊天客户端</description> 14 15 <properties> 16 <maven.compiler.source>17</maven.compiler.source> 17 <maven.compiler.target>17</maven.compiler.target> 18 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 19 </properties> 20 21 <dependencies> 22 <!--接入百炼平台--> 23 <dependency> 24 <groupId>com.alibaba.cloud.ai</groupId> 25 <artifactId>spring-ai-alibaba-starter-dashscope</artifactId> 26 </dependency> 27 </dependencies> 28 29</project> 30
添加配置
1server: 2 port: 8081 #端口号 3spring: 4 application: 5 name: chat-client #服务应用名称 6 dashscope: 7 api-key: sk-e9bcb1abcaeb4da89114ef639067097ede 8 chat: 9 options: 10 model: qwen-vl-max-latest # 模型名称 11 multi-model: true 12
代码编写
- 必须通过ChatClient.Builder 来进行构造
1@SpringBootTest 2public class ChatClientTest { 3 4 @Autowired 5 private ChatClient.Builder builder; 6 7 /** 8 * 同步响应 9 */ 10 @Test 11 public void test() { 12 ChatClient chatClient = builder.build(); 13 String content = chatClient.prompt() 14 .user("hello")// 用户输入的提示词 15 .call() 16 .content(); 17 System.out.println(content); 18 } 19 20 /** 21 * 流式响应 22 */ 23 @Test 24 public void test2() { 25 ChatClient chatClient = builder.build(); 26 Flux<String> stringFlux = chatClient.prompt() 27 .user("hello")// 用户输入的提示词 28 .stream() 29 .content(); 30 stringFlux.toIterable().forEach(System.out::println); 31 } 32 33 34} 35
这种方式会在底层自动注入1个ChatModel , 如果你配置了多个模型依赖, 会无法注入。引入多个大模型的依赖,在进行依赖注入的时候就会报错

1<dependencies> 2 <!--接入百炼平台--> 3 <dependency> 4 <groupId>com.alibaba.cloud.ai</groupId> 5 <artifactId>spring-ai-alibaba-starter-dashscope</artifactId> 6 </dependency> 7 <!--接入deepseek依赖--> 8 <dependency> 9 <groupId>org.springframework.ai</groupId> 10 <artifactId>spring-ai-starter-model-deepseek</artifactId> 11 </dependency> 12<!-- <dependency>--> 13<!-- <groupId>org.springframework.boot</groupId>--> 14<!-- <artifactId>spring-boot-starter-webflux</artifactId>--> 15<!-- </dependency>--> 16 17 </dependencies> 18


Autowired会先根据类型进行匹配,类型匹配不上就会找对应的名称,名称再找不到,就会出现上述错误
如何进行避免呢?

可以通过这种方式动态选择ChatModel:
1@Autowired 2private DashScopeChatModel dashScopeChatModel; 3@Test 4public void test3() { 5 ChatClient build = ChatClient.builder(dashScopeChatModel).build(); 6 String content = build.prompt() 7 .user("hello")// 用户输入的提示词 8 .call() 9 .content(); 10 System.out.println(content); 11} 12 13@Test 14public void testChatStream() { 15 ChatClient chatClient = ChatClient.builder(dashScopeChatModel).build(); 16 Flux<String> content = chatClient.prompt() 17 .user("Hello") 18 .stream() 19 .content(); 20 21 // 阻塞输出 22 content.toIterable().forEach(System.out::println); 23 } 24
多平台多模型动态配置大模型平台实战

配置类
MorPlatformAndModelOptions
1package com.mingzhi.springai; 2 3public class MorPlatformAndModelOptions { 4 /** 5 * 平台 6 */ 7 private String platform; 8 /** 9 * 模型 10 */ 11 private String model; 12 /** 13 * 温度 14 */ 15 private Double temperature; 16 17 public String getModel() { 18 return model; 19 } 20 21 public void setModel(String model) { 22 this.model = model; 23 } 24 25 public String getPlatform() { 26 return platform; 27 } 28 29 public void setPlatform(String platform) { 30 this.platform = platform; 31 } 32 33 public Double getTemperature() { 34 return temperature; 35 } 36 37 public void setTemperature(Double temperature) { 38 this.temperature = temperature; 39 } 40} 41
接口
MorPlatformAndModelController
1package com.mingzhi.springai.controller; 2 3import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel; 4import com.mingzhi.springai.MorPlatformAndModelOptions; 5import org.springframework.ai.chat.client.ChatClient; 6import org.springframework.ai.chat.model.ChatModel; 7import org.springframework.ai.chat.prompt.ChatOptions; 8import org.springframework.ai.deepseek.DeepSeekChatModel; 9import org.springframework.web.bind.annotation.RequestMapping; 10import org.springframework.web.bind.annotation.RestController; 11import reactor.core.publisher.Flux; 12 13import java.util.HashMap; 14import java.util.Map; 15 16@RestController 17public class MorPlatformAndModelController { 18 //声明一个map,用来初始化平台 19 Map<String, ChatModel> platformMap = new HashMap<>(); 20 21 //通过构造函数进行自动注入 22 public MorPlatformAndModelController(DashScopeChatModel dashScopeChatModel, 23 DeepSeekChatModel deepSeekChatModel) { 24 platformMap.put("dashscope", dashScopeChatModel); 25 platformMap.put("deepseek", deepSeekChatModel); 26 } 27 28 /** 29 * @param message 消息 30 * @param options 选项 31 * @return 32 */ 33 @RequestMapping(value = "/chat",produces = "text/stream;charset=UTF-8") 34 public Flux<String> chat( 35 String message, 36 MorPlatformAndModelOptions options) { 37 38 String platform = options.getPlatform(); 39 System.out.println("当前平台:" + platform); 40 ChatModel chatModel = platformMap.get(platform); 41 ChatOptions chatOptions = ChatOptions.builder() 42 .temperature(options.getTemperature()) 43 .model(options.getModel()) 44 .build(); 45 46 ChatClient chatClient = ChatClient.builder(chatModel).defaultOptions(chatOptions).build(); 47 Flux<String> content = chatClient.prompt() 48 .user(message) 49 .stream() 50 .content(); 51 return content; 52 } 53} 54
展示效果



定义3个ChatClient的bean
也可以根据请求动态创建, 看需求
1@Configuration 2public class AiConfig { 3 4 @Bean 5 public ChatClient deepseekR1(DeepSeekChatProperties chatProperties) { 6 7 DeepSeekApi deepSeekApi = DeepSeekApi.builder() 8 .apiKey(System.getenv("DEEP_SEEK_KEY")) 9 .build(); 10 11 12 DeepSeekChatModel deepSeekChatModel = DeepSeekChatModel.builder() 13 .deepSeekApi(deepSeekApi) 14 .defaultOptions(DeepSeekChatOptions.builder().model(DeepSeekApi.ChatModel.DEEPSEEK_REASONER).build()) 15 .build(); 16 17 return ChatClient.builder(deepSeekChatModel).build(); 18 } 19 20 @Bean 21 public ChatClient deepseekV3() { 22 23 DeepSeekApi deepSeekApi = DeepSeekApi.builder() 24 .apiKey(System.getenv("DEEP_SEEK_KEY")) 25 .build(); 26 27 28 DeepSeekChatModel deepSeekChatModel = DeepSeekChatModel.builder() 29 .deepSeekApi(deepSeekApi) 30 .defaultOptions( 31 DeepSeekChatOptions.builder() 32 .model(DeepSeekApi.ChatModel.DEEPSEEK_CHAT) 33 .build() 34 ) 35 .build(); 36 37 return ChatClient.builder(deepSeekChatModel).build(); 38 } 39 40 @Bean 41 public ChatClient ollama(@Autowired OllamaApi ollamaApi, @Autowired OllamaChatProperties options) { 42 OllamaChatModel ollamaChatModel = OllamaChatModel.builder() 43 .ollamaApi(ollamaApi) 44 .defaultOptions(OllamaOptions.builder().model(options.getModel()).build()) 45 .build(); 46 47 return ChatClient.builder(ollamaChatModel).build(); 48 } 49 50} 51
注意点
在单独引入阿里百炼平台时,有一个依赖可能会引入不进来




《【SpringAI中Chat-Client用法】》 是转载文章,点击查看原文。