【ChatMemory聊天记忆】
摘要:
本文简单介绍了SpringAI的聊天记忆功能,聊天记忆解决了大语言模型(LLM)无状态的问题,通过ChatMemory抽象层实现多轮对话上下文存储。还对聊天记忆的具体实现进行了简单的介绍,帮助新手快速上手聊天记忆功能。
一,简单介绍
1,为什么需要聊天记忆
大语言模型(LLM)本质上是无状态的,这意味着它们不会保留历史交互信息。当需要跨多轮交互保持上下文时,这一特性会带来局限。为此,Spring AI 提供了聊天记忆功能,支持在 LLM 交互过程中存储和检索上下文数据。
2,什么是ChatMemory
ChatMemory 抽象层支持实现多种记忆类型以满足不同场景需求。消息的底层存储由ChatMemoryResponsitory 处理,其唯一职责是存储和检索消息。ChatMemory 实现类可自主决定消息保留策略 — 例如保留最近 N 条消息、按时间周期保留或基于 Token 总量限制保留。
3,聊天记忆 / 历史
(1)聊天记忆:大语言模型在对话过程中保留并用于维持上下文感知的信息。
(2)聊天历史:完整的对话记录,包含用户与模型之间交换的所有消息。
若需完整记录所有历史消息,建议采用其他方案(如MySql、Redis...)。
二,具体实现
Spring AI 通过 ChatMemoryRepository 抽象层实现聊天记忆存储
MessageWindowChatMemory 维护固定容量的消息窗口(默认 20 条)。当消息超限时,自动移除较早的对话消息(始终保留系统消息)。
1,基于内存(默认)
InMemoryChatMemoryRepository 基于 ConcurrentHashMap 实现内存存储。
默认情况下,若未配置其他 Repository,Spring AI 将自动配置 InMemoryChatMemoryRepository 类型的 ChatMemoryRepository 的Bean供直接使用。
@Bean
public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {return MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).maxMessages(10).build();
}
2,基于关系型数据库(JdbcChatMemoryRepository )
JdbcChatMemoryRepository 是内置的 JDBC 实现,支持多种关系型数据库,适用于需要持久化存储聊天记忆的场景。
(1)引入依赖
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
(2)创建表 SPRING_AI_CHAT_MEMORY(MySQL)
也可以创建名为 schema-mysql.sql 的.sql文件在resource路径下,后面通过在yaml文件配置自动初始化
CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY
(conversation_id VARCHAR(36) NOT NULL,content TEXT NOT NULL,type VARCHAR(10) NOT NULL,`timestamp` TIMESTAMP NOT NULL,CONSTRAINT TYPE_CHECK CHECK (type IN ('USER', 'ASSISTANT', 'SYSTEM', 'TOOL'))
);
(3)自动注入并构造chatMemory
@Bean
public ChatMemory chatMemory(JdbcChatMemoryRepository chatMemoryRepository) {return MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).maxMessages(13).build();
}
(4)手动创建JdbcChatMemoryRepository的Bean
@Autowired
JdbcTemplate jdbcTemplate;ChatMemoryRepository chatMemoryRepository = JdbcChatMemoryRepository.builder().jdbcTemplate(jdbcTemplate)//指定数据库类型,这里是PostgreSQL库.dialect(new PostgresChatMemoryDialect()).build();
3,构造chatClient实例
在构造chatClient时自动注入chatMemory实例并添加该实例到聊天记忆拦截器实例 MessageChatMemoryAdvisor中
@Beanpublic ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory) {return ChatClient.builder(model) // 创建ChatClient工厂.defaultSystem("system prompt").defaultAdvisors(new SimpleLoggerAdvisor()) // 日志拦截器// 会话历史记录的拦截器,用于会话记忆.defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build();}
三,基本属性配置
1,initialize-schema
控制初始化 Schema 的时机。可选值:embedded(默认)、always、never。
2,schema
用于初始化的 Schema 脚本位置。支持classpath:URL 及平台占位符。
spring:ai:chat:memory:repository:jdbc:initialize-schema: alwaysschema: classpath:schema-mysql.sql