Spring AI Alibaba 记忆持久化到 Redis 实战指南
Spring AI Alibaba 记忆持久化到 Redis 实战指南
基于 Spring AI Alibaba 1.1.2.0,实现 Agent 短期记忆的 Redis 持久化,解决多轮对话中的上下文管理与状态恢复问题。
Spring AI Alibaba 记忆(Memory)机制详解与完整实战指南:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/162238591
上述会话记忆基于内存实现,下面基于redis实现。
一、引言
在构建智能对话 Agent 时,记忆能力是核心功能之一。Spring AI Alibaba 提供了灵活的短期记忆(Short‑term Memory)管理机制,通过 Checkpointer 将 Agent 的状态(包括对话历史)持久化到外部存储,从而实现会话级别的记忆隔离与恢复。使用 Redis 作为存储介质,不仅可以共享记忆到多个服务实例,还能避免应用重启导致的数据丢失。
二、环境要求
-
JDK
:17+
-
Spring Boot
:3.2.5
-
Spring AI Alibaba
:1.1.2.0
-
Redis
:6.x / 7.x(Windows 可选用 Memurai 或 WSL2)
-
Maven
:3.6+
-
DashScope API Key
(用于调用通义千问等模型)
三、核心概念
3.1 短期记忆(Short‑term Memory)
短期记忆让 Agent 在同一个会话(threadId)中记住之前的交互内容。在 Spring AI Alibaba 中,记忆以 Agent 状态(OverAllState)的形式存储在 Graph 的执行上下文中。
3.2 Checkpointer
Checkpointer 负责将 Agent 状态持久化到外部存储。框架提供了多种实现:
-
MemorySaver:内存存储,适合开发调试。
-
RedisSaver:Redis 存储,适合生产环境。
3.3 StateSerializer
状态序列化器,将 Java 对象序列化为字节数组存储到 Redis。框架默认使用 SpringAIJacksonStateSerializer,基于 Jackson 实现 JSON 序列化。
3.4 消息修剪(Message Trimming)
为防止长对话超出 LLM 的上下文窗口,可以通过 MessagesModelHook 在调用模型前修剪消息列表(例如保留首条和最近 N 条),或使用消息摘要(Summarization)压缩历史。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
四、完整实现步骤
4.1 创建 Maven 项目
pom.xml
注意:必须管理 Jackson 版本,避免与框架依赖冲突导致 NoSuchMethodError。
<span leaf="leaf"><?xml version="1.0" encoding="UTF-8"?></span>
关键点:通过
dependencyManagement引入jackson-bom确保所有 Jackson 模块版本一致,避免序列化方法签名不兼容。
4.2 配置文件 application.yml
<span leaf="leaf"><span>server</span>:</span>
4.3.3 Agent 配置(使用 RedisSaver)
<span leaf="leaf"><span>package</span> <span>com.badao.ai.config</span>;</span>
注意事项:
RedisSaver.builder().redisson(...)而非
redissonClient(...)。
StateSerializer不是泛型类,无需写
StateSerializer<?>。必须注册
messages字段的更新策略(如ReplaceStrategy),否则 Agent 无法正确存储对话历史。
4.3.4 消息修剪 Hook(可选)
<span leaf="leaf"><span>package</span> <span>com.badao.ai.hook</span>;</span>
4.3.5 服务层
<span leaf="leaf"><span>package</span> <span>com.badao.ai.service</span>;</span>
4.3.6 控制器
<span leaf="leaf"><span>package</span> <span>com.badao.ai.controller</span>;</span>
五、常见问题与解决方案
5.1 RedisSaver 构造方法 protected 访问错误
现象:'RedisSaver(RedissonClient, StateSerializer)' has protected access
原因:直接使用 new RedisSaver(...),但构造方法被设计为 protected。
解决:使用 Builder 模式:RedisSaver.builder().redisson(...).stateSerializer(...).build()。
5.2 Cannot resolve method 'redissonClient' in 'Builder'
现象:编译时找不到 redissonClient() 方法。
原因:Builder 中的方法名是 redisson,不是 redissonClient。
解决:改为 .redisson(redissonClient)。
5.3 NoSuchMethodError: ObjectMapper.treeToValue(TreeNode, TypeReference)
现象:调用接口时报 NoSuchMethodError,堆栈指向 SerializationHelper.deserializeMetadata。
原因:项目中 Jackson 版本不一致,框架编译时依赖的 Jackson 版本与实际运行时的版本不兼容(例如 2.15.4 与 2.17.2 方法签名不同)。
解决:在 pom.xml 中通过 dependencyManagement 统一 Jackson 版本至 2.17.2(或与 Spring Boot 默认版本一致)。详见本文 pom.xml 配置。
5.4 NumberFormatException: For input string: "5000ms"
现象:启动时 RedisConfig 字段注入失败。
原因:application.yml 中 timeout: 5000ms 带有单位,但字段类型是 int,无法解析。
解决:去掉 "ms" 后缀,直接写 timeout: 5000(单位默认为毫秒)。
5.5 记忆未生效
现象:每次请求 Agent 都像第一次对话,无法记住之前内容。
原因:
-
未配置
saver(Checkpointer)。 -
每次请求
threadId不一致。 -
StateSerializer未正确注册,无法反序列化状态。
解决:
-
确认 Agent 构建时调用了
.saver(redisSaver)。 -
确保客户端请求携带相同的
sessionId(即threadId)。 -
检查日志,确认 Redis 中已存储状态数据(可用
redis-cli KEYS '*'查看)。
六、验证测试
6.1 启动 Redis 和 Spring Boot 应用
Windows(解压版):
<span leaf="leaf">cd C:\Redis</span>
启动 Spring Boot:
<span leaf="leaf"><span>export</span> <span>DASHSCOPE_API_KEY</span><span>=</span><span>"你的API密钥"</span></span>
6.2 测试多轮对话
<span leaf="leaf"><span># 第一轮:告诉名字</span></span>
6.3 查看 Redis 存储的状态
<span leaf="leaf">redis-cli</span>
七、总结
通过本文,你学会了如何利用 Spring AI Alibaba 的 RedisSaver 将 Agent 的短期记忆持久化到 Redis,解决了多轮对话的上下文管理问题。重点包括:
-
使用
RedisSaver.builder()构建 Checkpointer,注意方法名redisson。 -
统一 Jackson 版本避免序列化冲突。
-
通过
threadId隔离不同会话的记忆。 -
可选地添加
MessagesModelHook控制上下文长度。
此方案可应用于生产环境,支持多实例共享记忆,且不易丢失。后续可结合消息摘要(Summarization)进一步优化长对话,或引入长期记忆(向量数据库)实现更复杂的场景。
参考资料:
-
Spring AI Alibaba 官方文档
-
RedisSaver 源码示例
-
DashScope 模型接入指南
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/ai002/post/20260822/Spring-AI-Alibaba-%E8%AE%B0%E5%BF%86%E6%8C%81%E4%B9%85%E5%8C%96%E5%88%B0-Redis-%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com