SpringAI——对话记忆

它指的是模型在与用户进行交互式对话过程中,能够追踪、理解并利用先前对话上下文的能力。就像我们人与人之间的对话一样,所有对话都是基于前面的对话,每一句交谈都有前面的对话作为基础,这样才不会牛头不对马嘴。那我们与AI之间的对话也是,我们希望AI可以记住我们之前的对话,而不是每次对话钱都要将之前的再重复一遍。

接下来我们通过代码来学习一下,前提已经创建好项目和配置好了环境看我之前的文章SpringAI------ChatClient的配置与运用

首先我们看一下没有记忆的对话:

复制代码
 @RequestMapping("/normal/chat")
    public String normalChat(String input) {
        UserMessage userMessage = new UserMessage(input);
        return chatModel.call(new Prompt(userMessage)).getResult().getOutput().getContent();
    }

那我再问他叫什么名字,正常来说它应该叫严珍,但是它是没有记忆的,所以:

那我们想,每次把每次对话(包括用户提问和AI回答)都存在一个列表里面,每次提问的时候都把列表传给大模型就可以了,这样它不就有记忆了,开干:

复制代码
private final static List<Message> messages = new ArrayList<>();


@RequestMapping("/memory/chat")
public String chat(String input) {
        UserMessage userMessage = new UserMessage(input);
        messages.add(userMessage);
        String content = chatModel.call(new Prompt(messages)).getResult().getOutput().getContent();
        AssistantMessage assistantMessage = new AssistantMessage(content);
        messages.add(assistantMessage);
        return content;
    }

结果:

但是这种手动添加上下文的聊天记忆太过于麻烦,聊天记录需要开发人员自己管理,不易于扩展,SpringAI 为我们提供了一个基于内存的对话记忆ChatMemory,请看Demo:

复制代码
 private final ChatClient chatClient;
 @Autowired
 public MemoryController(ChatClient.Builder builder) {
        ChatMemory chatMemory = new InMemoryChatMemory();
        this.chatClient = builder
                .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
                .build();
    }

    @RequestMapping("/memory/chat")
    public String chat(String input) {
        String content = chatClient.prompt()
                .user( input)
                .call().content();
        return content;
    }

它将一个 MessageChatMemoryAdvisor 注册到 ChatClient 中,这个 Advisor 的作用是在每次调用大模型时,自动将历史对话记录添加到 Prompt 中,从而让模型"记住"之前的对话内容。

我可以看到InMemoryChatMemory是通过一个Map来存储

原理简述:

  • 每次用户发送一条消息时,MessageChatMemoryAdvisor 会从 ChatMemory 中取出之前的历史对话。
  • 将历史对话插入到当前请求的 Prompt 中。
  • 发送给模型处理后,再把模型回复也保存进 ChatMemory。

这样就实现了带上下文记忆的连续对话。

相关推荐
karry_k3 小时前
MyBatis批量insert-select踩坑:useGeneratedKeys=true 可能让PostgreSQL返回大量插入结果
java·后端
karry_k3 小时前
PostgreSQL 在 MyBatis 中执行正常 SQL 失效:一次 DELETE USING 踩坑记录
java·后端
垚森3 小时前
AI时代,让曾经的遗憾变成现实
ai
leonshi4 小时前
使用embedchain快速建立rag知识库,本地大模型
ai·rag·ollama
SamDeepThinking6 小时前
从源码到代码:MyBatis-Flex 与 MyBatis-Plus 的逐项对比
java·后端·程序员
她的男孩9 小时前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
荣码11 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
doiito12 小时前
【Agent Harness】Gliding Horse 上下文感知与智能压缩:让 Agent 的“注意力”永不偏移
ai·rust·架构设计·系统设计·ai agent
plainGeekDev12 小时前
Gson → kotlinx.serialization
android·java·kotlin