让AI对话拥有"长期记忆"的能力,告别金鱼般的7秒记忆!🤖

        在构建智能对话系统时,记忆管理是决定用户体验的关键因素。Spring AI提供了强大的记忆管理功能,本文将手把手教你如何配置Redis和MySQL两种不同的记忆存储方案,让你的AI应用拥有持久的对话记忆能力!

一、Spring AI 中对话记忆的实现方式

        Spring AI 提供了多种实现对话记忆的方式,以满足不同应用场景的需求。其中,常见的方式包括数据库存储🗄️。

数据库存储:为了实现对话历史的持久化存储,Spring AI 支持使用数据库来存储对话记忆。例如,可以使用 MySQL、Redis 等数据库。以 MySQL 为例,通过配置数据源,将对话消息存储到 MySQL 数据库中。MysqlChatMemoryRepository类通过JdbcTemplate与 MySQL 数据库进行交互,实现了对话消息的存储和查询功能。这种方式适用于需要长期保存对话历史的场景,如客服系统的对话记录存档,以便后续进行数据分析和服务质量评估等。而使用 Redis 存储对话记忆,则利用了 Redis 的高性能和高并发特性,适合在对响应速度要求较高的场景中使用,如实时聊天应用中,能够快速地获取和更新对话历史记录,保证对话的流畅性💬。

除了上述两种方式,Spring AI 还支持其他存储方案,并且提供了扩展接口,允许开发者根据自己的需求实现自定义的对话记忆存储方式,以满足更加复杂和多样化的应用场景需求🤝。

二、代码实战:Spring AI 对话记忆的配置与使用

 

2.1 🔥 项目环境搭建

        使用 Spring AI 实现对话记忆功能之前,我们需要先搭建好项目环境。使用 Maven 来管理项目依赖,首先在pom.xml文件中添加 Spring AI 及相关依赖:

<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>1.0.0.1</version>
</dependency>
<!--    chatMemory    -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-memory</artifactId>
    <version>1.0.0.1</version>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-memory-jdbc</artifactId>
    <version>1.0.0.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.31</version>
</dependency>

        上述配置中,引入了 Spring AI 的核心依赖 DashScope ,集成的依赖spring-ai-alibaba-starter 。同时,添加了 MySQL 数据库连接和 Spring JDBC 相关依赖,用于实现对话记忆的持久化存储😉。 

 2.2 📦 Spring AI记忆管理核心配置
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  application:
    name: spring-ai
  ai:
    dashscope:
      api-key: "xxx-API_KEY"
  
    chat:
      memory:
        repository:
          jdbc:
            mysql:
              driver-class-name: com.mysql.cj.jdbc.Driver
              jdbc-url: jdbc:mysql://localhost:3306/spring_ai?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowMultiQueries=true&tinyInt1isBit=false&allowLoadLocalInfile=true&allowLocalInfile=true&allowUrl
              username: root
              password: root
              enabled: true  # 持久化存储
  • spring.ai.dashscope.api-key:配置 DashScope 的 API 密钥,用于访问 DashScope 提供的大模型服务。在使用 DashScope 模型进行对话时,需要提供有效的 API 密钥才能进行认证和调用。

  • spring.ai.chat.memory.repository.jdbc.mysql:配置 MySQL 相关参数,用于实现对话记忆的持久化存储

    • driver-class-name指定 MySQL 驱动类为com.mysql.cj.jdbc.Driver;

    • jdbc-url指定数据库连接 URL,连接到本地的spring_ai数据库,并设置了一些连接参数,如字符编码、禁用 SSL 等;

    • username和password分别指定数据库的用户名和密码为root;

    • enabled设置为true表示启用 MySQL 持久化存储 。

通过这些配置,Spring AI 可以与 MySQL 数据库建立连接,并将对话记忆数据存储到数据库中,以便长期保存和查询📚

2.3 🧩 核心代码实现 
2.3.1 MysqlMemoryConfig 配置类
package com.atg.spring_ai.config;


import com.alibaba.cloud.ai.memory.jdbc.MysqlChatMemoryRepository;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

/*
author: atg
*/
// 配置mysql存储话记忆的配置

@Configuration
public class MysqlMemoryConfig {
    // 数据库驱动

    @Value("${spring.ai.chat.memory.repository.jdbc.mysql.jdbc-url}")
    private String mysqlJdbcUrl;
    @Value("${spring.ai.chat.memory.repository.jdbc.mysql.username}")
    private String mysqlUsername;
    @Value("${spring.ai.chat.memory.repository.jdbc.mysql.password}")
    private String mysqlPassword;
    @Value("${spring.ai.chat.memory.repository.jdbc.mysql.driver-class-name}")
    private String mysqlDriverClassName;

    @Bean
    public MysqlChatMemoryRepository mysqlChatMemoryRepository() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(mysqlDriverClassName);
        dataSource.setUrl(mysqlJdbcUrl);
        dataSource.setUsername(mysqlUsername);
        dataSource.setPassword(mysqlPassword);
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return MysqlChatMemoryRepository.mysqlBuilder()
                .jdbcTemplate(jdbcTemplate)
                .build();
    }
}

这个配置类的作用是配置 MySQL 连接,并创建MysqlChatMemoryRepository实例,用于将对话记忆数据存储到 MySQL 数据库中。具体分析如下:

  1. 通过@Value注解从application.yml配置文件中读取 MySQL 的连接 URL、用户名、密码和驱动类名,并将其注入到相应的成员变量中。
  2. 在mysqlChatMemoryRepository方法中,首先创建DriverManagerDataSource数据源对象,设置其驱动类名、URL、用户名和密码,从而建立与 MySQL 数据库的连接。
  3. 然后创建JdbcTemplate对象,它是 Spring JDBC 框架提供的核心类,用于执行 SQL 语句。这里将刚刚创建的数据源dataSource传递给JdbcTemplate的构造函数,使其能够使用该数据源进行数据库操作。
  4. 最后,使用MysqlChatMemoryRepository的构建器模式,通过mysqlBuilder()方法创建构建器,设置jdbcTemplate,并调用build()方法构建MysqlChatMemoryRepository实例。

这个实例将用于在后续的代码中进行对话记忆数据的存储和查询操作,实现对话记忆的持久化功能💾。

2.3.2 核心代码实现
package com.atg.spring_ai.controller;

import com.alibaba.cloud.ai.memory.jdbc.MysqlChatMemoryRepository;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


import java.util.List;

import static org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID;

/*
author: atg
time: 2025/6/9 15:43
*/

@RestController
@RequestMapping("/memory/chat")
public class DashScopeChatMemoryController {

    private final ChatClient chatClient;

    private final MessageWindowChatMemory messageWindowChatMemory;

    private static final int MAX_MESSAGES = 10;


    public DashScopeChatMemoryController(ChatClient.Builder builder, MysqlChatMemoryRepository mysqlChatMemoryRepository) {
        // 创建MessageWindowChatMemory对象,并设置chatMemoryRepository和maxMessages属性
        this.messageWindowChatMemory = MessageWindowChatMemory.builder()
                .chatMemoryRepository(mysqlChatMemoryRepository)
                .maxMessages(MAX_MESSAGES)
                .build();

        // 创建ChatClient对象,并设置defaultAdvisors属性
        this.chatClient = builder
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(messageWindowChatMemory)
                                .build()
                )
                .build();
    }

    @GetMapping("/call")
    public String call(@RequestParam(value = "query", defaultValue = "你好,我的外号是TT,请记住呀") String query,
                       @RequestParam(value = "conversation_id", defaultValue = "yingzi") String conversationId) {

        return chatClient.prompt(query).advisors(
                a -> a.param(CONVERSATION_ID, conversationId))
                .call().content();

    }

    @GetMapping("/messages")
    public List<Message> messages(@RequestParam(value = "conversation_id", defaultValue = "yingzi") String conversationId) {
        return messageWindowChatMemory.get(conversationId);
    }

}

在这个控制器中,定义了两个接口方法,用于实现对话交互和获取对话历史:

  1. call方法:接收用户输入的query(查询内容,默认值为 “你好,我的外号是 TT,请记住呀”)和conversation_id(对话 ID,默认值为 “yingzi”)。通过chatClient.prompt(query)构建对话请求,设置advisors参数,其中a -> a.param(CONVERSATION_ID, conversationId)表示将对话 ID 传递给MessageChatMemoryAdvisor,以便它能够根据对话 ID 管理对话记忆。最后调用call().content()发起对话请求并获取模型返回的响应内容,将其作为方法的返回值返回给前端,实现了用户与模型的对话交互功能💬。
     
  2. messages方法: 接收conversation_id(对话 ID,默认值为 “yingzi”)。 messageWindowChatMemory.get(conversationId)方法从MessageWindowChatMemory中获取指定对话 ID 的对话历史记录,返回一个包含Message对象的列表,前端可以根据这些消息展示对话历史,方便用户查看之前的对话内容📜

 

三、总结 🎯

        本文通过详细的代码示例和实践要点,全面解析了 Spring AI 中 Chat Model基础使用方法以及进阶技巧 🧰。开发者可以利用这些知识高效地构建智能对话应用,实现从简单对话到复杂交互的多样化功能 🚀

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐