个人名片
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?
- 专栏导航:
码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀
Spring AI 聊天记忆管理:MessageWindowChatMemory 与 MessageChatMemoryAdvisor 详解
引言
在现代对话系统开发中,维护对话上下文是构建智能交互体验的关键。Spring AI 框架提供了强大的聊天记忆管理功能,其中 MessageWindowChatMemory
和 MessageChatMemoryAdvisor
是两个核心组件。本文将深入探讨这两个组件的正确使用方法,分析常见错误原因,并提供完整的配置示例。
一、Spring AI 聊天记忆核心概念
1.1 ChatMemory 接口
ChatMemory
是 Spring AI 中定义聊天记忆行为的核心接口:
public interface ChatMemory {
String DEFAULT_CONVERSATION_ID = "default";
String CONVERSATION_ID = "chat_memory_conversation_id";
default void add(String conversationId, Message message) {
Assert.hasText(conversationId, "conversationId cannot be null or empty");
Assert.notNull(message, "message cannot be null");
this.add(conversationId, List.of(message));
}
void add(String conversationId, List<Message> messages);
List<Message> get(String conversationId);
void clear(String conversationId);
}
该接口定义了三个核心操作:
add()
- 添加消息到记忆get()
- 获取对话历史clear()
- 清除对话记忆
1.2 ChatMemoryRepository
ChatMemoryRepository
是记忆存储的抽象接口:
public interface ChatMemoryRepository {
List<String> findConversationIds();
List<Message> findByConversationId(String conversationId);
void saveAll(String conversationId, List<Message> messages);
void deleteByConversationId(String conversationId);
}
默认实现 InMemoryChatMemoryRepository
使用内存存储对话记录。
二、MessageWindowChatMemory 详解
2.1 核心特性
MessageWindowChatMemory
是 ChatMemory
的主要实现类,具有以下特点:
- 维护一个固定大小的消息窗口
- 自动移除旧消息,保留最新消息
- 默认保留20条消息(可配置)
- 特殊处理系统消息(不会被自动移除)
2.2 正确创建方式
错误方式(会导致编译错误):
// 错误!构造函数是私有的
ChatMemory memory = new MessageWindowChatMemory(repository, 20);
正确方式 - 使用 Builder 模式:
@Bean
public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(20) // 可选,默认20
.build();
}
2.3 完整配置示例
@Configuration
public class ChatMemoryConfig {
@Bean
public ChatMemoryRepository chatMemoryRepository() {
return new InMemoryChatMemoryRepository();
}
@Bean
public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(30) // 自定义消息窗口大小
.build();
}
}
三、MessageChatMemoryAdvisor 详解
3.1 作用与功能
MessageChatMemoryAdvisor
是一个聊天顾问,负责:
- 自动将对话历史添加到请求中
- 管理不同会话的记忆
- 与
ChatMemory
协同工作
3.2 正确创建方式
错误方式:
// 错误!构造函数是私有的
new MessageChatMemoryAdvisor(chatMemory);
正确方式 - 使用 Builder:
MessageChatMemoryAdvisor.builder(chatMemory)
.conversationId("custom-id") // 可选
.build();
3.3 完整聊天客户端配置
@Bean
public ChatClient chatClient(OllamaChatModel chatModel, ChatMemory chatMemory) {
return ChatClient.builder(chatModel)
.defaultSystem("你是一个法律咨询助手")
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(chatMemory)
.conversationId("legal-consultation")
.build()
)
.build();
}
四、常见问题解决方案
4.1 构造函数访问错误
问题:
'MessageWindowChatMemory(...)' has private access
原因:试图直接实例化私有构造的类
解决:使用 Builder 模式
4.2 Builder 访问错误
问题:
'Builder()' has private access
原因:错误使用 Builder 构造函数
解决:使用静态 builder()
方法
// 正确
MessageWindowChatMemory.builder()...
// 错误
new MessageWindowChatMemory.Builder()...
4.3 依赖注入问题
推荐做法:通过方法参数注入依赖
@Bean
public ChatMemory chatMemory(ChatMemoryRepository repo) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(repo)
.build();
}
五、最佳实践
-
合理设置消息窗口大小
- 一般对话:20-30条
- 长对话场景:50-100条
- 注意内存消耗
-
会话管理策略
// 按用户ID区分会话 MessageChatMemoryAdvisor.builder(chatMemory) .conversationId(userId) .build();
-
组合使用多个 Advisor
.defaultAdvisors( new SimpleLoggerAdvisor(), new RetryAdvisor(), MessageChatMemoryAdvisor.builder(chatMemory).build() )
-
自定义记忆处理逻辑
- 继承
MessageWindowChatMemory
- 重写
process()
方法
- 继承
六、扩展应用
6.1 Redis 记忆存储
@Bean
public ChatMemoryRepository redisChatMemoryRepository(RedisTemplate<String, Object> redisTemplate) {
return new RedisChatMemoryRepository(redisTemplate);
}
6.2 自定义记忆策略
public class PriorityMessageChatMemory implements ChatMemory {
// 实现优先保留重要消息的逻辑
}
结论
Spring AI 的记忆管理功能通过 MessageWindowChatMemory
和 MessageChatMemoryAdvisor
提供了强大而灵活的对话上下文管理能力。关键在于正确使用 Builder 模式创建这些组件,并合理配置记忆策略。本文介绍的模式和最佳实践可以帮助开发者构建更智能、更自然的对话系统。
通过遵循这些指导原则,你可以避免常见的配置错误,并充分利用 Spring AI 提供的记忆管理功能,为用户创造更加连贯和个性化的对话体验。