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

SpringAI实现聊天记录保存到MySQL

数据库相关的准备

添加依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.11</version>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>

添加配置

  datasource:url: jdbc:mysql://localhost:3306/test_activiti?useUnicode=true&characterEncoding=utf-8username: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

创建SQL脚本

create table chat_message
(id              bigint auto_incrementprimary key,conversation_id varchar(255)                        not null,role            varchar(50)                         not null,context         text                                not null,created_at      timestamp default CURRENT_TIMESTAMP null
);

创建实体类

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("chat_message")
public class ChatMessage {@TableId(type = IdType.AUTO)private Long id;private String conversationId;private String role;private String context;private String createdAt;
}

创建mapper

@Mapper
public interface ChatMessageMapper extends BaseMapper<ChatMessage> {
}

SpringAI相关准备

不用阿里云的maven仓库,用默认的maven中央仓库。

版本控制

    <properties><java.version>21</java.version><spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version></properties>

    <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>

添加依赖

        <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency>

因为我对接的阿里云百炼平台

添加配置

spring:ai:openai:base-url: https://dashscope.aliyuncs.com/compatible-mode/api-key: ${ALIYUN_AK}chat:options:model: qwen-max

我的api-key 存储在我环境变量中

编写代码

创建MysqlChatMemory实现ChatMemory

@Component
public class MysqlChatMemory implements ChatMemory {@Autowiredprivate ChatMessageMapper chatMessageMapper;@Overridepublic void add(String conversationId, Message message) {ChatMessage chatMessage = ChatMessage.builder().conversationId(conversationId).role(message.getMessageType().name()).context(message.getText()).build();chatMessageMapper.insert(chatMessage);}@Overridepublic void add(String conversationId, List<Message> messages) {messages.forEach(message -> add(conversationId, message));}@Overridepublic List<Message> get(String conversationId) {LambdaQueryWrapper<ChatMessage> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(ChatMessage::getConversationId, conversationId);return chatMessageMapper.selectList(queryWrapper).stream().map(e -> new UserMessage(e.getContext())).collect(Collectors.toList());}@Overridepublic void clear(String conversationId) {LambdaQueryWrapper<ChatMessage> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(ChatMessage::getConversationId, conversationId);chatMessageMapper.delete(queryWrapper);}
}

创建chatModel

创建一个就行,我这里为了实现0代码切换大模型。

@Configuration
public class BaiLianConfig {@Value("${spring.ai.openai.api-key}")private String apiKey;@Value("${spring.ai.openai.base-url}")private String baseUrl;private final String BAILIAN_DEEPSEEK_MODEL = "deepseek-v3";private final String BAILIAN_QWEN_MODEL = "qwen-max";@Beanpublic OpenAiChatModel deepSeek(){return OpenAiChatModel.builder().openAiApi(OpenAiApi.builder().apiKey(apiKey).baseUrl(baseUrl).build()).defaultOptions(OpenAiChatOptions.builder().model(BAILIAN_DEEPSEEK_MODEL).build()).build();}@Beanpublic OpenAiChatModel qwen(){return OpenAiChatModel.builder().openAiApi(OpenAiApi.builder().apiKey(apiKey).baseUrl(baseUrl).build()).defaultOptions(OpenAiChatOptions.builder().model(BAILIAN_QWEN_MODEL).build()).build();}}

创建controller

@Slf4j
@RestController
@RequestMapping("/memory")
public class ChatMemoryController {private final ChatClient chatClient;public ChatMemoryController(ChatModel deepSeek) {this.chatClient = ChatClient.builder(deepSeek).build();}@Autowiredprivate MysqlChatMemory mysqlChatMemory;@GetMapping("/mysql")public Flux<String> mysql(String question, String conversationId){MessageChatMemoryAdvisor advisor = MessageChatMemoryAdvisor.builder(mysqlChatMemory).conversationId(conversationId).order(5).build();return chatClient.prompt().system("你是我的学习助手名字叫小菜包").user(question).advisors(advisor).stream().content();}}

测试

就是为了测试我的会话id就是我自己设置的,后面到了项目中肯定不是这样使用的。

http://www.lryc.cn/news/586210.html

相关文章:

  • 浅谈 Python 中的 yield——yield的返回值与send()的关系
  • Golang 面向对象(封装、继承、多态)
  • 特辑:Ubuntu,前世今生
  • Go内存分配
  • python excel处理
  • 【世纪龙科技】新能源汽车结构原理体感教学软件-比亚迪E5
  • Windows 用户账户控制(UAC)绕过漏洞
  • 单细胞分析教程 | (二)标准化、特征选择、降为、聚类及可视化
  • 力扣-24.两两交换链表中的节点
  • 7. 负载均衡:流量调度引擎
  • STM32--USART串口通信的应用(第一节串口通信的概念)
  • stack和queue的使用和模拟实现以及了解deque
  • Kafka——聊聊Kafka的版本号
  • React 组件中怎么做事件代理?它的原理是什么?
  • 【6.1.0 漫画数据库技术选型】
  • LRU缓存机制完全实战:链表的工程落地与面试通关
  • 复现永恒之蓝
  • 网络配置综合实验全攻略(对之前学习的总结)
  • 脉冲神经网络膜电位泄漏系数学习:开启时空动态特征提取的新篇章
  • docker配置
  • 【android bluetooth 协议分析 07】【SDP详解 2】【SDP 初始化】
  • 使用FastAdmin框架开发二
  • 算法魅力-BFS解决最短路问题
  • 【Elasticsearch】function_score与rescore
  • MS Azure Eventhub 发送 AD log 到cribl
  • 定长子串中元音的最大数目
  • PyQt5布局管理(QBoxLayout(框布局))
  • OSPFv3-一二类LSA
  • Java 之字符串 --- String 类
  • 机器学习(ML)、深度学习(DL)、强化学习(RL)关系和区别