Spring AI中使用ChatMemory实现会话记忆功能

文章目录

1、需求

我们知道大型语言模型 (LLM) 是无状态的,这就意味着他们不会保存之前的交互信息。当我们希望在一次会话中,模型支持多次交互,那么我们该如何实现呢? 在 Spring AI中提供了ChatMemory功能,它允许我们在与LLM的多次交互中存储与检索信息。此处我们借助Spring AI的ChatMemory功能实现一个简单的多轮对话。

    1. 集成ollama部署的本地模型
    1. 使用jdbc存储聊天历史信息(保存到mysql中)

2、ChatMemory中消息的存储位置


默认情况下是存储在内存中,但是它也提供了JDBCCassandraNeo4j的实现。

如果我们想自定义实现存储该如何实现呢? 需要实现ChatMemoryRepository接口。此处我们不自己实现,使用Spring AI 提供的 JDBC存储实现。

注意:使用Spring AI 提供的JDBC实现需要引入 spring-ai-starter-model-chat-memory-repository-jdbc 包

3、实现步骤

1、引入依赖

xml 复制代码
<properties>
        <spring-ai.version>1.0.0</spring-ai.version>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>        <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 集成ollama -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-ollama</artifactId>
    </dependency>
    <!-- 使用jdbc存储模型的聊天记录 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </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、配置Spring AI

yaml 复制代码
spring:
  application:
    name: spring-ai-advisor-chat-memory
  ai:
    ollama:
      base-url: http://localhost:11434 # 配置ollama的地址
      chat:
        model: deepseek-r1:14b  # 配置模型的名称
        options:
          temperature: 0.7 # 配置模型温度
    chat:
      memory:
        repository:
          jdbc:
            initialize-schema: always
            # 配置初始化脚本的位置
            schema: classpath:org/springframework/ai/chat/memory/repository/jdbc/schema-mariadb.sql
            platform: mariadb
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/temp_work?useUnicode=true&characterEncoding=utf8&autoReconnectForPools=true&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

logging:
  level:
    # 用于支持llm模型输入前和输入后的日志打印
    org.springframework.ai.chat.client.advisor: debug

3、配置chatmemory

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepositoryDialect;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * ai 配置
 * @author huan.fu
 * @date 2025/6/8 - 08:44
 */
@Configuration
public class AiConfiguration {

    @Bean
    public JdbcChatMemoryRepository jdbcChatMemoryRepository(JdbcTemplate jdbcTemplate, DataSource dataSource) {
        JdbcChatMemoryRepositoryDialect dialect = JdbcChatMemoryRepositoryDialect.from(dataSource);
        return JdbcChatMemoryRepository.builder().jdbcTemplate(jdbcTemplate).dialect(dialect).build();
    }

    @Bean
    public ChatMemory chatMemory(ChatMemoryRepository jdbcChatMemoryRepository){
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(jdbcChatMemoryRepository)
                // 每个会话最多记录20条信息
                .maxMessages(20)
                .build();
    }

    @Bean
    public ChatClient chatClient(OllamaChatModel ollamaChatModel, ChatMemory chatMemory){
        // 配置模型 (因为我们使用的是 ollama, 所以此处写的是 OllamaChatModel)
        return ChatClient.builder(ollamaChatModel)
                // 默认系统提示词
                .defaultSystem("你是一个拥有丰富经验的编程小助手,擅长编写各种程序。")
                // 添加模型输入前和输入后日志打印
                .defaultAdvisors(new SimpleLoggerAdvisor(),
                        // 配置 chat memory advisor
                        MessageChatMemoryAdvisor.builder(chatMemory).build())
                .build();
    }
}

4、java层传递conversaionId


4、验证

依次访问如下2个http请求

复制代码
http://localhost:8080/blockChat?prompt=介绍一下你自己&conversationId=123456789
http://localhost:8080/blockChat?prompt=我刚刚问的问题是什么&conversationId=123456789


会话id需保持一致

从上图中可以,在第二次询问模型时,模型知道上次的问题是什么。

5、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/spring-ai/spring-ai-advisor-chat-memory

6、参考文档

1、https://docs.spring.io/spring-ai/reference/api/chat-memory.html

相关推荐
大刘讲IT16 分钟前
赋能中小企业:基于五大开源模块的AI智能体构建方案与细化拆解
人工智能·经验分享·ai·开源·制造
SEOETC2 小时前
AIGC|杭州AI优化企业新榜单与选择指南
人工智能·ai·aigc
哥布林学者2 小时前
吴恩达深度学习课程二: 改善深层神经网络 第二周:优化算法(三)Momentum梯度下降法
深度学习·ai
逻极2 小时前
Kiro 安全最佳实践:守护代理式 IDE 的 “防火墙”
ide·人工智能·安全·ai
熊猫_豆豆4 小时前
QT6 写一个诗词鉴赏、朗诵、阅读程序(智谱清言AI赏析接口)
c++·ai·智谱清言·古诗鉴赏
小白跃升坊4 小时前
信息检索类智能体构建范式
人工智能·ai·全文检索·智能体
王哈哈^_^5 小时前
【完整源码+数据集】蓝莓数据集,yolo11蓝莓成熟度检测数据集 3023 张,蓝莓成熟度数据集,目标检测蓝莓识别算法系统实战教程
人工智能·算法·yolo·目标检测·计算机视觉·ai·视觉检测
带刺的坐椅6 小时前
(对标 Spring IA 和 LangChain4j)Solon AI & MCP v3.7.0, v3.6.4, v3.5.8 发布(支持 LTS)
java·spring·ai·solon·mcp·langchain4j
HyperAI超神经10 小时前
解决蛋白质构象异质性的原子级建模挑战!David Baker团队PLACER框架解析
人工智能·深度学习·ai·ai4s·蛋白质结构
Oxo Security1 天前
【AI安全】检索增强生成(RAG)
人工智能·安全·网络安全·ai