跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaAIjava

Spring AI Alibaba 短期记忆与长期记忆实现原理

Spring AI Alibaba 框架通过 MemorySaver 和 MemoryStore 组件分别实现短期记忆与长期记忆。短期记忆基于内存存储会话状态,支持线程隔离;长期记忆支持结构化数据存储及跨会话共享。文章结合源码解析了检查点保存恢复机制及命名空间管理方式,并提供了 Agent 调用示例。

JavaCoder发布于 2026/3/27更新于 2026/10/19105 浏览

记忆系统概述

在 AI Agent 应用中,记忆系统是维持对话连贯性和个性化体验的核心能力:

  • 短期记忆(Short-term Memory):保存当前会话的对话历史,类似人类的'工作记忆'
  • 长期记忆(Long-term Memory):持久化存储关键信息,类似人类的'长时记忆'

Spring AI Alibaba 通过 MemorySaver 和 MemoryStore 两个组件实现了这两种记忆机制。

短期记忆实现原理

核心组件:MemorySaver

MemorySaver 是短期记忆的实现类,负责保存和恢复会话状态(Checkpoint)。其核心特点:

  • 存储结构:ConcurrentHashMap<String, Map<String, Checkpoint>>
  • 隔离维度:通过 threadId 隔离不同会话
  • 生命周期:应用重启后数据丢失(内存存储)
实现机制
保存检查点

当 Agent 执行完一轮对话后,会调用 MemorySaver.save() 保存状态:

// MemorySaver.java
public class MemorySaver implements CheckpointSaver {
    private final ConcurrentHashMap<String, Map<String, Checkpoint>> storage = new ConcurrentHashMap<>();

    @Override
    public void save(Checkpoint checkpoint, RunnableConfig config) {
        String threadId = config.threadId().orElseThrow();
        String checkpointId = checkpoint.getId();
        // 按 threadId 分组存储
        storage.computeIfAbsent(threadId, k -> new ConcurrentHashMap<>()).put(checkpointId, checkpoint);
    }
}

关键要点:

  • 每个 threadId 对应一个独立的 Map
  • Checkpoint 包含完整的对话历史(messages)和状态(state)
恢复检查点

当用户继续对话时,Agent 会加载上一次的 Checkpoint:

@Override
public Optional<Checkpoint> load(RunnableConfig config) {
    String threadId = config.threadId().orElseThrow();
    Map<String, Checkpoint> threadCheckpoints = storage.get(threadId);
    if (threadCheckpoints == null || threadCheckpoints.isEmpty()) {
        return Optional.empty();
    }
    // 返回最新的 checkpoint
    return threadCheckpoints.values().stream().max(Comparator.comparing(Checkpoint::getCreatedAt));
}
使用示例

来自测试文件 ShortTermMemoryTest.java:82-116:

@Test
void testBasicShortTermMemory() throws Exception {
    // 1. 创建带 MemorySaver 的 Agent
    ReactAgent agent = ReactAgent.builder()
            .name("memory_agent")
            .model(chatModel)
            .saver(new MemorySaver()) // ← 启用短期记忆
            .build();
    // 2. 创建带 threadId 的配置
    RunnableConfig config = RunnableConfig.builder()
            .threadId("conversation_1") // ← 会话隔离标识
            .build();
    // 3. 第一轮对话:告诉名字
    agent.invoke("你好!我叫张三。", config);
    // 4. 第二轮对话:询问名字(依赖短期记忆)
    Optional<OverAllState> result = agent.invoke("我叫什么名字?", config);
    AssistantMessage response = extractLastMessage(result);
    // Agent 能记住之前的对话
    assertTrue(response.getText().contains("张三"));
}

执行流程:

  1. 第一轮对话后,MemorySaver 保存 Checkpoint(包含用户消息 + 回复)
  2. 第二轮对话时,Agent 加载 Checkpoint 恢复对话历史
  3. 将新消息追加到历史中,发送给 LLM
  4. LLM 基于完整历史回答问题

长期记忆实现原理

核心组件:MemoryStore

MemoryStore 用于存储结构化的长期信息,支持命名空间(namespace)组织数据:

  • 存储结构:namespace + key + value(类似 K-V 数据库)
  • 持久化:支持扩展到 Redis/MongoDB(当前版本为内存实现)
  • 跨会话:不依赖 threadId,可在不同会话间共享
数据模型
// StoreItem.java
public class StoreItem {
    private List<String> namespace; // 命名空间:如 ["user_profiles"]
    private String key;             // 键:如 "user_001"
    private Map<String, Object> value; // 值:如 {"name": "张三", "age": 28}

    public static StoreItem of(List<String> namespace, String key, Map<String, Object> value) {
        return new StoreItem(namespace, key, value);
    }
}
实现机制
存储数据
// MemoryStore.java
public class MemoryStore implements Store {
    private final Map<String, Map<String, StoreItem>> storage = new ConcurrentHashMap<>();

    @Override
    public void putItem(StoreItem item) {
        String namespaceKey = String.join("/", item.getNamespace());
        storage.computeIfAbsent(namespaceKey, k -> new ConcurrentHashMap<>()).put(item.getKey(), item);
    }
}
检索数据
@Override
public Optional<StoreItem> getItem(List<String> namespace, String key) {
    String namespaceKey = String.join("/", namespace);
    Map<String, StoreItem> namespaceMap = storage.get(namespaceKey);
    if (namespaceMap == null) {
        return Optional.empty();
    }
    return Optional.ofNullable(namespaceMap.get(key));
}
使用示例

来自测试文件 LongTermMemoryTest.java:88-188:

@Test
void testLongTermMemoryWithInterceptor() throws Exception {
    // 1. 创建记忆拦截器
    ModelHook memoryInterceptor = new ModelHook() {
        @Override
        public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, RunnableConfig config) {
            // 从配置获取用户 ID
            String userId = (String) config.metadata("user_id").get();
            // 从长期记忆加载用户资料
            Optional<StoreItem> profile = memoryStore.getItem(List.of("user_profiles"), userId);
            if (profile.isPresent()) {
                Map<String, Object> data = profile.get().getValue();
                // 注入到系统消息
                String context = String.format("用户信息:姓名=%s, 年龄=%s, 邮箱=%s",
                        data.get("name"), data.get("age"), data.get("email"));
                // ... 后续逻辑
            }
            return CompletableFuture.completedFuture(state);
        }
    };
}

目录

  1. 记忆系统概述
  2. 短期记忆实现原理
  3. 核心组件:MemorySaver
  4. 实现机制
  5. 保存检查点
  6. 恢复检查点
  7. 使用示例
  8. 长期记忆实现原理
  9. 核心组件:MemoryStore
  10. 数据模型
  11. 实现机制
  12. 存储数据
  13. 检索数据
  14. 使用示例

更多推荐文章

查看全部
  • Spring Boot 核心原理与面试高频考点解析
  • 本地 Git 服务器部署指南:从零搭建私有代码仓库
  • F5 刷新后,浏览器前端究竟发生了什么?
  • Amazon SageMaker 部署 AIGC 应用:从训练到 Web 集成的实战
  • Scrapy 爬取新闻网站数据:安装与配置入门
  • TRAE、Qoder、Cursor 与 GitHub Copilot 四款 AI 编程工具深度对比
  • Spring Bean 作用域、生命周期与自动装配源码解析
  • VRM4U 插件指南:在 Unreal Engine 5 中高效处理 VRM 模型
  • Flutter × HarmonyOS 6 实战落地:跨平台工具应用开发复盘
  • 大模型基座训练的挑战与难点
  • 快速部署 Qwen3-VL-4B-Instruct 模型:基于 WebUI 镜像实现推理
  • C++ 多线程编程基础:线程管理与同步机制
  • UZH RPG 组 AC-MPC:微分 MPC 赋能强化学习实现高速无人机竞速
  • 66 个可直接访问的机器人项目合集,涵盖科研教育工业医疗
  • Windows 环境下编译与运行 llama.cpp 实战指南
  • Java 时间类(中):JDK8 全新时间 API 详解
  • Llama-Factory 跨平台微调指南:Windows、MacOS 与 Linux 环境配置
  • Spring Web MVC 入门:从概念到实践
  • 基于 Web Unlocker 和 n8n 的自动化资讯采集与推送系统
  • DeepSeek 各版本说明与优缺点分析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online