Spring AI Alibaba 中的 Memory 短期记忆(通俗易懂汇总版)

💡 核心结论:一句话先记住

如果说大模型天生是个"金鱼脑(只有 7 秒记忆)",那么 Short-term Memory(短期记忆) 就是帮它在同一次聊天会话(Thread)里装上一个暂存硬盘。有了它,Agent 才能记得你上一句说了啥、不吃什么菜,从而根据上下文连贯地回答问题!

但要小心,聊天记录存得太多会让 Agent "脑容量爆表",所以我们还需要学会给记忆做"瘦身"(上下文工程)。


🛑 一、 概述与理解:短期记忆是怎么工作的?

  • 大白话: 每次你跟 Agent 说话,消息会在"用户输入"和"模型回答"之间来回交替。Spring AI Alibaba 把这串对话历史(消息列表)作为 Agent 的内部状态 (State) 来管理。
  • 幕后功臣 checkpointer 框架底层用了一个叫 checkpointer 的机制把这些状态保存起来。不管你是存内存里还是数据库里,只要下次带着同一个"会话 ID"来,Agent 就能把之前的聊天记录读取出来,无缝接上茬。

⚠️ 二、 核心痛点:记忆带来的"上下文过长"问题

  • 大白话: 把聊天历史全留着看似很完美,但大模型的"脑容量"(上下文窗口)是有限的!
  • 带来的灾难: 1. 聊得太长,Token 爆了,系统直接报错。
  1. 就算用的是支持超长文本的大模型,废话太多也会导致它"走神",被过时或跑题的信息分散注意力,回答质量断崖式下跌。

💻 三、 使用方法:怎么给 Agent 装上记忆?

在 Spring AI Alibaba 中,只需要在构建 Agent 的时候,随手挂载一个 checkpointer 即可。

1. 本地测试玩玩(抄作业区):

java 复制代码
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import com.alibaba.cloud.ai.graph.agent.ReactAgent;

// 核心大法:给 Agent 配备一个短期记忆保管箱
ReactAgent agent = ReactAgent.builder()
        .name("memory_agent")
        .model(chatModel)
        .saver(new MemorySaver()) // ⭐ 挂载它,Agent 瞬间不再失忆!
        .build();

2. 在生产环境中(必看避坑):

如果是企业上线环境,千万别用 MemorySaver!因为重启服务器记忆就丢了。生产环境必须用持久化的存储,比如把记录存到 Redis 里(使用 RedisSaver 替代 MemorySaver)。


🧠 四、 常见模式:如何给记忆"瘦身"?(4招减负大法)

为了解决前面说的"脑容量爆表"问题,官方提供了几种上下文工程的常见模式:

  1. 修剪消息(Trimming): 最实用!聊天超过一定条数,就把最老的聊天记录掐掉,只保留最近的 N 条。
  2. 删除消息(Deleting): 硬核清理!在图状态中永久删除某些特定消息,或者干脆清空所有历史(ClearAllMessages)。
  3. 总结消息(Summarizing): 高级玩法!让 AI 把前 100 句废话总结成一句"用户想去北京旅游",然后用这句总结替换掉长篇大论。
  4. 自定义策略: 自己写过滤规则,想怎么留就怎么留。

💻 代码实战:用 Hook 拦截并"修剪/删除"记忆:

java 复制代码
import com.alibaba.cloud.ai.graph.agent.hook.MessagesModelHook;
import org.springframework.ai.chat.messages.Message;
import java.util.List;

// 招式 1:修剪消息(MessageTrimmingHook 效果)
MessagesModelHook trimmingHook = new MessagesModelHook() {
    @Override
    public List<Message> beforeModel(List<Message> messages, RunnableConfig config) {
        // 发现记忆太长?只保留最近的 10 条消息,帮大模型减负
        if (messages.size() > 10) {
            return messages.subList(messages.size() - 10, messages.size());
        }
        return messages;
    }
};

// 招式 2:删除所有历史消息(ClearAllMessagesHook 效果)
MessagesModelHook clearHook = new MessagesModelHook() {
    @Override
    public List<Message> beforeModel(List<Message> messages, RunnableConfig config) {
        // 斩断过去,重新做人:只保留用户的最后一条提问
        return List.of(messages.get(messages.size() - 1));
    }
};

// 挂载修剪策略,打造一个既有记忆又不会超载的完美 Agent
ReactAgent smartAgent = ReactAgent.builder()
        .name("smart_memory_agent")
        .model(chatModel)
        .saver(new MemorySaver()) // 开启记忆
        .hooks(trimmingHook)      // ⭐ 开启自动瘦身!
        .build();

🛠️ 五、 访问与自定义记忆的四条密道

有时候你的业务需要主动去查阅或者修改当前的记忆状态,官方提供了四个切入点:

  1. Before Model: 在把记录喂给大模型之前拦截。上面的 Hook 代码用的就是这招,非常适合做修剪和屏蔽。
  2. After Model: 在大模型刚回答完之后拦截。适合用来做记忆总结(比如刚聊完一局,马上写个小结存起来)。
  3. 工具(Tools): 把读写状态的能力封装成一把"工具"塞给大模型,让它自己决定什么时候去查改记忆。
  4. 提示(Prompt): 不改历史记录,而是将部分重要的老记忆提取出来,偷偷塞进当前对话的 System Prompt(系统提示词)里,强行唤醒大模型的关注。

🎯 终极秒记口诀

智能聊天需记性,短期记忆来搞定;

Saver 挂载轻松起,生产换成 Redis 存;

聊得太多脑子懵,修剪删除加总结;

Hook 拦截去瘦身,脑容量小也不怕!