AgentScope Java新手村系列 第17篇 长期记忆系统
第十七章 长期记忆系统:从 LongTermMemory 到 workspace/MEMORY.md 中间件驱动
17.1 1.x LongTermMemory 旧 API 回顾
import io.agentscope.core.memory.LongTermMemory;import io.agentscope.core.memory.LongTermMemoryBase;import io.agentscope.core.memory.Mem0LongTermMemory;import io.agentscope.core.ReActAgent;public class Chapter17_LegacyLongTerm { public static void main(String[] args) { LongTermMemory memory = new Mem0LongTermMemory("https://api.mem0.ai",System.getenv("MEM0_API_KEY"));ReActAgent agent = ReActAgent.builder().name("assistant").sysPrompt("你是一个长期记忆助理。").model(model()).longTermMemory(memory)// 1.x.build();}}
2.0 仍可编译:ReActAgent.longTermMemory(...) 在 RC2 中标记为 @Deprecated(forRemoval = true),编译通过但会告警。

17.2 2.0 推荐的两层记忆结构
workspace 下两份文件,按不同"时间粒度"组织:
workspace/├── MEMORY.md# 长期稳定的事实笔记└── memory/├── 2026-06-05.md# 当天事件流├── 2026-06-06.md└── 2026-06-07.md
17.2.1 MEMORY.md
跨会话、跨天都会用到的"稳定信息"——
# MEMORY.md## 用户偏好- 常驻城市:杭州- 时区:UTC 8- 语言:中文## 长期目标- 2026 年内学完 Rust
17.2.2 memory/YYYY-MM-DD.md
按天追加的"事件流"——
# 2026-06-07## 14:32- 用户问"今天杭州天气",回答:22~28℃,局部多云,建议带伞## 15:01- 用户问"我常驻哪里",agent 从 MEMORY.md 知道"杭州",回答一致
17.3 两个核心中间件
io.agentscope.core.middleware 提供两个跟记忆直接相关的中间件:
| 中间件 | 何时触发 | 副作用 |
|---|---|---|
CompactionMiddleware | 上下文 token 超过阈值 | 早期消息压成摘要写进 MEMORY.md |
MemoryFlushMiddleware | 每轮 call 结束 | 把"该记的"刷到当日 memory/YYYY-MM-DD.md |
17.3.1 CompactionMiddleware
CompactionMiddleware 由 HarnessAgent 在 build() 时根据 MemoryConfig 自动挂载,业务方通过 .memory() 配置即可:
HarnessAgent agent = HarnessAgent.builder()....memory(MemoryConfig.builder().compactionEnabled(true)// 超过 token 阈值自动压缩.build()).build();
CompactionMiddleware 工作流程:
MEMORY.md 的"近期摘要"小节 旧消息从 AgentState 移除 17.3.2 MemoryFlushMiddleware
import io.agentscope.harness.agent.middleware.MemoryFlushMiddleware;HarnessAgent agent = HarnessAgent.builder()....memory(MemoryConfig.builder().build()) // 默认开启每轮结束后冲刷记忆.build();
MemoryFlushMiddleware 由 HarnessAgent 根据 MemoryConfig 自动挂载,业务方无需手动构造。工作流程:
memory/2026-06-07.md 没有 → 跳过,不写 17.3.3 完整配置
HarnessAgent agent = HarnessAgent.builder().name("assistant").sysPrompt("...").model(model()).workspace(Path.of("./workspace")).memory(MemoryConfig.builder().build()) // 默认开启 MemoryFlushMiddleware.build(); // CompactionMiddleware 按 CompactionConfig 挂载
17.4 主 agent 自动读 / 写 MEMORY.md
主 agent 在每轮推理时会自动读 MEMORY.md 顶部几行作为"已知背景"。如果你想"agent 决定更新 MEMORY.md"——给它 @Tool:
@Tool(name = "update_long_term_memory", description = "更新长期记忆")// 注册为 agent 可调工具public String updateMemory(@ToolParam(name = "section") String section, // 比如 "用户偏好"@ToolParam(name = "content") String content) { // 比如 "默认中文回答"Path memFile = Path.of("./workspace/MEMORY.md");// 记忆文件固定路径String existing = memFile.toFile().exists()? Files.readString(memFile) // 已有记忆 → 追加: "# MEMORY.md";// 新文件 → 创建String updated = existing "## " section "- " content "";Files.writeString(memFile, updated);// 写回文件return "memory updated";}
把工具通过 Toolkit 注册进 agent,LLM 看到用户说"以后请默认中文回答"会自己调这个工具写进 MEMORY.md,下次对话时立刻生效。
17.5 完整可运行示例
这个例子在演示什么?
public class Chapter17_MemoryStack { public static void main(String[] args) { DashScopeChatModel model = DashScopeChatModel.builder().apiKey(System.getenv("DASHSCOPE_API_KEY")).modelName("qwen-plus").build();// 1. 手工更新记忆的工具(agent 主动决策"记住这个")Toolkit toolkit = new Toolkit();toolkit.registerTool(new UpdateMemoryTool());// 2. agent:三层记忆机制一起跑HarnessAgent agent = HarnessAgent.builder().name("assistant").sysPrompt("你是一个有长期记忆的助理。用户告诉你的事如果需要长期记住,调用 update_long_term_memory 工具写下来。").model(model).workspace(Path.of("./workspace")).toolkit(toolkit).compaction(CompactionConfig.builder().build())// 上下文太长时自动压缩.memory(MemoryConfig.builder().build())// 默认 flush=每轮结束自动冲刷.build();// 3. 多轮对话(同一个 session,演示跨轮记忆)RuntimeContext ctx = RuntimeContext.builder().sessionId("user-9527-2026-06-07").userId("9527").build();// Round 1:agent 记住用户基本信息agent.call(List.of(new UserMessage("user", "我叫小李,住在杭州。")), ctx).block();// Round 2:agent 应该能从记忆里调出信息agent.call(List.of(new UserMessage("user", "我叫什么?住在哪?")), ctx).block();// Round 3:agent 主动调 update_long_term_memory 写偏好agent.call(List.of(new UserMessage("user", "以后请用中文回答。")), ctx).block();}}
跑完你会看到:
workspace/MEMORY.md — CompactionMiddleware 写的摘要 UpdateMemoryTool 写的用户偏好(@ToolParam 缺了这里会是 null) workspace/memory/ — 不一定生成。MemoryFlushMiddleware 的写入取决于 LLM 判断"是否值得记"以及异步回调是否执行完毕 Round 2 时 agent 能从上下文记忆里知道"小李 / 杭州" Round 3 时 agent 主动调工具把"中文回答"偏好写进 MEMORY.md 17.6 最小迁移清单(1.x LongTermMemory → 2.0 文件记忆)
| 1.x 用法 | 2.0 等价 |
|---|---|
LongTermMemory.retrieve(query) | 业务方手写 @Tool 调自家向量库;或 subagent 用 grep_files |
LongTermMemory.record(messages) | MemoryFlushMiddleware update_long_term_memory 工具 |
LongTermMemoryBase 子类 | 业务方自己实现 @Tool |
agent.longTermMemory(memory) | workspace/MEMORY.md memory/*.md 中间件 |
17.7 本章小结
1.xLongTermMemory 在 2.0 中被标记为弃用,未来会移除。 2.0 用 MEMORY.md memory/YYYY-MM-DD.md 两层文件做长期记忆。 CompactionMiddleware 自动压缩 MemoryFlushMiddleware 自动写入。 业务方可以手写 @Tool 让 agent 主动更新 MEMORY.md。
-
07.07
梦之形手机版燃烧巨人攻略 梦之形手机版燃烧巨人打法详解与通关技巧
-
07.07
逆战未来失落游轮地图详解 逆战未来失落游轮地图玩法与特色全解析
-
07.07
逆战未来火神炎帝逆战未来火神炎帝角色强度与实战表现分析
-
07.07
梦之形手机版白日梦攻略:梦之形手机版白日梦全流程通关与高难度关卡打法详解
-
07.07
小猫咪大城市挖洞教程:城市环境中猫咪挖洞行为的科学解析与实用指南
-
07.07
宝可梦冠军手游最强阵容搭配与实战配置指南宝可梦冠军手游阵容推荐
-
-
下载
- 《神剑伏魔录》(神剑风云)游戏音乐合集
- 其他游戏|7.73 MB
- 一款非常好玩的武侠闯关游戏
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- 《生化危机:浣熊市行动》免安装中文硬盘版下载
- 单机|6310 MB
- 一款以动作射击为主题的游戏
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏