在上一篇Advisor中我们提到了聊天记忆的几个Advisor,今天来详细了解一下聊天记忆

大模型本身是没有记忆的,虽然我们在使用deepseek或者豆包等应用时,大模型仿佛存在记忆,但那是应用的封装,单纯调用api时,大模型并没有对聊天历史的记忆

要使大模型能够记忆聊天历史,需要我们调用时进行额外处理

最小化样例

同样的,我们先来看个最简单的例子

package com.example.spring_ai.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpringAi08ChatMemory
{

    private final ChatClient chatClient;

    public SpringAi08ChatMemory(ChatClient.Builder chatClientBuilder)
    {
        ChatMemory chatMemory = MessageWindowChatMemory.builder().build();

        this.chatClient = chatClientBuilder.defaultAdvisors(
                new SimpleLoggerAdvisor(),
                MessageChatMemoryAdvisor.builder(chatMemory).build()
        ).build();
    }

    /**
     * 聊天记忆
     * @param userInput
     * @param userId 用户id
     * @return
     */
    @GetMapping("/ai/memory")
    String memory(String userInput, String userId)
    {
        return this.chatClient.prompt()
                .user(userInput)
                .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, userId))
                .call()
                .content();
    }


}

在这个例子中,使用聊天记忆分为三步:

1)创建ChatMemory

2)在创建ChatClient的时候,配置聊天记忆的Advisor

3)在发送请求时,加入一个能唯一标识当前会话的id,这里方便起见用的用户id

聊天记忆的原理

在系统中,为每一个对话都存储了一份历史聊天记忆

请求前:

取出历史聊天记忆,并将最新请求追加在末尾,一起发送给大模型

请求后:

将大模型的响应加入到历史聊天记忆的末尾

进阶知识

在了解了聊天记忆的使用和基本原理后,我们再看下下列进阶知识:

1)聊天记忆相关接口及类

2)spring-ai内置的聊天记忆实现

3)其他框架的相关功能

聊天记忆相关接口及类

BaseChatMemoryAdvisor

        |--ChatMemory

                |--ChatMemoryRepository

像前面原理中提到的,聊天记忆相关接口分为三层:

BaseChatMemoryAdvisor:负责在请求前和请求后追加对话内容,内部包含一个ChatMemory

ChatMemory:该层负责实现聊天记忆的存储策略,例如最大支持n条,或者最大支持n个token等等。内部包含一个ChatMemoryRepository

ChatMemoryRepository:该层负责消息的实际存储,例如保存在内存中,或者数据库中等。

spring-ai内置的聊天记忆实现

这里同样分层来看:

ChatMemoryRepository:存储方式默认实现为InMemoryChatMemoryRepository,同时支持cassandra、neo4j和关系型数据库jdbc类的数据库存储。

ChatMemory:目前只有MessageWindowChatMemory,其维护固定容量的消息(默认 20 条)

BaseChatMemoryAdvisor:目前有MessageChatMemoryAdvisor、PromptChatMemoryAdvisor、VectorStoreChatMemoryAdvisor三种,前两者的区别在于PromptChatMemoryAdvisor是将历史对话以文本的形式追加到SystemMessage的末尾,而MessageChatMemoryAdvisor是将历史对话以消息列表的形式追加到提示词的Messages中。VectorStoreChatMemoryAdvisor是将历史对话存储到向量数据库中,每次请求前搜索语义相近的k条历史记录(默认20),并以文本的形式追加到SystemMessage末尾。

其他框架的相关功能

聊天记忆摘要:为了压缩对话,减少聊天历史占用token数量,将历史聊天记录压缩为聊天摘要

聊天记忆摘要窗口:为了压缩对话同时又不错过最近的对话历史,保留最近n条对话,同时将n条以外的对话历史压缩为聊天摘要

此外还有知识图谱聊天记忆、实体聊天记忆、根据最大token(而不是对话条数)维护的记忆等。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐