返回文章列表
Agent记忆系统Context EngineeringRAG隐私

Agent 记忆系统 101:短期、长期与外部记忆的工程分层

“给 Agent 加记忆”最容易踩坑:什么都写、什么都召回,结果越用越脏、越聊越笨。本文用工程视角拆解记忆系统的三层分工(短期/长期/外部),给出写入阈值、召回排序、衰减规则与权限隔离的可落地方案,并提供可直接复用的记忆 schema 与评测指标。

2026年3月4日
Synthly 团队
预计阅读 16 分钟
Agent 记忆系统的分层结构:短期、长期与外部记忆的协作关系示意图

📷 Photo by Eva Bronzini via Pexels

记忆不是“更长上下文”,而是“可控的信息复用”

长上下文模型越来越强,但现实仍会遇到:

  • 会话跨天跨周,信息分散
  • 任务需要引用历史偏好与约束
  • 事实来自外部系统(工单、订单、知识库)

如果你把这些都塞进 prompt,只会得到三种后果:

  1. 成本飙升(token)
  2. 幻觉增加(信息噪声多)
  3. 权限失控(敏感信息混入)

所以记忆系统的目标是:在可控的范围内复用信息


一、三层记忆的工程分工

把记忆分成三层,可以避免“什么都存”的失控。

1)短期记忆(Working Memory)

  • 生命周期:当前任务/当前会话
  • 内容:中间变量、计划步骤、工具回执摘要、临时偏好
  • 目标:支持多步骤执行与一致性

典型实现:

  • 会话状态(state machine state)
  • 结构化缓存(例如 currentTask.plan, toolReceipts

短期记忆最重要的一点:可丢弃

2)长期记忆(Long-term Memory)

  • 生命周期:跨会话、跨任务
  • 内容:稳定偏好、长期约束、经验证的事实
  • 风险:一旦写脏,会长期污染

长期记忆必须满足:

  • 可追溯(为什么写入、来自哪里)
  • 可更新(版本/时间戳)
  • 可删除(用户可控、合规可控)

3)外部记忆(External Memory / Source-of-Truth)

  • 生命周期:由外部系统决定
  • 内容:文档、数据库、工单系统、知识库
  • 特点:可引用、可审计、可权限控制

外部记忆适合回答“事实类问题”,而长期记忆更适合“偏好类信息”。


二、写入策略:什么时候写、写什么、写到哪

长期记忆的失败通常不是检索算法,而是写入策略。

1)写入阈值:不是什么都配得上进长期记忆

建议用三个条件控制写入:

  • 稳定性:信息是否在多个回合被确认(或来自外部来源)
  • 可复用性:未来任务是否可能需要(偏好/约束/常用实体)
  • 风险等级:敏感信息默认不写,或加密/隔离写入

一个简单规则:

  • 用户偏好(语言、格式、时区)→ 可写
  • 临时目标(“这次帮我写个周报”)→ 不写
  • 外部事实(订单金额、合同条款)→ 不写入长期记忆,应该存外部系统并引用

2)写入内容要结构化:别把一段话当记忆

建议定义一个可治理的 schema:

{
  "memoryId": "m_...",
  "scope": "user",
  "type": "preference",
  "key": "report.format",
  "value": "markdown",
  "confidence": 0.9,
  "source": {
    "kind": "user_confirmed",
    "eventId": "e_...",
    "timestamp": "2026-03-04"
  },
  "ttlDays": 365,
  "pii": false
}

结构化的好处:

  • 冲突可检测(同一个 key 多个 value)
  • 衰减可执行(ttlDays)
  • 权限可控制(scope)

3)写到哪:长期记忆与外部记忆别混

建议分库:

  • memory_store:偏好、约束、常用实体(轻量、可治理)
  • source_store:文档、数据表、工单(可审计、可权限)

把事实塞进长期记忆,会让系统无法解释来源。


三、召回策略:最近优先 vs 语义相似 vs 任务相关

“怎么取”比“取多少”更重要。

1)召回是一道排序题(Ranking),不是一道检索题

你通常会同时有三种信号:

  • 最近性(Recency):最近发生的更可能相关
  • 语义相似(Semantic):向量相似度
  • 任务相关(Task Fit):与当前目标/工具/领域的匹配

推荐用加权融合:

$$score = w_r \cdot recency + w_s \cdot similarity + w_t \cdot taskFit$$

并且对不同类型记忆用不同权重。

2)误召回治理:宁缺毋滥

记忆系统最致命的问题是:召回了“不相关但很像”的信息,模型会强行把它编进答案。

工程策略:

  • 设定最小相似度阈值(低于阈值不注入)
  • 对高风险类型(例如权限/付款)禁用记忆注入
  • 对注入内容做“引用标记”,便于调试

3)注入格式:让模型知道“这不是事实来源”

建议把长期记忆注入成“偏好/约束”,而不是“事实陈述”。例如:

  • ✅ “用户偏好:输出格式为 Markdown”
  • ❌ “用户的订单金额是 3999 元”(事实应来自外部系统)

四、衰减与清理:记忆越用越脏的根因

长期记忆要像缓存一样有生命周期。

1)TTL 与版本化

  • 偏好类:TTL 可长(90-365 天)
  • 实体类:TTL 中等(30-90 天)
  • 敏感类:默认不写或短 TTL

同一 key 的更新要保留 updatedAtconfidence,避免旧信息长期占位。

2)冲突合并:同一个 key 多个 value 怎么办

例:timezone 同时出现 Asia/ShanghaiAmerica/LA

策略:

  • 最近一次明确确认 > 历史
  • 置信度更高 > 置信度更低
  • 无法确认 → 追问用户,不要强行覆盖

五、权限与合规:哪些信息绝不能被跨会话复用

记忆系统天然带来合规风险:

  • 跨用户泄漏
  • 跨租户泄漏
  • 超范围使用(用户没授权却复用)

最小防线:

  • scope 必须明确:user / workspace / tenant
  • 默认 user 隔离,不允许跨用户
  • 对敏感字段(PII、凭证、财务)标记并默认拒绝注入

如果你计划做 B2B 多租户,建议把权限隔离放在设计第一位。


六、评测指标:别只看“更像人”

1)召回层(Retrieval)

  • 命中率:需要的记忆是否被召回
  • 误召回率:不相关记忆注入比例
  • 新鲜度:召回内容是否过期

2)生成层(Generation)

  • 正确率:任务完成质量
  • 引用覆盖率:事实是否来自可追溯来源(外部记忆)
  • 追问率:缺信息时是否能正确追问

3)系统层(System)

  • token 成本变化
  • 端到端延迟变化
  • “越聊越笨”回归:长会话下的质量退化曲线

七、可直接复用的 Checklist

  • 分层:短期/长期/外部分工明确,不混用
  • 写入:有阈值、有结构化 schema、有来源与置信度
  • 召回:融合排序 + 阈值 + 高风险禁用
  • 注入:偏好/约束格式,不把事实写成“记忆”
  • 清理:TTL、版本化、冲突合并、可删除
  • 权限:scope 隔离,敏感信息默认不注入
  • 评测:命中/误召回/成本/退化曲线全链路指标

常见问题

我应该先做 RAG 还是先做长期记忆?

如果你的场景依赖外部事实(产品文档、订单、工单),优先做 RAG(外部记忆)更可控:可引用、可审计、可权限。长期记忆更适合偏好与约束,且治理成本更高。

记忆注入越多越好吗?

不是。注入越多,噪声越大,幻觉越强。记忆系统的目标是“高质量、低噪声、可验证”的信息复用。

怎么判断“越聊越笨”是记忆导致的?

把记忆注入做成可开关的实验变量(A/B),并记录每次注入的记忆条目列表与排序分数。若关闭记忆后质量显著回升,且误召回率高,基本可以锁定是记忆污染。

想看更多工程化文章见 /articles,也可以在 /apps/new 体验 Agent 能力。