摘要:

        本文简单介绍了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中

    @Bean
    public 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: always
            schema: classpath:schema-mysql.sql

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐