1、ChatClient简介
ChatClient是Spring AI为“大多数常见AI交互场景”设计的推荐入口点,是最佳实践指南,它涵盖了90%以上的用例。ChatClient不仅仅是一个简单的转发器,它集成了AI应用中最常见的“高级功能”,并以一致的、声明式的方式提供:
- 系统提示词:可以通过
SystemPromptTemplate轻松设定AI的角色。 - 格式化响应:可以指定返回格式为JSON等,方便后续解析。
- 聊天记忆:通过
Conversation或ChatMemory组件,轻松管理多轮对话的历史上下文,无需手动拼接消息列表。 - Tools(函数调用):可以方便地注册工具(
FunctionCallback),让AI模型在需要时调用业务方法。
需要使用某个模型独有的、尚未被ChatClient通用API支持的参数或特性,可以回退到使用底层的ChatModel。
Spring AI的完整架构层次
上图,可以用三句话来理解:
- Spring AI提供了OllamaChatModel等来封装各自的API,
- ChatClient在这些ChatModel实现上,提供了更高层次的抽象和便利功能,
- ChatClient提供一套统一的、更优雅的API使用所有模型。
**简化为一句话:**ChatClient是Spring AI提供的统一抽象层,让开发者能够用一套简洁的API调用封装好的各大模型。
总结:在使用Spring AI调用大模型API时,除非ChatClient无法实现,否则优先考虑用ChatClient。
2、ChatClient基本使用
2.1、创建方式
ChatClient 有两种创建方式:静态工厂方法和建造者模式。
2.1.1、静态工厂方法
// 最简单、最直接的创建方式ChatClientchatClient=ChatClient.create(ollamaChatModel);优点:使用模型的默认配置,一行代码创建。
适合场景:快速原型、简单测试。
2.1.2、建造者模式
// 可配置的创建方式ChatClientchatClient=ChatClient.builder(dashScopeChatModel).defaultSystem("我是阿里云通义千问助手").build();优点:可设置默认参数,支持高级功能(记忆、函数调用等)
适合场景:生产环境、需要定制化配置。
2.1.3、总结
从ChatClient源码看,不管是用create()还是builder(),都有一个参数就是ChatModel接口。而OllamaChatModel和DashScopeChatModel都是实现ChatModel接口。
2.2、示例代码演示
以文本生成测试为示例,创建一个测试类:ChatClientController,写接口调用API进行测试,方便实时修改提示信息与接口交互测试,我在接口加了一个msg参数接收用户输入的信息。
@RestController@RequestMapping(value="/chat/client")publicclassChatClientController{@AutowiredprivateOllamaChatModelollamaChatModel;/** * 文本生成 * @param msg 用户提示信息 * @return */@RequestMapping(value="/text")publicStringtextTest(@RequestParam(value="msg",defaultValue="你是谁呀?")Stringmsg){ChatClientchatClient=ChatClient.create(ollamaChatModel);returnchatClient.prompt().user(msg).call().content();}}启动项目,访问接口,测试结果如下:
3、ChatClient多平台模型动态管理
我在《0元玩转大模型:SpringBoot集成Spring AI与Ollama实现文本+视觉AI》有介绍到,Ollama专注于文本生成和理解的工具,本身不支持生成音频或视频。
在实际项目使用过程中,也可能存在某一大模型厂商提供功能不满足业务需求,或者因价格原因不想使用它们提供模型,需要替换掉或同时接入多个模型。一般代码是不会轻易修改的,毕竟有时可能会迁一发动全身,这时能修改配置的方式来动态切换是最好的。
本文就以阿里云百炼大模型和本地Ollama为例,写演示代码。
3.1、pom依赖
由于项目是基于Spring AI与Ollama实现 Demo,因此需要添加云百炼大模型的maven依赖。
<!--云百炼--><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.1.0.0-RC1</version></dependency>3.2、application.yml配置
spring:application:# 服务应用名name:spring-ai-demo-ollamaai:ollama:# 默认服务URL,windows# 文档:https://docs.ollama.com/windowsbase-url:http://localhost:11434chat:# 模型名称,必须下载到本地才可用model:gemma3:4b# 阿里 云百炼大模型dashscope:api-key:${ALI_AI_KEY}# 文本生成模型配置项chat:options:# 默认模型:qwen-plus,可不配置model:qwen-plus3.3、示例代码演示
3.3.1、方式一:根据参数动态创建
实现思路大致如下:
- 定义多平台模型选项参数实体类
MultiPlatformModelOptions, - 定义多平台模型
platformModelMap的Map,并初始化它, - 根据参数可动态切换平台模型。
步骤一:定义多平台模型选项参数实体类:
@DatapublicclassMultiPlatformModelOptionsimplementsSerializable{/** * 平台名称 */privateStringplatform;/** * 模型名称 */privateStringmodel;/** * 模型温度 */privateDoubletemperature;}步骤二:定义MultiPlatformModelController在里面模拟切换
@RestController@RequestMapping(value="/multi/platform")publicclassMultiPlatformModelController{privateMap<String,ChatModel>platformModelMap=newHashMap<>();publicMultiPlatformModelController(OllamaChatModelollamaChatModel,DashScopeChatModeldashScopeChatModel){platformModelMap.put("ollama",ollamaChatModel);platformModelMap.put("dashscope",dashScopeChatModel);}@RequestMapping(value="/streamText",produces="text/stream;charset=UTF-8")publicFlux<String>streamText(Stringmsg,MultiPlatformModelOptionsoptions){// 获取模型ChatModelchatModel=platformModelMap.get(options.getPlatform());// 创建ChatClientChatClientchatClient=ChatClient.builder(chatModel).defaultSystem("我是"+options.getPlatform()+"模型AI助手").defaultOptions(ChatOptions.builder().model(options.getModel())// 该参数如果不设置,模型调用时按默认值.temperature(options.getTemperature()).build()).build();// 调用模型returnchatClient.prompt().user(msg).stream().content();}}步骤三:测试验证
启动项目,访问接口,构造请求参数示例:?msg=你是谁&platform=ollama&model=gemma3:4b&temperature=0.8。
测试结果如下:
3.3.2、方式二:使用配置类
实现思路大致和【方式一:根据参数动态创建】一样,只不过把参数放到配置类而已。
步骤一:在配置类application.yml添加以下内容:
# 多平台大模型配置项multi:platform:options:# 平台名称platform:ollama# 模型名称model:gemma3:4b# 模型温度temperature:0.8步骤二:定义多平台模型配置类MultiPlatformModelConfig
@Configuration@Slf4jpublicclassMultiPlatformModelConfig{/** * 多平台模型配置 * @param ollamaChatModel 本地Ollama模型 * @param dashScopeChatModel 阿里通义千问模型 * @return */@BeanpublicMap<String,ChatModel>platformModelMap(OllamaChatModelollamaChatModel,DashScopeChatModeldashScopeChatModel){Map<String,ChatModel>map=newHashMap<>();map.put("ollama",ollamaChatModel);map.put("dashscope",dashScopeChatModel);log.info("已注册模型平台: {}",map.keySet());returnmap;}/** * 多平台模型客户端 * @param platformModelMap 多平台模型配置 * @param defaultPlatform 默认平台名称 * @param defaultModel 默认模型名称 * @param defaultTemperature 默认模型 * @return */@BeanpublicMap<String,ChatClient>chatClientMap(Map<String,ChatModel>platformModelMap,@Value("${multi.platform.options.default.platform}")StringdefaultPlatform,@Value("${multi.platform.options.default.model}")StringdefaultModel,@Value("${multi.platform.options.default.temperature}")DoubledefaultTemperature){Map<String,ChatClient>clientMap=newHashMap<>();// 为每个平台创建ChatClientplatformModelMap.forEach((platform,model)->{// 为每个平台创建基础ChatClientChatClient.Builderbuilder=ChatClient.builder(model).defaultSystem("我是"+platform+"模型AI助手");// 如果是默认平台,应用默认配置if(platform.equals(defaultPlatform)){builder.defaultOptions(ChatOptions.builder().model(defaultModel).temperature(defaultTemperature).build());}clientMap.put(platform,builder.build());});returnclientMap;}/** * 默认平台ChatClient * @param chatClientMap 多平台模型客户端 * @param defaultPlatform 默认平台名称 * @return */@Bean@PrimarypublicChatClientdefaultChatClient(Map<String,ChatClient>chatClientMap,@Value("${multi.platform.options.default.platform:ollama}")StringdefaultPlatform){ChatClientclient=chatClientMap.get(defaultPlatform);if(client==null){thrownewIllegalStateException("默认平台未找到: "+defaultPlatform);}returnclient;}/** * 显示平台【本地Ollama模型】方式ChatClient * @param chatClientMap 多平台模型客户端 * @return */@BeanpublicChatClientollamaClient(Map<String,ChatClient>chatClientMap){returnchatClientMap.get("ollama");}/** * 显示平台【阿里云通义千问】方式ChatClient * @param chatClientMap 多平台模型客户端 * @return */@BeanpublicChatClientdashScopeClient(Map<String,ChatClient>chatClientMap){returnchatClientMap.get("dashscope");}}步骤三:创建DynamicPlatformModelController,添加三个接口,分别用于验证:根据配置值动态调用、显示平台【本地Ollama模型】方式调用和显示平台【阿里云通义千问】方式调用。
@RestController@RequestMapping(value="/dynamic/platform")publicclassDynamicPlatformModelController{@AutowiredprivateChatClientdynamicChatClient;@AutowiredprivateChatClientollamaClient;@AutowiredprivateChatClientdashScopeClient;/** * 根据配置值动态调用 * @param msg 用户提示信息 * @return */@RequestMapping(value="/streamText",produces="text/stream;charset=UTF-8")publicFlux<String>streamText(Stringmsg){returndynamicChatClient.prompt().user(msg).stream().content();}/** * 显示平台【本地Ollama模型】方式调用 * @param msg * @return */@RequestMapping(value="/streamText/ollama",produces="text/stream;charset=UTF-8")publicFlux<String>streamTextOllama(Stringmsg){returnollamaClient.prompt().user(msg).stream().content();}/** * 显示平台【阿里云通义千问】方式调用 * @param msg * @return */@RequestMapping(value="/streamText/dashScope",produces="text/stream;charset=UTF-8")publicFlux<String>streamTextDashScope(Stringmsg){returndashScopeClient.prompt().user(msg).stream().content();}}步骤四:测试验证
根据配置值动态调用,结果如下:
显示平台【本地Ollama模型】方式调用,结果如下:
显示平台【阿里云通义千问】方式调,结果如下:
至此,Spring AI ChatClient多平台模型动态管理实战内容就结束啦!感兴趣的同学赶快动手起来吧。
4、我的公众号&资料获取
敬请关注我的公众号:大象只为你,持续更新技术知识…
如需Spring AI与Ollama实现 Demo,代码有更新,请后台回复:【ollama】。