【SpringAI中Chat-Client用法】

作者:明志学编程-日期:9/30/2025

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用法】》 是转载文章,点击查看原文


相关推荐


数电基础--电平规范_TTL与CMOS
逐步前行9/30/2025

高电平输出大于2.4V,如果落在2.4V至3.5V之间,CMOS电路不能检测到高电平,需要进行电平输换。(3)、3.3V的TTL驱动5V的CMOS,考虑可以存在电压钳位,比如单片机的GPIO,不适合上拉电阻。(1)、3.3V的TTL驱动3.3V的CMOS,可以通过简单的上拉电阻实现电平匹配。(2)、5V的TTL驱动5V的CMOS,可以通过简单的上拉电阻实现电平匹配。高电平输出3.3V,CMOS电路不能检测到高电平,需要进行电平转换。Tx输出5V,Q2截止,Rx端为3.3V;


《WebAssembly指南》第六章:读懂 WebAssembly 文本格式
锋通科技10/2/2025

本文介绍了WebAssembly文本格式的基本概念和使用方法。主要内容包括:1. WebAssembly文本格式采用S表达式表示模块结构,比二进制格式更易读易修改。2. 详细讲解了函数定义、参数传递、栈机器运行机制等核心概念,并通过加法函数示例演示了模块的创建和调用过程。3. 介绍了内存管理机制,包括内存共享、字符串处理和多内存使用场景。4. 深入讲解了表格(Table)的概念及其在动态链接中的应用,展示了如何通过表格实现函数指针功能。5. 概述了WebAssembly支持的各种类型和特性,包括数值类型、引


AR/VR赋能工业巡检:开启智能化运维新时代
Teamhelper_AR2025/10/2

在工业 4.0 时代浪潮的推动下,增强现实(AR www.teamhelper.cn )与虚拟现实(VR)技术加速从理论概念迈向工业应用前沿,尤其在工业设备巡检这一关键领域,正展现出前所未有的变革潜力,有望彻底颠覆传统依赖人工经验、效率低下、风险高且数据不连贯的巡检模式。 AR技术:重塑工业巡检核心优势 AR技术通过巧妙地将虚拟信息与真实环境相融合,为工业巡检人员带来了革新性的工作体验。借助AR智能眼镜,巡检人员能够实时获取设备参数、操作指南以及历史数据等关键信息,无需再频繁翻阅纸质


释放模型潜能:ONNX Runtime 如何进行优化与加速?
Cosolar2025/10/2

在机器学习从实验室走向真实世界的过程中,模型的部署与运行效率往往是决定项目成败的“最后一公里”。一个在离线环境中表现优异的模型,如果无法满足生产环境对低延迟、高吞吐和低资源消耗的要求,其商业价值将大打折扣。 ONNX Runtime (ORT) 作为由微软主导的开源跨平台推理引擎,凭借其出色的性能、广泛的硬件支持和活跃的社区,已成为业界部署模型的事实标准之一。然而,仅仅将模型转换为 ONNX 格式并使用 ORT 运行,只是拿到了“入场券”。要真正释放其潜能,我们需要从模型优化、推理引擎配置、硬


SIMD编程入门:让性能飞起来的实践指南
oioihoii2025/10/3

在现代计算中,单指令多数据流(SIMD)技术就像是一把性能优化的瑞士军刀,能让你的程序速度提升数倍甚至数十倍。本文将带你从零开始,掌握这把利器的使用之道。 什么是SIMD?从汽车生产线说起 想象一下汽车生产线:传统方式是一个工人依次安装每个轮胎,而SIMD就像是培训了一个专门团队,能够同时安装四个轮胎。这就是单指令多数据流的核心思想——一条指令,多个数据。 // 传统标量计算 - 依次处理每个元素 for (int i = 0; i < 4; i++) { result[i] = a[


HTTP为什么不安全?
你的人类朋友2025/10/4

🌐 前言 你好呀,我是你的人类朋友! 本文主要讲讲 HTTP 为什么不安全,以及 HTTPS 如何解决这些问题。 ❗❗ 核心问题速览 HTTP(超文本传输协议):互联网上应用最广泛的网络协议,但数据以明文形式传输。注意,是明文,谁都能看!! HTTPS(安全超文本传输协议):HTTP 的安全版本,= HTTP + SSL/TLS 加密,就像把明信片放进防拆信封里寄送,别人无法看到信息的内容。 补充知识 1:SSL/TLS在【传输层】对 HTTP 数据进行加密,确保隐私和完整性。 补充知识 2


【深度相机术语与概念】
是刘彦宏吖2025/10/5

获取相机输出的 深度图、灰度图、彩色图 和 点云图,用于导航、避障、三维建模、手势识别等应用。 【深度相机术语与概念】 相机类型 3D 相机 3D 相机是一种能够捕捉三维图像的相机。它通过各种技术手段(如立体视觉、飞行时间、结构光等)获取物体的三维形状和深度信息。3D 相机可以生成具有 3D 空间坐标信息的点云数据,使得计算机能够理解和处理三维空间中的物体。 主动双目立体相机 主动双目立体相机是一种结合了双目立体视觉和主动光源(如结构光)的相机系统。它通过投射已知的光图案到场景中,并使用双目相


Python 的 TCP 编程
hubenchang05152025/10/6

#Python 的 TCP 编程 传输控制协议(Transmission Control Protocol) 是一种 面向连接、可靠传输 的网络通信协议,是现代互联网最核心的协议之一。 #客户端程序 TCP 客户端程序通常只需要连接到服务器然后收发数据即可。下面是一个示例,它向 tcpbin.com 的 4242 端口发送 hello\n,对方会原样返回。 import socket # 创建 TCP socket sock = socket.socket(socket.AF_INET, so


第7章:数据库与持久化存储
芝麻开门-新起点2025/10/8

7.1 为何需要数据库:记忆与状态管理 内容讲解 默认情况下,AI Bot 是**“无状态”的。这意味着除了短暂的当前对话上下文,它不记得任何过去的事情。每次对话都是一次全新的开始。然而,在许多真实场景中,我们需要 Bot 拥有记忆**,能够持久化地存储和检索信息。这就是**数据库(Database)**的作用。 数据库为 Bot 提供了以下关键能力: 长期记忆:记住用户的偏好、历史订单、个人信息等。例如,一个订餐 Bot 应该记住你常去的地址和喜欢的口味。状态跟踪:在复杂的多轮任务中,跟踪当前


【SCI一区】【电动车】基于ADMM双层凸优化的燃料电池混合动力汽车研究(Matlab代码实现)
荔枝科研社2025/10/9

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭:行百里者,半于九十。 💥1 概述 基于ADMM双层凸优化的燃料电池混合动力汽车研究 随着车辆互联性的出现,互联汽车 (CVs) 在增强道路安全、改善乘坐舒适性、提高交通效率和提高能源效率方面提供了巨大的潜力。通过从车对车 (V2V) 和车对基础设施 (V2I) 通信中获取交通信息,CV 能够更准确、更广泛地感知

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0