学习笔记:详述 Agent 记忆的四层分类、存储与检索策略、上下文窗口管理、知识图谱整合以及工程落地要点

目录


概述

Agent 记忆是决定 Agent 能否从"单次问答工具"进化为"真正助手"的关键分水岭。没有记忆的 Agent,每次对话都是全新开始,多步任务中无法知道自己上一步做了什么、当前处于哪个阶段。本章从认知科学中借用了记忆分类框架,结合实际工程实践,系统梳理 Agent 记忆的设计思路与落地方法。

为什么记忆对 Agent 至关重要

  • 没有记忆 → 每次对话都是全新开始,之前达成的约定全部消失。
  • 缺乏短期记忆 → Agent 无法感知"当前状态",多步任务寸步难行。
  • 缺乏长期记忆 → 用户每次都要重复交代偏好、背景、历史决策,体验割裂。
  • 缺乏实体记忆 → Agent 记不住关键事实(用户名字、项目配置、截止日期)。

记忆让 Agent 具备"连续性"——从一个输入-输出的无状态函数,变成一个能随时间积累的有状态系统。

四层记忆分类速览

在这里插入图片描述

感知记忆(Sensory Memory)

  • 定义:当前调用中接收的原始输入——用户消息、上传的截图、传入的文档等。
  • 生命周期:单次调用,处理完即消失。
  • 类比:人刚听到的一句话,没主动记就几秒后忘记。
  • 工程意义:是 Agent 接收外部信息的"入口层",通常由 API 网关或消息队列直接处理,不做持久化。

短期记忆(Short-term Memory)

  • 定义:context window 中的 messages 列表——用户说了什么、模型输出了什么、工具调用返回了什么。
  • 生命周期:一次任务期间存在,任务结束(对话关闭)即清空。
  • 类比:工作台,桌上摆着正在处理的东西。
  • 限制:有 token 上限(工作台大小有限),超出后需用滑动窗口、摘要压缩等策略管理。

长期记忆(Long-term Memory)

  • 定义:跨任务保留的信息,存储在外部数据库中。
  • 生命周期:持久化,任务间共享。
  • 类比:档案室,需要主动去翻。

长期记忆又可细分为三种子类型:

情节记忆(Episodic Memory)

存储具体的事件经历。例如"上周二用户让我写了一个 Python 爬虫,中间遇到了反爬问题,最后用 Selenium 解决了"。

价值:遇到类似新任务时,可检索历史相似经历作为参考。记录的是"当时发生了什么、怎么解决的"。

语义记忆(Semantic Memory)

存储从多次经历中提炼的通用知识和规律。例如多次反爬经历后沉淀出"当目标网站有 JavaScript 动态渲染时,requests 库抓不到内容,应优先考虑 Selenium 或 Playwright"。

特点:信息密度更高,检索更容易命中。存的是结论而非过程。

程序记忆(Procedural Memory)

存储操作流程 / SOP。例如"部署 Flask 应用的标准步骤:创建虚拟环境 → 安装依赖 → 配置 gunicorn → 设置 nginx → 启动服务"。

价值:处理重复性任务时直接调出 SOP 执行,无需每次从头推理。

实体记忆(Entity Memory)

  • 定义:从对话中提取的关键实体和事实,存为结构化字段。例如"用户偏好 Python"、“客户预算是 5 万”、“项目截止日是 3 月底”。
  • 类比:医生的病历卡——不是存录音,而是结构化记录。
  • 特点:信息密度高、查询快、不受原始表述方式影响。通常用关系数据库或 KV 存储,支持精确查询。

四层记忆横向对比

类型 载体 容量 生命周期 访问方式
感知记忆 当次输入 极小 单次调用 即时访问
短期记忆 context window 受 token 限制 一次任务 直接读取
长期记忆 向量/关系数据库 无限 持久化 语义检索
实体记忆 结构化存储 无限 持久化 精确查询

记忆系统的三个核心设计问题

存什么?

判断标准:“这条信息,下次任务开始时如果知道,会让 Agent 做得更好吗?”

值得存储的三类内容

  1. 用户偏好和习惯——语言风格、技术栈偏好、工作习惯。
  2. 任务执行中产生的关键结论和决策——如"调研发现竞品 A 的定价策略是按用量收费"。
  3. 外部知识——产品文档、FAQ、历史案例。

不值得存储的

  • 中间推理过程(除非用于调试溯源)
  • 工具返回的原始数据(日志太啰嗦)
  • 闲聊内容

怎么存?

根据信息类型选择合适的存储介质:

信息类型 推荐存储 检索方式
非结构化文本/知识 向量数据库 语义相似度检索
结构化偏好/状态 关系数据库 / KV 精确查询
操作流程/SOP 向量数据库 或 代码模板 语义检索 + 模板匹配
实体关系网络 知识图谱(三元组) 图遍历/多跳推理

主流做法是混合存储:结构化的偏好字段用关系数据库精确查,非结构化的知识和历史用向量数据库语义检索,实体间关系用知识图谱做关联推理。

什么时候取出来用?

两种策略,实践中通常结合使用:

主动检索(Proactive Retrieval)
  • 时机:任务开始前。
  • 做法:用当前任务的描述检索相关记忆,将结果注入 system prompt 作为背景知识。
  • 效果:Agent 带着历史记忆进入任务,用户无需重复交代背景。
被动/按需检索(Reactive Retrieval)
  • 时机:推理过程中。
  • 做法:将"查记忆"封装成一个 Tool,Agent 自己决定何时调用。
  • 特点:更灵活,但依赖模型判断能力。

最佳实践:session 开始时做一次主动检索加载偏好和背景;执行过程中遇到需要专业知识或历史数据时,按需检索。

Context Window 管理策略

短期记忆的"工作台"不够大时,有三种主流策略:

滑动窗口(Sliding Window)

只保留最近 N 轮对话,更早的直接丢弃。

  • 优点:实现简单,内存开销固定。
  • 缺点:早期重要信息可能丢失——如第一轮说的"所有代码用 TypeScript"到第十轮被滑出。
  • 适用:对话轮次少、历史依赖弱的任务。

摘要压缩(Summarization)

历史接近上限时,用 LLM 将早期对话压缩成一段摘要,替换原始历史。

原始对话:[User: ...] [Assistant: ...] [Tool: ...] × 50 轮
          ↓ LLM 摘要
替换为:  [Summary: 用户要求开发一个 REST API,已确定使用 Flask + PostgreSQL,前三轮完成了用户认证模块]
  • 效果:token 占用从几千降到几百。
  • 代价:压缩会丢失细节,且需要额外 LLM 调用。

分层卸载(Tiered Offloading)

将不常用但重要的信息"卸载"到长期记忆。中间结果如果当前不需要、但后面可能用到,先存入向量数据库并从 context window 移除,后续需要时再检索回来。

三种策略可组合使用滑动窗口兜底保证 context 不会爆炸,摘要压缩定期做"压缩整理",关键信息卸载到长期记忆做持久化。

记忆整合:从碎片到知识

零散存储的记忆需要经过三个关键环节才能成为高质量的知识资产:

去重(Deduplication)

语义相近的多条记忆合并为更完整的版本。例如三条关于"用户喜欢简洁代码"的不同表述合并为一条。

冲突消解(Conflict Resolution)

两条记忆矛盾时(如"用户偏好 Python"与"最近转用 Go"),保留时间更新的,标记旧的过期。时间戳在此非常关键——每条记忆都应携带创建时间和最近更新时间。

抽象提炼(Abstraction / Distillation)

将情节记忆转化为语义记忆——把多次具体经历"蒸馏"出通用规律。可以通过 LLM 自动完成:把一批相关情节记忆喂给 LLM,让它总结出通用知识,将结果作为新的语义记忆存入。

输入:[多条情节记忆]
  "2026-03-01: 用户部署时忘了开虚拟环境,依赖冲突"
  "2026-03-15: 用户部署时 requirements.txt 漏了版本号"
  "2026-04-02: 用户部署时 Python 版本不匹配"
      ↓ LLM 提炼
输出:[语义记忆]
  "用户部署流程的常见问题集中在环境隔离和依赖管理,建议后续部署前自动执行环境检查脚本"

整合节奏

  • 每次任务结束后:做轻量级去重和更新。
  • 每天/每周:做深度整理和提炼,批量转化情节记忆为语义记忆。
  • 部分框架(如 Mem0)已内置后台异步整合逻辑。

知识图谱:让记忆之间产生关联

向量数据库的局限

向量数据库是"一条一条"存取,记忆间无显式关联。两条语义相似度不高的记忆——例如"用户 A 是公司 B 的 CTO"和"公司 B 的主营业务是云计算"——无法被向量检索同时命中。

三元组结构

知识图谱用"实体 → 关系 → 实体"的三元组结构存储:

[用户 A] --担任 CTO--> [公司 B]
[公司 B] --主营业务--> [云计算]

多跳推理

从"用户 A"出发,沿"担任 CTO"找到"公司 B",再沿"主营业务"找到"云计算"——两跳拿到答案。这是纯向量检索做不到的。

实践做法

向量数据库 ← 模糊语义检索("和这个任务相关的历史有哪些?")
知识图谱   ← 精确关系推理("这个实体的关联信息是什么?")

对话中用 LLM 自动提取实体和关系存入知识图谱;检索时先用向量检索拿候选记忆,再用知识图谱补充关联信息,合并后注入 context。

完整闭环:"读 → 用 → 写"三阶段

一个成熟的记忆模块按以下三阶段循环运转:

第一阶段:任务开始前,先"读"记忆

1. 从实体记忆取出用户结构化偏好(语言风格、技术栈、过往决策)
2. 用任务描述去长期记忆做语义检索,取回最相关的历史背景
3. 两部分信息拼进 system prompt 开头

第二阶段:任务执行中,持续"用"记忆

1. 短期记忆全程工作——每次消息、输出、工具返回结果追加进 messages
2. 需要特定专业知识时,Agent 通过 Tool 发起临时长期记忆检索
3. 检索结果注入当前步骤 context,用完即走(不污染短期记忆)

第三阶段:任务结束后,主动"写"记忆

1. 新偏好 → 更新实体记忆对应字段
2. 有价值结论 → 写入长期记忆,embedding 后存入向量数据库
3. 必要时触发记忆整合流程(去重/冲突消解/抽象提炼)
4. 短期记忆清空,等待下一个任务
// Memory 模块的伪代码示意
public class AgentMemory {
    private EntityMemory entityMem;    // 实体记忆(结构化)
    private LongTermMemory longTermMem; // 长期记忆(向量数据库)
    private ShortTermMemory shortTermMem; // 短期记忆(context window)
    
    public void onSessionStart(String taskDescription) {
        // 阶段1:读
        List<Entity> prefs = entityMem.queryByUser(currentUserId);
        List<Memory> related = longTermMem.semanticSearch(taskDescription);
        injectToSystemPrompt(prefs, related);
    }
    
    public void onToolResult(String stepContext) {
        // 阶段2:按需检索
        List<Memory> knowledge = longTermMem.semanticSearch(stepContext);
        injectToCurrentContext(knowledge);
    }
    
    public void onSessionEnd(SessionSummary summary) {
        // 阶段3:写
        entityMem.update(summary.extractedEntities());
        longTermMem.store(summary.keyConclusions());
        longTermMem.triggerConsolidation(); // 触发后台整合
        shortTermMem.clear();
    }
}

主流框架与开源方案

Mem0

  • 定位:通用记忆层服务(Memory-as-a-Service)。
  • 核心思路:将记忆管理做成独立服务层,调用 memory.add()memory.search(),底层 embedding、去重、冲突消解自动完成。
  • 特色:支持按 user_id 做记忆隔离;同时支持向量存储和图存储。
  • 状态:GitHub 约 5 万星,已获 Series A 融资,商业化成熟度高。

Letta(前身 MemGPT)

  • 定位:有状态 Agent 框架(Stateful Agents)。
  • 核心思路:灵感来自操作系统内存管理,分三个层级:
    • Core Memory:始终留在 context window 的核心信息(用户画像、当前任务目标)。
    • Recall Memory:最近对话历史,按时间顺序存储。
    • Archival Memory:长期归档知识,容量无限,检索需主动发起。
  • 亮点:Agent 自己通过工具调用管理三层记忆;引入"休眠计算"(sleep-time compute)做后台整合。

Graphiti(Zep 开源组件)

  • 定位:时序知识图谱记忆。
  • 核心思路:给每条记忆标注有效时间窗口,通过时序知识图谱管理记忆生命周期,自动识别过时记忆。
  • 特色:支持双时间有效性(valid_at / invalid_at);基于 Neo4j。
  • 性能:在 DMR 基准上达 94.8% 准确率,P95 延迟约 300ms。

框架对比

框架 存储核心 记忆类型 整合机制 适用场景
Mem0 向量+图 长期/实体 自动去重+冲突消解 通用记忆层,接入已有 Agent
Letta 三层分级 核心/回顾/归档 休眠整合 复杂自主 Agent
Graphiti 时序知识图谱 实体+关系 时间窗口过期识别 强依赖时序和关系的场景

工程化建议

  • 慢写快读:记忆系统在写入端做 heavy lifting(抽取、embedding、实体识别、去重),读端只做轻量检索。写入延迟可以接受几百毫秒,读取延迟应控制在 100ms 内。
  • 混合检索策略:单一向量检索不够。推荐向量语义 + BM25 关键词 + 图关系 + 时间排序的多路召回,合并后重排序。
  • 记忆安全:注意跨用户记忆隔离、注入攻击防范(攻击者可能通过对话污染记忆库)、敏感信息脱敏。
  • 异步整合:去重和抽象提炼不应阻塞主流程,应采用后台任务/消息队列异步执行。
  • 可观测性:记录每条记忆的来源(哪个 session、哪轮对话)、写入时间、更新时间、检索命中率,便于排查和调优。
  • 渐进式引入:不必一开始就搭建完整记忆系统。可从简单的实体记忆(KV 存储用户偏好)起步,逐步加入向量长期记忆,最后引入知识图谱和自动整合。

参考资料

Logo

更多推荐