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

Spring-AI初级使用记录 spring-ai-bom版本1.0.1-(单、多轮对话)

Spring-AI初级使用记录-(单、多轮对话)

Spring-AI官方文档:https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html
当前环境:

  • Spring AI version: 1.0.1
  • Spring Boot version: 3.5.4
  • Java version: 21.0.2
  • Maven version:无所谓,大多数都可以。

创建项目

1.创建SpringBoot项目:
在这里插入图片描述
点击下一步后添加相关依赖,不添加也行,后面在pom文件中可以自己配置。这里选择Open Ai和Web
在这里插入图片描述
创建完成后可以检查下pom文件,完整的pom文件如下(为了测试方便我多加了swagger,不需要可以去掉):

   <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--新版的Swagger,jdk17以后老版不能用了--><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.5.0</version> <!-- 或更高版本,如2.12.x --></dependency></dependencies><dependencyManagement><dependencies><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>

恭喜🎉至此项目就创建完了。

配置项目

2.开始配置yml,注意:completions-path这个属性不配置默认是/v1/chat/completions(根据自己实际情况修改)。

spring:ai:openai:api-key: XXXXXXXXXXX # 将这里替换为你自己的OpenAI API Keybase-url: https://XXX.XXX.com # OpenAI API的基础URLchat:options:# 使用的模型,可根据需求更换model: deepseek-reasonertemperature: 0.7 # 控制生成文本的随机性,取值范围0 - 1,值越大越随机completions-path: /v2/chat/completions 

结束配置,开始编程。

单轮对话调用

编写测试案例:

@RestController
@RequestMapping("/ChatClient")
@Tag(name = "Spring-AI客户端")
public class AiController {//具体人设信息public static final String system="你是一个高中生,名字叫做小明,今年16岁,喜欢唱跳rap篮球。";//对话客户端private final ChatClient chatClient;//构造注入AiController(ChatClient chatClient) {this.chatClient = chatClient;}@GetMapping("/chat")@Operation(summary = "同步调用")String chat(String userInput) {return this.chatClient.prompt().advisors(new SimpleLoggerAdvisor()) //开启日志.system(system)  //人设.user(userInput)    //userMessage.call()    //同步调用.content();    }@GetMapping(value = "/chatStream",produces = "text/html;charset=utf-8")@Operation(summary = "流式调用")Flux<String> chatStream(String userInput) {return this.chatClient.prompt().advisors(new SimpleLoggerAdvisor()) //开启日志.system(system)  //人设.user(userInput)    //userMessage.stream()    //流式调用.content();}
}

因为在pom文件中导入了Swagger,方便调试直接调用请求,经测试单轮对话同步、流式请求都测试成功。swagger默认地址:http://localhost:8080/swagger-ui/index.html

在这里插入图片描述

由于swagger中看不出来流式的效果,可以直接在浏览器中测试,会出现打字机效果。
(http://localhost:8080/ChatClient/chatStream?userInput=你吃饭了吗)
在这里插入图片描述

多轮对话调用

使用SpringAI加入记忆进行多轮对话测试

 @AutowiredChatMemoryRepository chatMemoryRepository;  //注入对话记忆@GetMapping("/chatMemory")@Operation(summary = "带记忆的同步调用")String chatMemory(String userInput) {// 1. 构建对话记忆存储配置// 使用MessageWindowChatMemory实现窗口记忆策略ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository) // 底层记忆存储仓库(测试使用内存实现).maxMessages(20)    // 设置历史消息最大保留轮次(滑动窗口大小).build();// 2. 生成唯一会话ID(实际项目中由)String conversationId = "123456789"; // 示例固定值,生产环境需动态生成// 3. 构建对话请求并配置各组件return this.chatClient.prompt()// 3.1 设置对话角色.system(system)  // 系统角色设定(AI人设/指令)// 3.2 设置基础参数.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId) // 绑定当前对话ID到请求上下文)// 3.3 添加增强功能(Advisors).advisors(new SimpleLoggerAdvisor(),  // 启用请求日志记录(用于调试)MessageChatMemoryAdvisor.builder(chatMemory).build(),   // 启用记忆管理功能new SystemFirstSortingAdvisor() // 确保系统消息优先排序)// 3.4 设置当前用户输入.user(userInput)// 3.5 执行调用.call() // 发送同步请求到对话服务// 3.6 处理响应.content(); // 提取响应中的文本内容}@GetMapping(value = "/chatMemoryStream",produces = "text/html;charset=utf-8")@Operation(summary = "带记忆的流式调用")public Flux<String> generateStream(String userInput) {// 1. 构建对话记忆存储配置// 使用MessageWindowChatMemory实现窗口记忆策略ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository) // 底层记忆存储仓库(测试使用内存实现).maxMessages(20)    // 设置历史消息最大保留轮次(滑动窗口大小).build();// 2. 生成唯一会话ID(实际项目中由)String conversationId = "123456789"; // 示例固定值,生产环境需动态生成// 3. 构建对话请求并配置各组件return this.chatClient.prompt()// 3.1 设置对话角色.system(system)  // 系统角色设定(AI人设/指令)// 3.2 设置基础参数.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId) // 绑定当前对话ID到请求上下文)// 3.3 添加增强功能(Advisors).advisors(new SimpleLoggerAdvisor(),  // 启用请求日志记录(用于调试)MessageChatMemoryAdvisor.builder(chatMemory).build(),    // 启用记忆管理功能new SystemFirstSortingAdvisor() // 确保系统消息优先排序)// 3.4 设置当前用户输入.user(userInput)// 3.5 执行调用.stream() // 发送流式请求到对话服务// 3.6 处理响应.content(); // 提取响应中的文本内容}

如上示例中有SystemFirstSortingAdvisor类需要单独便编写来确保系统人设始终保持在第一位(具体为什么要使用它,是因为1.0.1版本对Spring Ai多轮对话有BUG,可以参考这篇文章:https://blog.csdn.net/YnagLei/article/details/150619680?spm=1001.2014.3001.5502),内容如下:

/*** 保证SYSTEM在最前面的增强*/
public class SystemFirstSortingAdvisor implements BaseAdvisor {@Overridepublic ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {List<Message> processedMessages = chatClientRequest.prompt().getInstructions();processedMessages.sort(Comparator.comparing(m -> m.getMessageType() == MessageType.SYSTEM ? 0 : 1));return chatClientRequest.mutate().prompt(chatClientRequest.prompt().mutate().messages(processedMessages).build()).build();}@Overridepublic ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {return chatClientResponse; // no-op}@Overridepublic int getOrder() {return 0; // larger than MessageChatMemoryAdvisor so it runs afterwards}
}

至此带记忆的多轮对话已编写完成,进行测试。
第一轮:你吃饭了吗?
在这里插入图片描述
第二轮:我刚问你什么了?
在这里插入图片描述
很明显模型已经知道咱们之前问的问题了,说明测试成功。

http://www.dtcms.com/a/343722.html

相关文章:

  • reactive 核心要点
  • FFmpeg及 RTSP、RTMP
  • 大型前端项目如何实现css 隔离:利用浏览器原生的 Shadow DOM 完全隔离 DOM 结构与样式...
  • 前端AI工具——TRAE
  • Linux基础命令大全:从入门到熟练
  • 开发避坑指南(34):mysql深度分页查询优化方案
  • GitCode 疑难问题诊疗:全面指南与解决方案
  • 关于在 IntelliJ IDEA 中安装和配置 Java 17
  • 简单聊聊多模态大语言模型MLLM
  • RabbitMQ 应用问题
  • RabbitMQ深度剖析:从基础到高级进阶实战
  • RabbitMQ 全面指南:架构解析与案例实战
  • 线性回归学习笔记
  • k8s——持久化存储 PVC
  • 自定义rabbitmq的ConnectionFactory配置
  • uniapp轮播 轮播图内有定位样式
  • uniappx鸿蒙适配
  • 2025年视频大模型汇总、各自优势及视频大模型竞争焦点
  • 2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(七)
  • 蓝牙学习--连接蓝牙播放音乐无声的分析步骤
  • Matplotlib 可视化大师系列(六):plt.imshow() - 绘制矩阵与图像的强大工具
  • 【大语言模型 13】Dropout与正则化技术全景:深度网络过拟合防御的终极武器
  • 什么是短视频矩阵系统企业立项功能源码开发,支持OEM
  • Flask 之 Cookie Session 详解:用户状态管理
  • 了解 PostgreSQL 的 MVCC 可见性基本检查规则
  • Apache Flink集群架构:核心角色与协同机制
  • 【ElasticSearch】使用docker compose,通过编写yml安装es8.15和kibana可视化界面操作,go连接es
  • 为什么需要关注Flink并行度?
  • 使用 Apache Flink CDC 3.0 实现 MySQL 到 Elasticsearch 的数据同步
  • 回归测试的重要性与实践指南