在上一篇文章中,我们介绍了如何引入Spring AI,本文将深入探讨如何实现聊天记录的持久化存储。
一、初始方案:内存存储的局限性
在项目初期,我们使用简单的内存存储实现聊天记录管理:
创建ChatController
编写接口
参数说明:
- CHAT_MEMORY_CONVERSATION_ID_KEY:会话key,用于区分会话。
- CHAT_MEMORY_RETRIEVE_SIZE_KEY:发送给聊天模型的上下文长度。
二、问题发现与接口分析
使用apifox测试这几个接口
可以发现在对话中确实保存了聊天记录,获取聊天记录的接口也正确返回

此处返回的聊天记录如下:
但是目前的聊天记录是存储在内存中,程序一旦关闭聊天记录就失效了,我们需要做的是将聊天记录永久存储,解决方法就是重写ChatMemory,结合Redis实现聊天记录的持久化。
三、架构演进:Redis持久化方案
核心接口设计
通过ChatMemory的源码可以看出它是一个接口,提供了将消息添加到对话(add)、从对话中检索消息(get)以及清除对话历史记录(clear)的方法,那么我们可以根据它的结构来实现一个自定义的ChatMemory。

Redis实现方案
- 首先,新建一个类命名为RedisChatMemory 实现ChatMemory接口,并添加@Component注解将它注册成一个服务,引入RedisTemplate依赖并实现ChatMemory定义的方法。
- 这里的RedisTemplate定义的模版类型约束是Message,只用于Message的数据交互,那么就意味着在配置RedisTemplate时就要指定属性类型,其次Message是接口,在反序列化时需要明确指定其具体实现类,所以我们要根据Message来自定义一个序列化器
- 接下来需要将序列器注册到RedisTemplate中
- 接下来需要将我们的RedisChatMemory通过Spring AI的Advisor添加到聊天大模型中,这里也设置了defaultSystem,后续还会根据实际使用需要进行修改。
服务层重构
现在已经完成了对ChatMemory的持久化存储,需要修改原来的ChatController类,将实现接口的逻辑部分代码移到ChatService,新建ChatSession类,以持久化存储对话
这里我们先定义三个接口,分别为获取聊天记录、获取会话列表、普通聊天
流式聊天后续会在和前端沟通后进行实现(也可能根据需要而放弃实现)
四、测试
最后我们可以使用apifox测试接口:




三个接口都很成功,返回结果符合预期
redis中存储格式如图所示:

技术方案全景
- 核心架构 Spring AI + DeepSeek模型 + Redis持久化 └─ ChatClient API层 → 记忆管理 → Redis存储 → 会话服务
- 关键技术栈
- 多态序列化:Jackson自定义TypeResolver + 类型白名单
- 上下文管理:MessageChatMemoryAdvisor + 滑动窗口策略
- 持久化方案:Redis Hash结构 + TTL自动过期