【Spring AI】Spring AI Alibaba的简单使用

提示:文章最后有详细的参考文档。

前提条件

  • SpringBoot版本为3.x以上
  • JDK为17以上
  • 申请api-key,地址:百炼平台

引入依赖

说明:我的springboot版本为3.2.4,spring-ai-alibaba-starter版本为1.0.0-M2.1(对应spring-ai版本为1.0.0-M2),jdk版本为17。

1. pom.xml中引入

<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId>
</dependency>

spring-ai-alibaba 基于 spring-ai 开发,由于 spring-ai 相关依赖包还没有发布到中央仓库,如出现 spring-ai-core 等相关依赖解析问题,请在您项目的 pom.xml 依赖中加入如下仓库配置。

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

并且在maven的setting.xml中做出如下更改:

<mirror>  <id>alimaven</id>  <name>aliyun maven</name>  <url>https://maven.aliyun.com/repository/public</url> <!-- 表示除了spring-milestones、maven2其它都走阿里云镜像  --> <mirrorOf>*,!spring-milestones,!maven2</mirrorOf>  
</mirror>

2. application.yml中引入

spring:ai:dashscope:api-key: 申请的api-keychat:client:enabled: true

3. 代码中引入

    @Resourceprivate ChatModel chatModel;

开发示例

1. 简单的对话

@GetMapping("/simple")
public String simpleChat(@RequestBody JSONObject param) {// 接收并校验参数String inputInfo = CommonUtil.getAndCheck(param, "inputInfo", "请输入内容!");// 构建chatClientChatClient.Builder builder = ChatClient.builder(chatModel);ChatClient chatClient = builder.defaultSystem("你是一个精通Java、Python的程序大佬。").build();return chatClient.prompt().user(inputInfo).call().content();
}

2. 流式对话

使用Server Sent Event(SSE)事件返回,对应前端需要处理SSE事件的数据。

@GetMapping("/stream")
public Flux<ServerSentEvent<String>> streamChat(@RequestBody JSONObject param) {// 接收并校验参数String inputInfo = CommonUtil.getAndCheck(param, "inputInfo", "请输入内容!");return chatModel.stream(new Prompt(inputInfo)).map(response -> ServerSentEvent.<String>builder().data(response.getResult().getOutput().getContent()).build()).doOnComplete(() -> log.info("响应完成!")).doOnError(e -> log.error("响应异常:", e));
}

3. 带记忆对话(原生API存储)

使用原生的:MessageChatMemoryAdvisor

private final ChatClient chatClient;
public AIChatController(ChatClient.Builder builder) {this.chatClient = builder.defaultSystem("你是一个精通Java、Python的程序大佬。").defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())).build();
}@GetMapping("/memoryStreamWithApi")
public Flux<ServerSentEvent<String>> memoryStreamWithApi(@RequestBody JSONObject param) {// 接收并校验参数// 对话记忆ID,我是通过前端传参获取,你可以获取一个UUIDString accessKey = CommonUtil.getAndCheck(param, "accessKey", "您没有改功能访问权限!");String inputInfo = CommonUtil.getAndCheck(param, "inputInfo", "请输入内容!");// 请求数据return chatClient.prompt().user(inputInfo).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, accessKey).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 5))    // 从上下文中检索聊天内存响应大小,具体参数定义可参考文章最后的Spring AI API文档.stream().chatResponse().map(response -> {return ServerSentEvent.<String>builder().data(response.getResult().getOutput().getContent()).build();}).doOnComplete(() -> {log.info("响应完成!");}).doOnError((e) -> {log.warn("响应异常:", e);});
}

4. 带记忆对话(Redis存储)

使用redis存储:

@GetMapping("/memoryStreamWithRedis")
public Flux<ServerSentEvent<String>> memoryStreamWithRedis(@RequestBody JSONObject param) {// 接收并校验参数// 对话记忆ID,我是通过前端传参获取,你可以获取一个UUIDString accessKey = CommonUtil.getAndCheck(param, "accessKey", "您没有改功能访问权限!");String inputInfo = CommonUtil.getAndCheck(param, "inputInfo", "请输入内容!");List<Message> messageList = new ArrayList<>();// 拼接redis keyString redisKey = CommonConst.MY_ACCESS_KEY_PREFIX + accessKey;// 判断是否存在聊天记忆,有的话将其带入本次对话中if (redisService.hasKey(redisKey)) {// 从redis中获取聊天记忆数据List<String> strList = redisService.getCacheList(redisKey);List<Message> memoryList = new ArrayList<>();if (!CollectionUtils.isEmpty(strList)) {strList.forEach(s -> memoryList.add(new UserMessage(s)));// 反转聊天记忆数据,我存入List数据时采用头插法,所以这里需要反转list,以保证聊天内容的先后顺序Collections.reverse(memoryList);messageList.addAll(memoryList);}}messageList.add(new UserMessage(inputInfo));StringBuilder resultStr = new StringBuilder();return chatModel.stream(new Prompt(messageList)).map(response -> {resultStr.append(response.getResult().getOutput().getContent());return ServerSentEvent.<String>builder().data(response.getResult().getOutput().getContent()).build();}).doOnComplete(() -> {// 将LLM返回的文本存入redis,存储的数据类型是List,enqueue()方法的定义看下文redisService.enqueue(redisKey, resultStr.toString(), MAX_LENGTH);log.info("响应完成!");}).doOnError(e -> log.warn("响应异常:", e));
}

RedisService中部分代码:

/*** 添加固定长度的队列,左添加** @param key       key* @param value     value* @param maxLength 最大存储的聊天记录长度*/
public void enqueue(String key, String value, int maxLength) {// 使用Redis的LPUSH命令添加元素,然后确保长度不超过最大值redisTemplate.opsForList().leftPush(key, value);// 保持队列长度不超过指定长度,LTRIM会自动删除超出长度的旧元素if (redisTemplate.opsForList().size(key) > maxLength) {redisTemplate.opsForList().trim(key, 0, maxLength - 1);}
}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/
public <T> List<T> getCacheList(final String key) {return redisTemplate.opsForList().range(key, 0, -1);
}/*** 判断 key 是否存在** @param key 键* @return true 存在 false不存在*/
public Boolean hasKey(String key) {return redisTemplate.hasKey(key);
}

参考文档

 官方参考文档:Spring AI Alibaba 官方 、Spring AI 官方、Spring AI API 文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Java源力物语》-3.空值猎手

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” \quad 夜色渐深&#xff0c;在一处偏僻小径上&#xff0c;月光透过浓密的源力云层&#xff0c;在地面上投下斑驳的光影。String正独自练习着刚从…

科技云报到:人工智能时代“三大件”:生成式AI、数据、云服务

科技云报到原创。 就像自行车、手表和缝纫机是工业时代的“三大件”。生成式AI、数据、云服务正在成为智能时代的“新三大件”。加之全球人工智能新基建加速建设&#xff0c;成为了人类社会数字化迁徙的助推剂&#xff0c;让新三大件之间的耦合越来越紧密。从物理世界到数字世…

hiprint结合vue2项目实现静默打印详细使用步骤

代码地址是&#xff1a;vue-plugin-hiprint: hiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑 本地安装包地址&#xff1a;electron-hiprint 发行版 - Gitee.com 1、先安装hipint安装包在本地 2、项目运行npm&#xff08;socket.…

CUDA各种内存和使用方法

文章目录 1、全局内存2、局部内存3、共享内存3.1 静态共享内存3.2 动态共享内存 4、纹理内存5、常量内存6、寄存器内存7、用CUDA运行时API函数查询设备CUDA 错误检测 1、全局内存 特点&#xff1a;容量最大&#xff0c;访问延时最大&#xff0c;所有线程都可以访问。 线性内存…

Chapter 03 复合数据类型-1

1.列表 Python内置的一种有序、可变的序列数据类型&#xff1b; 列表的定义&#xff1a; [ ]括起来的逗号分隔的多个元素组成的序列 列表对象的创建&#xff1a; &#xff08;1&#xff09;直接赋值 >>> list1 []#创建一个空列表赋值给list1 >>> list…

【后端】LNMP环境搭建

长期更新各种好文&#xff0c;建议关注收藏&#xff01; 本文近期更新完毕。 LNMPlinuxnginxmysqlphp 需要的资源 linux服务器 web服务软件nginx 对应的语言编译器代码文件 数据库mysql安装 tar.gz包或者命令行安装 进入root&#xff1a; sodu 或su mkdir path/{server,soft}…

基于PyQt5的UI界面开发——多界面切换

介绍 最初&#xff0c;因为课设的缘故&#xff0c;我只是想做一个通过按键进行切面切换而已&#xff0c;但是我看网上资料里面仅是语焉不详&#xff0c;让我困惑的很&#xff0c;但后面我通过摸索才发现这件事实在是太简单了&#xff0c;因此我想要记录下来。 本博客将介绍如…

操作002:HelloWorld

文章目录 操作002&#xff1a;HelloWorld一、目标二、具体操作1、创建Java工程①消息发送端&#xff08;生产者&#xff09;②消息接收端&#xff08;消费者&#xff09;③添加依赖 2、发送消息①Java代码②查看效果 3、接收消息①Java代码②控制台打印③查看后台管理界面 操作…

机器视觉检测相机基础知识 | 颜色 | 光源 | 镜头 | 分辨率 / 精度 / 公差

注&#xff1a;本文为 “keyence 视觉沙龙中机器视觉检测基础知识” 文章合辑。 机器视觉检测基础知识&#xff08;一&#xff09;颜色篇 视觉检测硬件构成的基本部分包括&#xff1a;处理器、相机、镜头、光源。 其中&#xff0c;和光源相关的最重要的两个参数就是光源颜色和…

【每日学点鸿蒙知识】压力测试、Web组件拦截器、nfc开关状态、定位能力、rn支持的三方库

1、HarmonyOS的wukong 支持运行python脚本进行压力或者常规测试吗&#xff1f; Python脚本调用hdc命令&#xff0c;执行hdc shell wukong XXXwukong只支持稳定性压测&#xff0c;普通测试建议使用arkxtest测试框架 2、Web组件页面内跳转时自定义WebHeader问题&#xff1f; 如…

GDPU Vue前端框架开发 期末赛道出勇士篇(更新ing)

记住&#xff0c;年底陪你跨年的不会仅是方便面跟你的闺蜜&#xff0c;还有孑的笔记。 选择题 1.下列选项用于设置Vue.js页面视图的元素是&#xff08;&#xff09;。 A. Template B. script C. style D. title 2.下列选项中能够定义Vuejs根实例对象的元素是&#xff08;&…

Flutter开发HarmonyOS 鸿蒙App的好处、能力以及把Flutter项目打包成鸿蒙应用

Flutter开发HarmonyOS的好处&#xff1a; Flutter是谷歌公司开发的一款开源、免费的UI框架&#xff0c;可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux 的跨平台开发…

Effective C++ 条款 17:以独立语句将 `newed` 对象置入智能指针

文章目录 条款 17&#xff1a;以独立语句将 newed 对象置入智能指针核心思想示例代码错误用法分析推荐设计总结 条款 17&#xff1a;以独立语句将 newed 对象置入智能指针 核心思想 问题背景 如果在将 newed 对象传递给智能指针时&#xff0c;包含了复杂的表达式&#xff0c;一…

【体验官招募】SoFlu - JavaAI 开发助手:开启智能开发新时代

你是否有过这样的经历&#xff1f;在深夜的办公室里&#xff0c;面对紧急的 Java 项目&#xff0c;看着厚厚的需求文档&#xff0c;你是否感到无从下手&#xff1f; 当你尝试理解客户那些复杂又模糊的需求时&#xff0c;是否会因为要和产品经理反复沟通确认每一个细节而感到厌…

【Compose multiplatform教程07】多平台常用组件和重要组件目录

一、基础交互与显示组件 Text 查看示例 功能说明&#xff1a;用于在界面上显示文本内容&#xff0c;支持设置字体、大小、颜色、样式&#xff08;如加粗、斜体、下划线&#xff09;等属性&#xff0c;满足不同的文本展示需求&#xff0c;可传达各种信息给用户。示例场景&#…

自学记录HarmonyOS Next DRM API 13:构建安全的数字内容保护系统

在完成了HarmonyOS Camera API的开发之后&#xff0c;我开始关注更复杂的系统级功能。在浏览HarmonyOS Next文档时&#xff0c;我发现了一个非常有趣的领域&#xff1a;数字版权管理&#xff08;DRM&#xff09;。最新的DRM API 13提供了强大的工具&#xff0c;用于保护数字内容…

【HENU】河南大学计院2024 操作系统 简答题复习

和光同尘_我的个人主页 一直游到海水变蓝。 单项选择 15x2 30 判断 10x1 10 简答 3x10 30 综合 3x10 30 简答题 简述操作系统的四个基本特征。 并发性 共享性 虚拟性 异步性 并发性是最重要特性&#xff0c;其它三种特性以此为前提。 并发 并发(Concurrence)&#…

基于Android的校园导航系统

基于Android的校园导航系统是一种专为校园环境设计的移动应用程序&#xff0c;旨在帮助学生、教职工及访客快速、准确地找到校园内的目的地。以下是对基于Android的校园导航系统的详细介绍&#xff1a; 一、系统概述 基于Android的校园导航系统通常包括客户端&#xff08;移动…

GEE错误——PCA系数变换的时候出现的错误

目录 错误提示1 错误提示2 原始的教程链接&#xff1a; 错误代码 修正后的代码 结果 错误提示1 这个是因为原始GEE教程中给的让我们填入需要进行计算的波段名称&#xff0c;而且是以list的形式传入。 错误提示2 这里我们虽然传入了正确的波段名称&#xff0c;但是发现要…

C#代码实现把中文录音文件(.mp3 .wav)转为文本文字内容

我们有一个中文录音文件.mp3格式或者是.wav格式&#xff0c;如果我们想要提取录音文件中的文字内容&#xff0c;我们可以采用以下方法&#xff0c;不需要使用Azure Speech API 密钥注册通过离线的方式实现。 1.首先我们先在NuGet中下载两个包 NAudio 2.2.1、Whisper.net 1.7.3…