Spring AI 会话记忆持久化:从入门到彻底搞懂的 MySQL 实战指南
引言:还记得第一次使用 ChatGPT 时,它能记住我们之前对话的惊喜吗?这种“记忆”能力,对于打造一个真正智能的应用至关重要。今天,我将带你深入 Spring AI 的内部,手把手教你如何为你的 AI 应用赋予“持久化记忆”,让每一次对话都充满上下文的情感与智慧。
一、故事开始:为什么我们需要“记忆”?
想象一下这个场景:你正在和一个智能客服聊天。
-
第一次:你问:“我想买一台笔记本电脑。”
-
AI 回答:推荐了几款产品。
-
第二次:你接着问:“第一款有什么颜色?”
这时,一个没有记忆的 AI 会困惑:“嗯?您说的‘第一款’是指什么?” 而一个有记忆的 AI 会流畅地回答:“您刚才看到的联想 Yoga 有灰色和银色两种配色。”
这就是会话记忆的价值:它让对话变得连续、自然、有温度。而 Spring AI 要做的,就是帮我们优雅地实现这一点。

二、揭秘:Spring AI 的记忆是如何设计的?
Spring AI 采用了一种非常聪明的“两层架构”,把复杂问题简单化:
🧠 上层:记忆管家(ChatMemory)
-
角色:就像人类的短期记忆。
-
职责:决定每次和 AI 模型聊天时,要“想起”之前的哪几句话。太多了会乱(Token 超限),太少了会断片。
-
实现:
MessageWindowChatMemory,像一个滑动窗口,只保留最近的 N 条对话。
💾 下层:记忆仓库(ChatMemoryRepository)
-
角色:就像人类的长期记忆或日记本。
-
职责:负责把所有的对话原原本本地“写”进数据库(如 MySQL),需要时再完整地“读”出来。
-
实现:
JdbcChatMemoryRepository,是连接 Spring AI 和 MySQL 的那座坚固的桥梁。
简单来说:记忆管家(ChatMemory)负责“灵活动脑”,记忆仓库(ChatMemoryRepository)负责“可靠记录”。两者配合,才造就了一个既聪明又靠谱的 AI 助手。
三、动手实战:三步搭建“记忆系统”
理论听起来很美妙,现在我们来真刀真枪地配置一下。整个过程清晰简单,就像搭积木一样。
第 1 步:引入“积木块”(Maven 依赖)
首先,我们需要告诉项目,我们要使用 Spring AI 官方提供的与 MySQL 交互的记忆组件。
<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>
</dependency>
小贴士:这个
starter包就像是一个智能工具箱,只要引入它,Spring AI 就会自动帮我们准备好后面要用到的JdbcChatMemoryRepository这个核心零件。
第 2 步:配置“连接器”(application.yml)
接下来,我们需要进行一些配置,让工具箱知道如何工作。
spring:
ai:
chat:
memory:
repository:
jdbc:
initialize-schema: always # 告诉Spring AI:请帮我自动创建数据库表
schema: classpath:sql/schema-mysql.sql # 创建表所需要的SQL脚本文件在这里
datasource:
url: jdbc:mysql://localhost:3306/your_database
username: your_username
password: your_password
第 3 步:设计“日记本”(数据库表结构)
最后,我们需要设计一下“日记本”的格式,也就是数据库表的结构。创建一个 schema-mysql.sql文件:
CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY (
id BIGINT NOT NULL AUTO_INCREMENT,
conversation_id VARCHAR(36) NOT NULL, -- 会话ID:区分不同聊天
content TEXT NOT NULL, -- 消息内容:完整记录说了什么
type VARCHAR(10) NOT NULL, -- 消息类型:用户/助手/系统
timestamp TIMESTAMP NOT NULL, -- 时间戳:保证对话顺序
PRIMARY KEY (id),
INDEX CONVERSATION_ID_IDX (conversation_id, timestamp) -- 索引:加速查询
);
解读:这张表就像一本按不同
conversation_id分册的日记。每次对话,Spring AI 都会自动帮你按时间顺序记好每一笔,完全不用你手动写 SQL 干预!
四、灵魂配置:让记忆系统“活”起来
配置好了基础设施,现在需要创建一个核心的 Bean,让记忆管家和记忆仓库协同工作。
@Configuration
public class AiConfig {
@Bean
public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository) // 注入仓库
.maxMessages(50) // 设置记忆窗口:只记得最近50轮对话
.build();
}
}
这个 Bean 是整个记忆系统的灵魂:
-
它告诉
MessageWindowChatMemory(记忆管家):“你的记忆数据都存在那个chatMemoryRepository(记忆仓库)里。” -
maxMessages(50)是一个黄金平衡点:既保证了对话上下文的连贯性,又防止了因记忆过长导致的 API 令牌消耗过大和模型响应变慢。
五、业务实现:轻松管理聊天历史
最棒的部分来了!由于 Spring AI 已经把脏活累活都干完了,我们在业务层(如 Controller)调用记忆功能变得异常简单。
@RestController
@RequestMapping("/chat/history")
@RequiredArgsConstructor
public class ChatHistoryController {
// 直接注入Spring AI为我们准备好的“记忆仓库”
private final ChatMemoryRepository chatMemoryRepository;
/**
* 获取某个会话的完整聊天历史
* 比如:用户想回顾之前和AI的整个聊天过程
*/
@GetMapping("/{chatId}")
public List<MessageVO> getChatHistory(@PathVariable String chatId) {
// 一行代码搞定!底层复杂的数据序列化、SQL查询都由框架完成
List<Message> messages = chatMemoryRepository.findByConversationId(chatId);
return messages.stream().map(MessageVO::new).toList();
}
/**
* 删除某个会话的所有记录
* 比如:用户想清空某次聊天,重新开始
*/
@DeleteMapping("/{chatId}")
public void deleteChatHistory(@PathVariable String chatId) {
// 同样是一行代码,清晰易懂
chatMemoryRepository.deleteByConversationId(chatId);
}
}
看到这里的优雅了吗? 我们不需要编写任何 SQL 语句,也不需要理解消息是如何被序列化成 JSON 存入 content字段的。Spring AI 的封装,让我们可以像使用普通 Java 集合一样操作数据库中的聊天记录。
六、全景图:一次用户请求的完整旅程
让我们通过一个生动的例子,把上面的知识点串联起来,看看从用户提问到收到回答,记忆系统是如何全程参与的:
-
用户提问:在聊天界面输入:“这款电脑的续航怎么样?” 并点击发送。前端的请求中包含了
chatId(例如"chat_001")。 -
记忆唤醒:
ChatMemory(记忆管家)收到请求,它转身对ChatMemoryRepository(记忆仓库)说:“嘿,帮我把chat_001这个会话的日记本拿给我看看。” -
检索记忆:记忆仓库(
JdbcChatMemoryRepository)熟练地打开 MySQL 数据库,执行查询,将之前所有关于chat_001的对话记录按时间顺序整理好,交还给记忆管家。 -
智能裁剪:记忆管家发现日记本太厚了(超过了50条),它遵循“最近50条”的原则,只摘取了最新的相关对话(比如用户之前问过“联想Yoga”),准备作为上下文。
-
寻求答案:记忆管家将“精简版”的对话历史和新问题一起发送给大语言模型(如 GPT-4)。模型因为有上下文,能精准理解“这款电脑”指的是之前讨论的“联想Yoga”,然后生成关于其续航能力的专业回答。
-
珍藏记忆:收到模型的回答后,记忆管家会将用户的新问题和AI的新回答作为新的一页,郑重地交给记忆仓库,由它存入数据库的
SPRING_AI_CHAT_MEMORY表中。这样,下次聊天时,这段记忆就又可以被唤醒了。
七、优雅背后的思考
通过今天的实战,我们看到了 Spring AI 如何通过 ChatMemory 和 ChatMemoryRepository 的巧妙分工,将复杂的会话记忆持久化问题变得如此简单和优雅。
然而,一个优秀的工程师总能发现潜在的问题:这种基于 MessageWindowChatMemory的设计,虽然完美服务于 AI 模型,但它为了实现滑动窗口,会在数据库层面删除旧消息。这意味着,从业务角度看,我们的聊天记录并不是“永久”的。
那么,如何实现既能给 AI 模型提供“短期记忆”,又能为业务留存“永久历史”的完美方案呢?这将是我们在下一篇文章《解决Spring AI聊天记录丢失:自定义Advisor实现持久化存储》中要揭秘的核心内容。
附录:快速回顾
|
核心概念 |
作用 |
好比是 |
|---|---|---|
|
|
持久化引擎,直接与数据库交互 |
日记本 |
|
|
记忆管理器,控制上下文窗口 |
记忆管家 |
|
|
区分不同会话的唯一标识 |
日记本的分册标签 |
|
|
限制单次对话上下文的长度 |
记忆的黄金七秒法则 |
更多推荐


所有评论(0)