💡 核心结论:一句话先记住
如果说大模型天生是个"金鱼脑(只有 7 秒记忆)",那么 Short-term Memory(短期记忆) 就是帮它在同一次聊天会话(Thread)里装上一个暂存硬盘。有了它,Agent 才能记得你上一句说了啥、不吃什么菜,从而根据上下文连贯地回答问题!
但要小心,聊天记录存得太多会让 Agent "脑容量爆表",所以我们还需要学会给记忆做"瘦身"(上下文工程)。
🛑 一、 概述与理解:短期记忆是怎么工作的?
- 大白话: 每次你跟 Agent 说话,消息会在"用户输入"和"模型回答"之间来回交替。Spring AI Alibaba 把这串对话历史(消息列表)作为 Agent 的内部状态 (State) 来管理。
- 幕后功臣
checkpointer: 框架底层用了一个叫checkpointer的机制把这些状态保存起来。不管你是存内存里还是数据库里,只要下次带着同一个"会话 ID"来,Agent 就能把之前的聊天记录读取出来,无缝接上茬。
⚠️ 二、 核心痛点:记忆带来的"上下文过长"问题
- 大白话: 把聊天历史全留着看似很完美,但大模型的"脑容量"(上下文窗口)是有限的!
- 带来的灾难: 1. 聊得太长,Token 爆了,系统直接报错。
- 就算用的是支持超长文本的大模型,废话太多也会导致它"走神",被过时或跑题的信息分散注意力,回答质量断崖式下跌。
💻 三、 使用方法:怎么给 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招减负大法)
为了解决前面说的"脑容量爆表"问题,官方提供了几种上下文工程的常见模式:
- 修剪消息(Trimming): 最实用!聊天超过一定条数,就把最老的聊天记录掐掉,只保留最近的 N 条。
- 删除消息(Deleting): 硬核清理!在图状态中永久删除某些特定消息,或者干脆清空所有历史(ClearAllMessages)。
- 总结消息(Summarizing): 高级玩法!让 AI 把前 100 句废话总结成一句"用户想去北京旅游",然后用这句总结替换掉长篇大论。
- 自定义策略: 自己写过滤规则,想怎么留就怎么留。
💻 代码实战:用 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();
🛠️ 五、 访问与自定义记忆的四条密道
有时候你的业务需要主动去查阅或者修改当前的记忆状态,官方提供了四个切入点:
- Before Model: 在把记录喂给大模型之前拦截。上面的 Hook 代码用的就是这招,非常适合做修剪和屏蔽。
- After Model: 在大模型刚回答完之后拦截。适合用来做记忆总结(比如刚聊完一局,马上写个小结存起来)。
- 工具(Tools): 把读写状态的能力封装成一把"工具"塞给大模型,让它自己决定什么时候去查改记忆。
- 提示(Prompt): 不改历史记录,而是将部分重要的老记忆提取出来,偷偷塞进当前对话的 System Prompt(系统提示词)里,强行唤醒大模型的关注。
🎯 终极秒记口诀
智能聊天需记性,短期记忆来搞定;
Saver 挂载轻松起,生产换成 Redis 存;
聊得太多脑子懵,修剪删除加总结;
Hook 拦截去瘦身,脑容量小也不怕!