当前位置: 首页
AI教程
AgentScope Java新手村第17期 长期记忆系统

AgentScope Java新手村第17期 长期记忆系统

热心网友 时间:2026-07-06
转载

第十七章 长期记忆系统:从 LongTermMemory 到 workspace/MEMORY.md 中间件驱动

谈到 AgentScope 的长期记忆机制,2.0 版本堪称一次彻底重构。1.x 中的 LongTermMemory 接口虽然功能完整,但随着架构快速迭代,新型文件存储配合中间件设计让记忆管理变得更加轻量和透明。我们先回顾旧版 API 的模样,再展开 2.0 的新思路。

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),编译通过但会弹出告警。也就是说,接口尚存,但团队已经明确告知:迟早会删除,尽早迁移更省心。

【AgentScope Ja va新手村系列】(17)长期记忆系统

17.2 2.0 推荐的两层记忆结构

新版本把记忆拆分为两个层级,按“时间粒度”划分清晰。来看 workspace 下的文件布局:

workspace/
├── MEMORY.md              # 长期稳定的事实笔记
└── memory/
    ├── 2026-06-05.md      # 当天事件流
    ├── 2026-06-06.md
    └── 2026-06-07.md

简单来说:MEMORY.md 存放跨会话、跨天都能复用的稳定信息,例如用户偏好、长期目标;而 memory/YYYY-MM-DD.md 则按天追加事件流,记录当天发生的内容。

17.2.1 MEMORY.md

举个例子,MEMORY.md 的内容大概像这样:

# MEMORY.md

## 用户偏好
- 常驻城市:杭州
- 时区:UTC 8
- 语言:中文

## 长期目标
- 2026 年内学完 Rust

这些信息不会随单次对话结束而消失,agent 每次启动都会自动读取。

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

这个中间件由 HarnessAgentbuild() 时根据 MemoryConfig 自动挂载,业务方只需通过 .memory() 配置是否开启即可:

HarnessAgent agent = HarnessAgent.builder()
    .name("assistant")
    .sysPrompt("...")
    .model(model())
    .memory(
        MemoryConfig.builder()
            .compactionEnabled(true)  // 超过 token 阈值自动压缩
            .build()
    )
    .build();

CompactionMiddleware 的工作流程非常清晰:

  • 监听每轮 call 结束
  • 检查当前上下文 token 数
  • 超过阈值 → 将“较旧的消息”交给 LLM 总结成几行
  • 摘要写入 MEMORY.md 的“近期摘要”小节
  • 旧消息从 AgentState 中移除

这样一来,上下文窗口始终能维持在一个合理长度,而重要信息并未丢失——只是被提炼后存入文件。

17.3.2 MemoryFlushMiddleware

另一个中间件负责在每轮结束后,把需要记录的内容刷到当天的日志文件中:

import io.agentscope.harness.agent.middleware.MemoryFlushMiddleware;

HarnessAgent agent = HarnessAgent.builder()
    .name("assistant")
    .sysPrompt("...")
    .model(model())
    .memory(
        MemoryConfig.builder()
            .build()   // 默认开启每轮结束后冲刷记忆
    )
    .build();

同样由 HarnessAgent 根据 MemoryConfig 自动挂载,业务方无需手动构造。它的工作流程是:

  • 监听每轮 call 结束
  • 让 LLM 判断“本轮是否有值得长期记忆的内容”(事实、用户偏好变化等)
  • 如果有 → 追加到当日 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 顶部几行,作为“已知背景”。如果你想让它主动更新 MEMORY.md,只需提供一个 @Tool

@Tool(name = "update_long_term_memory", description = "更新长期记忆")
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 + "\n## " + section + "\n- " + content + "\n";
    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())
            .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 下看到:

  • 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.x 的 LongTermMemory 在 2.0 中已被标记为弃用,未来会移除。
  • 2.0 采用 MEMORY.md + memory/YYYY-MM-DD.md 两层文件作为长期记忆。
  • CompactionMiddleware 自动压缩,MemoryFlushMiddleware 自动写入。
  • 业务方可以手写 @Tool 让 agent 主动更新 MEMORY.md。

可以说,这套全新的记忆系统让开发者能够更精细地控制哪些信息应该长久保留,哪些可以当天消化。迁移虽然需要一定工作量,但换来的是更透明、更灵活的管理方式——值得一试。

来源:https://developer.aliyun.com/article/1745340

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
阿里云Qoder CN灵码AI助手免费版及credits计费指南

阿里云Qoder CN灵码AI助手免费版及credits计费指南

阿里云QoderCN(原通义灵码)是一款AI智能编码助手,提供IDE插件、独立IDE等形态,覆盖编码及日常办公场景。产品分个人社区版(免费)、个人专业版、企业标准版和企业VPC版,采用Credits计费模式,支持多种AI模型。

时间:2026-07-06 16:30
基于大模型的城市文旅知识图谱构建与内容分发

基于大模型的城市文旅知识图谱构建与内容分发

大模型构建城市知识图谱时优先采信权威信源。贵港西江传媒联合《度假旅游》杂志,通过本地采编、期刊发布、阿里云多平台分发模式,产出产业文旅等结构化内容,提升AI知识库收录权重,为城市品牌长效传播提供可复制路径。

时间:2026-07-06 16:30
贵州文旅AIGEO内容运营本地媒体落地实践

贵州文旅AIGEO内容运营本地媒体落地实践

针对贵州文旅行业在阿里云平台的内容运营痛点,总结合规发文规则,包括弱化营销、避免引流信息与极限词。以《度假旅游杂志》在贵阳设立本地化运营站点为例,为黔域文旅商家产出合规原创内容,提升AI平台收录权重。同时指出商家常踩的审核红线,强调以干货分享获取自然流量。

时间:2026-07-06 16:29
阿里内部禁用Claude Code OpenCode成替代方案

阿里内部禁用Claude Code OpenCode成替代方案

ClaudeCode对国内用户定向封禁,网传阿里内部已全面禁用。OpenCode作为开源替代,支持接入多种AI模型,通过CCSwitch或手动配置可无缝迁移原有MCP与AgentSkill,规避账号风险。

时间:2026-07-06 16:29
年实测Homebrew安装配置国内源多种安装方式一篇搞定

年实测Homebrew安装配置国内源多种安装方式一篇搞定

Homebrew是macOS上流行的包管理工具,提供pkg安装包、脚本安装和Git克隆等多种安装方式。国内用户推荐使用镜像脚本安装并配置中科大或清华大学镜像源以加速下载。常用命令包括brewinstall安装工具、brewinstall--cask安装图形应用、brewupdate更新及brewdoctor诊断环境。

时间:2026-07-06 16:29
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜