当前位置: 首页 > news >正文

【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.mrgr.cn/news/81643.html

相关文章:

  • vim交换文件的作用
  • 求阶乘(信息学奥赛一本通-2019)
  • FPGA自分频产生的时钟如何使用?
  • [cg] UE5 调试技巧
  • 大疆机场及无人机上云
  • EFCore HasDefaultValueSql
  • HTML速查
  • 【QT开发自制小工具】PDF/图片转excel---调用百度OCR API接口
  • 洛谷 P1014:Cantor 表
  • 用友-友数聚科技CPAS审计管理系统V4 getCurserIfAllowLogin存在SQL注入漏洞
  • Unity Dots理论学习-2.ECS有关的模块(1)
  • KVM虚拟机管理脚本
  • 攻防世界web第三题file_include
  • VSCode调试
  • Oracle 数据库执行计划的查看与分析技巧
  • webauthn介绍及应用
  • 实用工具推荐----Doxygen使用方法
  • Dockerfile教程
  • redis基础知识
  • Git如何设置和修改当前分支跟踪的上游分支
  • 关于DataGridView的使用注意事项
  • 【漏洞复现】BIG-IP Next Central Manager OData 注入漏洞(CVE-2024-21793)
  • uniapp 文本转语音
  • 机器学习之KNN算法预测数据和数据可视化
  • 爆改RagFlow
  • WPF 绘制过顶点的圆滑曲线(样条,贝塞尔)