Skip to content

Agent 长短期记忆系统基础

Agent 记忆系统解决的是一个核心问题:如何让 Agent 不只是完成一次对话,而是能在当前会话中保持上下文,并在跨会话场景下持续理解用户。

短期记忆负责当前会话里的连续理解,长期记忆负责跨会话保存有价值的信息。两者不是独立模块,而是在每次请求中一起参与 Prompt 组装、结果生成和记忆写回。

为什么需要记忆

没有记忆的 Agent 每次对话都像从零开始,无法持续理解用户身份、稳定偏好、项目背景和历史任务。

短期记忆

保存当前 Session 内的消息历史,让 Agent 能理解前后文,但会受到上下文窗口限制。

长期记忆

将有价值的信息写入外部存储,支持跨会话复用,例如用户画像、项目背景和历史经验。

调度中枢

Memory Manager 决定本次请求读取哪些记忆,以及响应后哪些内容值得写回。

没有记忆时,Agent 很容易在第二轮、第三轮对话里重新询问用户已经说过的信息。例如用户已经说过“我是后端工程师”,下一轮让它推荐学习路线时,它仍然可能反问“你的技术背景是什么?”

有记忆后,Agent 可以把用户身份、技术背景、稳定偏好和项目上下文带入后续对话,输出会更连续,也更个性化。

上下文窗口再大,也不是无限缓冲区。长对话如果不管理,会遇到三个问题:

Token 上限

当历史消息持续累积,总长度超过窗口上限时,旧内容会被截断或无法继续注入。

成本增长

每次调用都要携带历史上下文,对话越长,输入 Token 越多,成本也越高。

响应变慢

输入越长,模型处理时间越长,首 Token 延迟也会明显上升。

因此,Agent 不能只把所有历史消息塞进 Prompt,而要引入存储、截断、压缩和长期检索机制。

人类记忆 日常理解 Agent 对应实现 技术载体
工作记忆 桌面便利贴,只放当前任务要用的信息 短期记忆 当前会话 messages[]
常驻备忘录 每次开工前都会先看的一页关键信息 长期记忆全文注入 MEMORY.md / System Prompt
搜索历史聊天 记不清原话,只记得大概主题,于是找回相关聊天片段 长期记忆 RAG 向量数据库 Top-K 相似度检索
通讯录备注 给联系人记录长期偏好和注意事项 用户画像 USER.md / KV Store
会后纪要 把长对话整理成关键结论和待办 会话压缩摘要 compressed_context

这个类比能帮助理解:短期记忆解决“眼前正在做什么”,长期记忆解决“过去沉淀了什么”。

Agent 的记忆系统可以分成两层:执行层和记忆层。

执行层

负责用户输入、LLM 推理、工具调用和流式输出。LangChain、LangGraph 等框架主要工作在这一层。

记忆层

负责消息历史存储、跨会话持久化、记忆检索与注入、压缩与遗忘策略。

执行层决定 Agent 如何思考和行动;记忆层决定 Agent 如何保留、筛选和取回信息。

不同框架对记忆系统的设计哲学不同,没有绝对优劣,主要看透明度、自动化程度和业务场景。

路线 代表 存储方式 检索方式 适合场景
文件系统记忆 OpenClaw Markdown + JSON 文件 全文注入,超阈值后可降级检索 个人 Agent、教学项目、本地优先
多后端存储 LangChain / LangGraph Checkpointer、Store、SQL、向量库 状态机 + store.search 原型到生产,生态优先
多源召回 LlamaIndex ChatMemoryBuffer、VectorMemory 滑动窗口 + 向量检索 + 多路召回 企业知识管理、RAG 密集场景
分层自管理 Letta / MemGPT Core blocks、Archival、Recall LLM 自主读写工具 研究型自主 Agent、超长对话
维度 短期记忆 长期记忆
作用域 当前对话 / 单次 Session 跨 Session 持久保留
容量 受 Context Window 限制 理论上可扩展到外部存储
持久性 默认不持久,主要随上下文存在 写入文件、KV 存储或向量库
查询方式 直接读取消息列表 语义检索或 KV 精确查询
核心挑战 窗口溢出,需要截断和压缩 写入时机和检索精度

短期记忆的核心链路是:存储 -> 截断 -> 压缩

  1. 存储:把每轮对话追加到 messages[],同时记录 session_id、元数据和 Token 统计。

  2. 截断:当消息超过阈值时,按 FIFO 策略只保留最近消息,控制本轮注入模型的上下文长度。

  3. 压缩:如果旧消息里有重要信息,不直接丢弃,而是先由 LLM 提炼成摘要,再注入到 system 层。

一个完整的会话对象通常包含四类字段:

session-memory.json
{
"session_id": "sess_abc123",
"messages": [
{ "role": "user", "content": "你好,我叫李明,是一名后端工程师" },
{ "role": "assistant", "content": "你好李明,有什么可以帮你?" }
],
"compressed_context": "用户是后端工程师,当前关注 LangChain Agent 与 FastAPI 集成,倾向 Python 技术栈。",
"metadata": {
"created_at": "2026-08-03T10:00:00",
"last_active": "2026-08-03T10:30:00",
"token_count": 4200,
"compress_count": 1
}
}
字段 作用
session_id 标识一次完整会话,用于跨请求追踪上下文
messages[] 保存当前会话的对话轮次
compressed_context 保存被压缩后的历史摘要
metadata 记录时间、Token 消耗、压缩次数等运营信息

只做截断会带来一个问题:较早的消息虽然可能还在原始会话记录里,但不会再进入本轮 Prompt,模型当下读不到。这样一来,用户身份、重要决策、技术细节和未完成任务等关键信息就无法参与后续推理。压缩摘要就是为了解决这个问题。

截断的目标是控制上下文长度。最简单的策略是保留最近 N 条消息,让更早的历史消息不再注入本轮 Prompt。

它实现简单,但会损失信息。适合处理低价值、临时性、已经完成的历史内容。

一个好的压缩 Prompt,至少要保留四类信息:

用户身份

用户角色、背景、偏好,用来保持个性化理解。

重要决策

已经达成的结论和方向,避免后续对话推翻共识。

技术细节

技术选型、参数、约束条件,保证后续建议一致。

未完成任务

已提出但尚未处理的需求,避免遗忘承诺和待办事项。

长期记忆要解决的是跨会话问题:哪些信息值得永久保存?保存到哪里?下次如何取回来?

把小体积、高频访问、非常关键的信息直接注入 Prompt。

适合用户偏好、稳定身份、少量核心背景。优点是简单直接,缺点是体积变大后 Token 成本高。

维度 KV Store 向量库
查询方式 精确 key 查找 语义相似度检索
适合数据 JSON 用户画像、偏好、配置 历史对话片段、经验、非结构化文本
优点 快、简单、结构稳定 能处理模糊表达和相似问题
局限 key 必须明确 召回结果需要排序和过滤
  1. 结构化数据:如果是 JSON、键值对、用户偏好,优先使用 KV Store。

  2. 小体积核心事实:如果内容少于大约 2000 tokens,并且高频使用,可以直接注入 Prompt。

  3. 大体积自然语言:如果是大量历史片段、文档或经验,使用向量库 + RAG 按需召回。

长期记忆不是“什么都写”。写入前要判断这条信息未来是否真的有价值。

事实性

是否描述相对客观、可验证的信息。例如用户是 Python 后端工程师。

稳定性

是否不会很快过期。例如用户偏好简洁代码风格。

跨会话复用性

是否对未来新会话仍有参考价值。例如用户正在推进 FastAPI 项目。

内容 是否写入 原因
用户是 Python 后端工程师,5 年经验 写入 事实稳定,后续可复用
用户偏好简洁代码风格 写入 可长期影响输出风格
帮我把这段代码改优雅一点 跳过 只是当前任务请求
用户今天心情不好,说话较短 谨慎 可能临时有效,不一定长期稳定
方式 做法 适合情况
Direct 全文注入 MEMORY.md 或核心记忆全部放进 Prompt 记忆体积小、使用频率高、内容高度关键
RAG 语义检索 根据当前问题检索 Top-K 相关记忆,只注入相关片段 记忆体积大、内容分散、需要控制 Token 成本

可以用一个简单阈值理解:当长期记忆内容很小,Direct 最简单;当记忆体积变大,RAG 更能控制 Token 成本。

长期记忆如果只追加不整理,会越来越乱。sleep-time 机制指的是在 Agent 空闲时启动后台整理任务,对记忆做去重、合并和提炼。

  1. 日常写入:每次对话后,把符合条件的事实、偏好和项目背景追加到长期记忆。

  2. 空闲触发:会话结束或系统空闲时,后台启动记忆整理任务。

  3. 去重合并:把重复、相近、碎片化的信息合并成更清晰的表达。

  4. 整理完成:保留高质量、稳定、可复用的记忆,减少噪音堆积。

Memory Manager 是记忆系统的调度中枢。每次请求进入 Agent,它至少要做两次判断:先判断读取哪些记忆,再判断结果写入哪里。

输入来源

用户消息、工具调用结果、Agent 内部状态,都会成为记忆管理的输入。

读取决策

判断本次请求需要读取短期消息、压缩摘要、Direct 记忆还是 RAG 检索结果。

写入决策

判断响应后哪些信息要写回短期记忆、长期记忆、KV 存储或向量库。

一条用户消息进入 Agent 后,短期记忆和长期记忆会共同参与完整链路。

  1. 用户输入:用户消息进入 Agent,触发记忆处理链路。

  2. 短期记忆读取:读取当前会话的 messages[]compressed_context

  3. 长期记忆注入:根据策略选择 Direct 注入或 RAG 检索。

  4. Prompt 组装:把系统规则、短期上下文、长期记忆和当前问题组合成完整 Prompt。

  5. LLM 推理:模型基于完整上下文生成响应。

  6. 短期写回:把用户消息和助手响应追加到当前会话。

  7. 价值判断:评估新信息是否具备事实性、稳定性和跨会话复用性。

  8. 长期写入:把有价值的信息写入 MEMORY.md、KV Store 或向量库。