文章目录
- 1、需求
- 2、ChatMemory中消息的存储位置
- 3、实现步骤
-
- 1、引入依赖
- [2、配置Spring AI](#2、配置Spring AI)
- 3、配置chatmemory
- 4、java层传递conversaionId
- 4、验证
- 5、完整代码
- 6、参考文档
1、需求
我们知道大型语言模型 (LLM
) 是无状态
的,这就意味着他们不会保存之前的交互信息。当我们希望在一次会话中,模型支持多次交互,那么我们该如何实现呢? 在 Spring AI
中提供了ChatMemory
功能,它允许我们在与LLM的多次交互中存储与检索信息。此处我们借助Spring AI的ChatMemory功能实现一个简单的多轮对话。
-
- 集成ollama部署的本地模型
-
- 使用jdbc存储聊天历史信息(保存到mysql中)
2、ChatMemory中消息的存储位置
默认
情况下是存储在内存
中,但是它也提供了JDBC
、Cassandra
和Neo4j
的实现。
如果我们想自定义实现存储该如何实现呢? 需要实现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