Spring AI Alibaba 入门开发一

目录

一、准备工作

二、HelloWorld

[2.1 项目结构](#2.1 项目结构)

[2.2 创建父工程](#2.2 创建父工程)

[2.3 创建子模块------ssa-01-HelloWorld](#2.3 创建子模块——ssa-01-HelloWorld)

三、微服务调用本地大模型-本章可跳过

[3.1 准备工作](#3.1 准备工作)

系统与硬件要求

本地部署大模型配置推荐列表

[3.2 开发调用本地大模型](#3.2 开发调用本地大模型)

四、ChatModel和ChatClient

[4.1 ChatModel](#4.1 ChatModel)

[4.2 ChatClient](#4.2 ChatClient)

[4.3 使用ChatClient调用大模型](#4.3 使用ChatClient调用大模型)

[4.4 两者对比](#4.4 两者对比)

五、同时使用多个模型实现流式输出

[5.1 流式输出介绍](#5.1 流式输出介绍)

[5.2 SSE(Server-Sent Events)服务器发送事件](#5.2 SSE(Server-Sent Events)服务器发送事件)

[5.3 多模型共存开发](#5.3 多模型共存开发)

[5.4 Flux介绍](#5.4 Flux介绍)

[5.5 新增前端交互](#5.5 新增前端交互)


一、准备工作

1、到阿里百炼平台申请API KEY、然后获取base_url、模型code。具体请自行百度。

2、我的相关配置

JDK 21

maven 建议3.9.5

SpringBoot : 3.5.5

spring-ai: 1.0.0

SpringAIAlibaba:1.0.2

二、HelloWorld

2.1 项目结构

2.2 创建父工程

只需修改父工程pom.xml即可,代码如下:

XML 复制代码
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <java.version>21</java.version>
        <spring-boot.version>3.5.5</spring-boot.version>
        <spring-ai.version>1.0.0</spring-ai.version>
        <SpringAIAlibaba.version>1.0.0.2</SpringAIAlibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring AI Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-bom</artifactId>
                <version>${SpringAIAlibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring AI -->
            <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>
                <version>${spring-boot.version}</version>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

2.3 创建子模块------ssa-01-HelloWorld

1、pom.xml

XML 复制代码
 <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

2、配置文件

复制代码
application.properties
复制代码
server.port=8888

#解决中文乱码
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

spring.application.name=ssa-01-HelloWorld
#Sprig AI Alibaba 相关配置
spring.ai.dashscope.api-key=${qianwen-api}
spring.ai.dashscope.base-url=https://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
spring.ai.dashscope.chat.options.model=qwen-max

注意:配置api-key时,不能使用明文,需要先配置环境变量,然后在properties中使用${环境变量}

3、创建配置类

有两种方式获取api-key,一种是读取application.properties的内容,一种是读取环境变量的值。具体实现如下:

java 复制代码
@Configuration
public class LLMConfig {
    //方式1:读取配置文件信息
    @Value("${spring.ai.dashscope.api-key}")
    private String apiKey;

    @Bean
    public DashScopeApi dashScopeApi() {
        return DashScopeApi.builder().apiKey(apiKey).build();
    }

    //方式2:读取环境变量
//    @Bean
//    public DashScopeApi dashScopeApi2() {
//        return DashScopeApi.builder().apiKey(System.getenv("qianwen-api")).build();
//    }
}

4、对话模型-Chat Model

对话模型(Chat Model)接收一系列消息(Message)作为输入,与模型 LLM 服务进行交互,并接收返回的聊天消息(Chat Message)作为输出。相比于普通的程序输入,模型的输入与输出消息(Message)不止支持纯字符文本,还支持包括语音、图片、视频等作为输入输出。同时,在 Spring AI Alibaba 中,消息中还支持包含不同的角色,帮助底层模型区分来自模型、用户和系统指令等的不同消息。

Spring AI Alibaba 复用了 Spring AI 抽象的 Model API,并与通义系列大模型服务进行适配(如通义千问、通义万相等),目前支持纯文本聊天、文生图、文生语音、语音转文本等。以下是框架定义的几个核心 API:

  • ChatModel,文本聊天交互模型,支持纯文本格式作为输入,并将模型的输出以格式化文本形式返回。
  • ImageModel,接收用户文本输入,并将模型生成的图片作为输出返回。
  • AudioModel,接收用户文本输入,并将模型合成的语音作为输出返回。

Spring AI Alibaba 支持以上 Model 抽象与通义系列模型的适配,并通过 spring-ai-alibaba-starter AutoConfiguration 自动初始化了默认实例,因此我们可以在应用程序中直接注入 ChatModel、ImageModel 等 bean,当然在需要的时候也可以自定义 Model 实例。

5、创建controller

使用两种方式与大模型进行交互,一种是.call():此方式是一次响应所有的内容;一种是.stream():文字逐个返回。

java 复制代码
@RestController
public class ChatHelloWorldController {

    @Resource
    private ChatModel chatModel;

    @GetMapping("/hello/call")
    public String doCall(@RequestParam(value = "msg" , defaultValue = "高欢") String msg) {
        String result = chatModel.call(msg);
        return result;
    }

    @GetMapping("/hello/stream")
    public Flux<String> doStream(@RequestParam(value = "msg" , defaultValue = "宇文泰") String msg) {
        return chatModel.stream(msg);
    }
}

三、微服务调用本地大模型-本章可跳过

3.1 准备工作

1、本地安装Ollama。注意:默认安装C盘,建议更换其他位置。安装方法请百度。

系统与硬件要求

项目 最低要求 特别说明
操作系统 Windows 10 22H2 或更新版本(家庭版/专业版均可) 版本过旧可能导致兼容性问题,建议更新。
处理器 (CPU) 4核及以上(推荐Intel i7或AMD Ryzen 5以上) 若没有独立显卡,将完全依赖CPU进行推理,速度会慢很多。
内存 (RAM) 16GB 或更高 运行大模型时,内存是保证系统不崩溃的关键。
显卡 (GPU) 强烈推荐NVIDIA或AMD独立显卡 Ollama支持NVIDIA、AMD Radeon GPU加速。
NVIDIA显卡驱动 551.61 或更新版本 这是官方文档的要求,驱动太旧可能无法识别显卡。
AMD显卡驱动 安装最新版AMD Radeon驱动,或支持ROCm/Vulkan的驱动 部分RDNA2架构显卡(如RX 6000系列)可能推荐使用Vulkan加速。
存储空间 安装程序本身约需4GB ,另需为模型文件预留几十到上百GB 模型文件体积很大,强烈建议安装在SSD上以提升加载速度。

本地部署大模型配置推荐列表

推荐级别 模型系列 具体推荐模型 (Ollama命令) 模型大小 (量化后) 显存占用 预期速度 (tokens/秒) 适用场景
🏆 首选推荐 Qwen3 (4B) ollama run qwen3:4b-q4_K_M ~2.9 GB ~3.2 GB 30 - 50 日常聊天、问答、编程辅助、文本总结,体验流畅
🥈 次选推荐 Qwen2.5 (3B) ollama run qwen2.5:3b-q4_K_M ~2.0 GB ~2.2 GB 40 - 60 轻量级任务,响应极快,适合资源敏感场景
🤔 进阶挑战 DeepSeek-R1 (7B) ollama run deepseek-r1:7b-q4_K_M ~4.4 GB ~4.6 GB (略超显存) 8 - 15 复杂推理、代码生成,需要部分CPU+GPU混合运行,速度较慢

确认好模型后,可以使用pull命令拉去,使用run命令运行,具体与docker类似。

3.2 开发调用本地大模型

1、新建子模块,项目结构如下:

2、修改pom.xml文件

XML 复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--spring-ai-alibaba dashscope-->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        </dependency>
        <!--ollama-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-ollama</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </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-actuator</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

3、application.properties

复制代码
server.port=8888

#解决中文乱码
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

spring.application.name=ssa-02-ollama
#Sprig AI Alibaba 相关配置
spring.ai.dashscope.api-key=${qianwen-api}
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=qwen3:4b

4、新建controller

java 复制代码
@RestController
public class OllamaController {
    @Resource(name = "ollamaChatModel")
    private ChatModel chatModel;

    @GetMapping("/ollama")
    private Flux<String> ollama(@RequestParam(value = "msg" ,defaultValue = "高欢") String msg){
        return chatModel.stream(msg);
    }
}

5、新建启动类

java 复制代码
public class SSA_02_OllamaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SSA_02_OllamaApplication.class, args);
    }
}

6、运行如下:

四、ChatModel和ChatClient

4.1 ChatModel

对话模型(Chat Model)接收一系列消息(Message)作为输入,与模型 LLM 服务进行交互,并接收返回的聊天消息(Chat Message)作为输出。相比于普通的程序输入,模型的输入与输出消息(Message)不止支持纯字符文本,还支持包括语音、图片、视频等作为输入输出。同时,在 Spring AI Alibaba 中,消息中还支持包含不同的角色,帮助底层模型区分来自模型、用户和系统指令等的不同消息。

Spring AI Alibaba 复用了 Spring AI 抽象的 Model API,并与通义系列大模型服务进行适配(如通义千问、通义万相等),目前支持纯文本聊天、文生图、文生语音、语音转文本等。以下是框架定义的几个核心 API:

  • ChatModel,文本聊天交互模型,支持纯文本格式作为输入,并将模型的输出以格式化文本形式返回。
  • ImageModel,接收用户文本输入,并将模型生成的图片作为输出返回。
  • AudioModel,接收用户文本输入,并将模型合成的语音作为输出返回。

Spring AI Alibaba 支持以上 Model 抽象与通义系列模型的适配,并通过 spring-ai-alibaba-starter AutoConfiguration 自动初始化了默认实例,因此我们可以在应用程序中直接注入 ChatModel、ImageModel 等 bean,当然在需要的时候也可以自定义 Model 实例。

ChatModel适合简单大模型交互场景。

4.2 ChatClient

ChatClient 提供了与 AI 模型通信的 Fluent API,它支持同步和反应式(Reactive)编程模型。与 ChatModelMessageChatMemory 等原子 API 相比,使用 ChatClient 可以将与 LLM 及其他组件交互的复杂性隐藏在背后,因为基于 LLM 的应用程序通常要多个组件协同工作(例如,提示词模板、聊天记忆、LLM Model、输出解析器、RAG 组件:嵌入模型和存储),并且通常涉及多个交互,因此协调它们会让编码变得繁琐。当然使用 ChatModel 等原子 API 可以为应用程序带来更多的灵活性,成本就是您需要编写大量样板代码。

ChatClient 类似于应用程序开发中的服务层,它为应用程序直接提供 AI 服务,开发者可以使用 ChatClient Fluent API 快速完成一整套 AI 交互流程的组装。

包括一些基础功能,如:

  • 定制和组装模型的输入(Prompt)
  • 格式化解析模型的输出(Structured Output)
  • 调整模型交互参数(ChatOptions)

还支持更多高级功能:

  • 聊天记忆(Chat Memory)
  • 工具/函数调用(Function Calling)
  • RAG

ChatClient是高级封装,基于ChatModel创建,适合快速构建保准化复杂AI服务,支持同步和流式交互,集成多种高级功能。

4.3 使用ChatClient调用大模型

1、项目结构

2、创建子模块,修改pom.xml

XML 复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--spring-ai-alibaba dashscope-->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

创建启动类

java 复制代码
@SpringBootApplication
public class SSA_03_ChatModel_ChatClient_Application {
    public static void main(String[] args) {
        SpringApplication.run(SSA_03_ChatModel_ChatClient_Application.class, args);
    }
}

创建配置文件

复制代码
server.port=8888

#解决中文乱码
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

spring.application.name=ssa-02-ChatModel-ChatClient
#Sprig AI Alibaba 相关配置
spring.ai.dashscope.api-key=${qianwen-api}
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=goekdenizguelmez/JOSIEFIED-Qwen2.5:7b-q4_k_m

创建controller,注意:下面通过两种方式创建ChatClient对象。

方式一:在config里通过@Bean注解创建------推荐

java 复制代码
@Configuration
public class LLMConfig {
    @Value("${spring.ai.dashscope.api-key}")
    private String apiKey;

    @Bean
    public DashScopeApi dashScopeApi() {
        return DashScopeApi.builder().apiKey(apiKey).build();
    }

    @Bean
    public ChatClient chatClient(ChatModel dashScopeChatModel) {
        return ChatClient.builder(dashScopeChatModel).build();
    }
}
java 复制代码
@RestController
public class ChatClient_V2_Controller {

    @Resource
    private ChatClient chatClient;

    @GetMapping("/client1")
    public String doClient1(@RequestParam(value = "msg" ,defaultValue = "请简单介绍侯莫陈崇") String msg) {
        return chatClient.prompt().user(msg).call().content();
    }
}

第二种方式:在controller里通过构造方法创建------不推荐

java 复制代码
@RestController
public class ChatClientController {

    private final ChatClient chatClient;

    public ChatClientController(ChatModel dashScopeChatModel) {
        this.chatClient = ChatClient.builder(dashScopeChatModel).build();
    }

    @GetMapping("/client")
    public String doClient(@RequestParam(value = "msg" ,defaultValue = "南北朝时期最勇猛的将领是谁?") String msg) {
        return chatClient.prompt().user(msg).call().content();
    }
}

4.4 两者对比

五、同时使用多个模型实现流式输出

5.1 流式输出介绍

1、流式输出(StreamingOutput)

是一种逐步返回大模型生成结果的技术,生成一点返回一点,允许服务器将响应内容

分批次实时传输给客户端,而不是等待全部内容生成完毕后再一次性返回。

这种机制能显著提升用户体验,尤其适用于大模型响应较慢的场景(如生成长文本或复杂推理结果)

2、实现方式

Spring AI Alibaba两种流式输出:分别为ChatModel和ChatClient。

5.2 SSE(Server-Sent Events)服务器发送事件

Server-Sent:由服务器发送。

Events:事件,指服务器主动推送给客户端的数据或消息。

Server-SentEvents(SSE)服务器发送事件实现流式输出。

Server-Sent Events (SSE) 是一种允许服务端可以持续推送数据片段(如逐词或逐句)到前端的 Web 技术。通过单向的HTTP长连接,使用一个长期存在的连接,让服务器可以主动将数据"推"给客户端,SSE是轻量级的单向通信协议,适合AI对话这类服务端主导的场景

核心概念

SSE 的核心思想是:客户端发起一个请求,服务器保持这个连接打开并在有新数据时,通过这个连接将数据发送给客户端。这与传统的请求-响应模式(客户端请求一次,服务器响应一次,连接关闭)有本质区别。SSE下一代(Stream able Http)。

总结:一种让服务器能够主动、持续地向客户端(比如你的网页浏览器)推送数据的技术。

SSE适用场景:

5.3 多模型共存开发

1、创建子模块,项目结构

2、修改pom.xml

XML 复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--spring-ai-alibaba dashscope-->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.38</version>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

3、新增配置文件

复制代码
server.port=8888

#解决中文乱码
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

spring.application.name=ssa-01-HelloWorld
#Sprig AI Alibaba 相关配置
spring.ai.dashscope.api-key=${qianwen-api}
spring.ai.dashscope.base-url=https://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
#spring.ai.dashscope.chat.options.model=qwen-max

4、创建启动类

复制代码
@SpringBootApplication
public class SSA_04_Stream_OutputApplication {
    public static void main(String[] args) {
        SpringApplication.run(SSA_04_Stream_OutputApplication.class, args);
    }
}

5、新增配置类-创建ChatModel对象

java 复制代码
@Configuration
public class LLMConfig {
    //定义各个模型名称
    private final String DEEPSEEK_MODEL = "deepseek-v4-pro";
    private final String QWEN_MODEL = "qwen-max";

    //创建deepseek的ChatModel
    @Bean(name = "deepseek")
    public ChatModel deepseek() {
        return
                DashScopeChatModel.builder().dashScopeApi(
                        DashScopeApi.builder().apiKey(System.getenv("qianwen-api")).build())
                        .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build())
                        .build();
    }

    //创建qwen的ChatModel
    @Bean(name = "qwen")
    public ChatModel qwen() {
        return
                DashScopeChatModel.builder().dashScopeApi(
                        DashScopeApi.builder().apiKey(System.getenv("qianwen-api")).build()
                ).defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build())
                        .build();
    }
}

6、新增controller-使用ChatModel调用大模型

java 复制代码
@RestController
public class ChatModelController {

    @Resource(name = "deepseek")
    private ChatModel deepseekChatModel;

    @Resource(name = "qwen")
    private ChatModel qwenChatModel;

    @GetMapping("/model/deepseek")
    public Flux<String> doDeepSeekModel(@RequestParam(value = "msg",defaultValue = "你是谁") String msg) {
        return deepseekChatModel.stream(msg);
    }

    @GetMapping("/model/qwen")
    public Flux<String> doQwenModel(@RequestParam(value = "msg",defaultValue = "你是谁") String msg) {
        return qwenChatModel.stream(msg);
    }

}

7、新增配置类-创建ChatClient对象

java 复制代码
@Configuration
public class LLMConfig {
    //定义各个模型名称
    private final String DEEPSEEK_MODEL = "deepseek-v4-pro";
    private final String QWEN_MODEL = "qwen-max";

    //创建deepseek的ChatModel
    @Bean(name = "deepseek")
    public ChatModel deepseek() {
        return
                DashScopeChatModel.builder().dashScopeApi(
                        DashScopeApi.builder().apiKey(System.getenv("qianwen-api")).build())
                        .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build())
                        .build();
    }

    //创建qwen的ChatModel
    @Bean(name = "qwen")
    public ChatModel qwen() {
        return
                DashScopeChatModel.builder().dashScopeApi(
                        DashScopeApi.builder().apiKey(System.getenv("qianwen-api")).build()
                ).defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build())
                        .build();
    }

    @Bean(name = "deepseekChatClient")
    public ChatClient deepseekChatClient(@Qualifier("deepseek") ChatModel deepseek) {
        return
                ChatClient.builder(deepseek)
                        .defaultOptions(ChatOptions.builder().model(DEEPSEEK_MODEL).build()).build();
    }

    @Bean(name = "qwenChatClient")
    public ChatClient qwenChatClient(@Qualifier("qwen") ChatModel qwen) {
        return
                ChatClient.builder(qwen).defaultOptions(ChatOptions.builder().model(QWEN_MODEL).build()).build();
    }
}

8、创建controller-使用ChatClientdiaoyong 调用大模型

java 复制代码
@RestController
public class ChatModelController {

    @Resource(name = "deepseek")
    private ChatModel deepseekChatModel;

    @Resource(name = "qwen")
    private ChatModel qwenChatModel;

    @Resource(name = "deepseekChatClient")
    private ChatClient deepseekChatClient;

    @Resource(name = "qwenChatClient")
    private ChatClient qwenChatClient;


    @GetMapping("/model/deepseek")
    public Flux<String> doDeepSeekModel(@RequestParam(value = "msg",defaultValue = "你是谁") String msg) {
        return deepseekChatModel.stream(msg);
    }

    @GetMapping("/model/qwen")
    public Flux<String> doQwenModel(@RequestParam(value = "msg",defaultValue = "你是谁") String msg) {
        return qwenChatModel.stream(msg);
    }

    @GetMapping("/client/deepseek")
    public Flux<String> deDeepSeekClient(@RequestParam(value = "msg",defaultValue = "你是谁") String msg) {
        return deepseekChatClient.prompt(msg).stream().content();
    }

    @GetMapping("/client/qwen")
    public Flux<String> doQwenClient(@RequestParam(value = "msg",defaultValue = "你是谁") String msg){
        return qwenChatClient.prompt(msg).stream().content();
    }

}

5.4 Flux介绍

Flux是SpringWebFlux中的一个核心组件,属于响应式编程模型的一部分。它主要用于处理异步、非阻塞的流式数据,能够高效地处理高并发场景。Flux可以生成和处理一系列的事件或数据如流式输出等。

看类注释和类所在的jar包我们就明白:

SAA中的流式输出是通过ReactorStreams技术实现的和SpringWebFlux的底层实现是一样的技术。

具体执行流程:

ReactorStreams会订阅数据源,当有数据时,ReactorStreams以分块流的方式发送给客户端用户。

5.5 新增前端交互

在/resoure/static添加index.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>SSE流式chat</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 20px;
        }

        #messageInput {
            width: 90%;
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin-bottom: 10px;
        }

        button {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        button:hover {
            background-color: #0056b3;
        }

        #messages {
            margin-top: 20px;
            padding: 15px;
            background-color: #f9f9f9;
            border: 1px solid #ddd;
            border-radius: 8px;
            max-height: 300px;
            overflow-y: auto;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        #messages div {
            padding: 8px 0;
            border-bottom: 1px solid #eee;
            font-size: 14px;
            color: #333;
        }

        #messages div:last-child {
            border-bottom: none;
        }
    </style>
</head>
<body>
<textarea id="messageInput" rows="4" cols="50" placeholder="请输入你的问题..."></textarea><br>
<button onclick="sendMsg()">发送提问</button>
<div id="messages"></div>
<script>
    function sendMsg() {
        // 获取用户输入的消息
        const message = document.getElementById('messageInput').value;
        if (message == "") return false;

        //1 客户端使用 JavaScript 的 EventSource 对象连接到服务器上的一个特定端点(URL)
        const eventSource = new EventSource('client/qwen?question=' + message);
        //2 监听消息事件
        eventSource.onmessage = function (event) {
            // 获取流式返回的数据
            const data = event.data;
            // 将接收到的数据展示到页面上
            const messagesDiv = document.getElementById('messages');
            messagesDiv.innerHTML += event.data;
        };

        //3 监听错误事件
        eventSource.onerror = function (error) {
            console.error('EventSource 发生错误:', error);
            eventSource.close(); // 关闭连接
        };
    }
</script>
</body>
</html>

修改对应的controller

复制代码
@GetMapping("/client/qwen")
public Flux<String> doQwenClient(@RequestParam(value = "question") String msg){
    return qwenChatClient.prompt(msg).stream().content();
}

启动后,输入:http://localhost:8888/index.html

相关推荐
AI_小站15 天前
Loop Engineering又是啥?一文讲清企业Agent落地的四层工程进化论
java·人工智能·架构·prompt·大模型开发·智能体·大模型应用
xcLeigh21 天前
Doubao-Seed-Evolving大模型接入教程|搭建全品类提示词+AI工具导航网页
前端·人工智能·python·ai·html·ai开发·豆包
阿木实验室25 天前
两周复现 FUEL:AI辅助无人机算法开发实战,附源码地址
ai开发·fuel算法·无人机探索
uncle_ll1 个月前
LangChain 实战指南:回调系统、自定义组件与有状态对话全落地
langchain·llm·embedding·agent·大模型开发·rag
咋吃都不胖lyh1 个月前
大模型云端部署标准操作流程(SOP)
ai开发
HelloFYW2 个月前
Superpowers 5.1.0 技能使用手册(中文版)
开发工具·ai开发·claude code·superpowers·技能手册
Tbisnic2 个月前
AI大模型学习第十三天:让AI学会查资料、记数据、看图和听声
人工智能·ai·大模型开发·rag·coze
断春风2 个月前
企业级 AI 应用开发实战:从 Demo 到生产系统的完整架构
人工智能·架构·ai开发
唯刻V2 个月前
谷歌官方 Android CLI 深度解读
android·cli·ai开发·ai时代·android cli