【SAA】SpringAI Alibaba学习笔记(一):SSE与WS的区别以及如何注入多个AI模型

目录

[一、SSE(Server-Sent Events)与WS(WebSocket)](#一、SSE(Server-Sent Events)与WS(WebSocket))

核心概念

区别

二、SAA中同时注入多个模型

三、注入ChatClient


一、SSE(Server-Sent Events)与WS(WebSocket)

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

核心概念

客户端发起一个请求,服务器保持这个连接打开并在有新数据时,通过这个连接将数据发送给客户端。就像我们现在使用AI时,它不是一次性返回所有数据给客户端,而是逐字逐句地返回。我个人认为:这种方式用户使用体验更好。在学习SAA时,接口返回数据的类型通常有两种:

第一种为String,直接把所有生成的文字以字符串类型全部返回给前端。学习过程中,调用该接口时如果生成的文字过多,通常浏览器会"转圈圈",即浏览器在等待数据全部传输中,这样给人的一种错觉就是"网络卡了"。我觉得用户使用感很差。

第二种为Flux<String>,即流式输出,这种便是逐字逐句地响应给客户端,体验感极佳。


区别


二、SAA中同时注入多个模型

在使用过程中可知道我们在开发中可能会同时使用到不同的AI模型,但是简单的注入程序不能识别,此时需要进行配置。

这里我们以千问模型deepseek为例子。

定义名为SaaLLMConfig的配置类。

java 复制代码
@Configuration
public class SaaLLMConfig {
    //模型名称常量定义,一套系统多模型共存
    private final String DEEPSEEK_MODEL="deepseek-v3";  //模型的名称
    private final String QWEN_MODEL="qwen-max";

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


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

三、注入ChatClient

ChatClient不支持自动注入,需要手动注入。需要在配置类中配置。而且ChatClient不能离开ChatModel,要想使用ChatClient,需要先创建ChatModel。

需要在@Bean注解里标注名称,参数里也需要使用@Qualifier指定哪一个ChatModel。

java 复制代码
@Bean(name = "deepseekChatClient")  //要指定名称,要不然注入时区分不了哪一个
    public ChatClient deepseekChatClient(@Qualifier("deepseek") ChatModel deepseek)  {
        return ChatClient.builder(deepseek)  //需要注入ChatModel
                .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();
    }
相关推荐
奋发向前wcx15 小时前
y1,y2总复习笔记10 2026.7.24
笔记·哈希算法·散列表
MuMuMu122316 小时前
智慧监测的“火眼金睛”:当AIoT重构环保监管体系
笔记
头发还在的女程序员17 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats17 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
min(a,b)17 小时前
学习第 4 天:面向对象与异常处理
python·学习·学习方法
一只小菜鸡..17 小时前
南京大学 操作系统 (JYY) 学习笔记:进程地址空间与内存“外挂”魔法
笔记·学习
我命由我1234518 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
tju新生代魔迷18 小时前
Verilog语言学习(一)
学习
一只小菜鸡..19 小时前
南京大学 操作系统 (JYY) 学习笔记:访问操作系统的对象与“一切皆文件”
笔记·学习
都叫我大帅哥20 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程