概述

记忆是 Agent 区别于「无状态 LLM 调用」的核心能力之一:它让 Agent 在多轮对话、长任务和跨会话中保持上下文一致。记忆系统设计是 Agent 中台的重要模块,决定了 Agent 的智能上限与状态管理质量。

1. 记忆的分层

借鉴人类认知架构,Agent 的记忆可分为多层:

记忆类型 生命周期 存储介质 用途
工作记忆 本次会话 上下文窗口 当前任务状态、中间结果
短期记忆 会话内 上下文 + 摘要 多轮对话保持连贯
长期记忆 跨会话 向量库/关系库 用户画像、历史偏好、事实知识
程序性记忆 长期 配置/代码 技能、工作流、标准操作流程

2. 工作记忆与上下文窗口

LLM 的上下文窗口是有限的,且随内容增长成本与延迟上升。工作记忆设计围绕「窗口管理」展开:

  • 滚动窗口:保留最近 N 轮完整对话
  • 摘要压缩:对早期对话周期性生成摘要,替换原文
  • 关键信息抽取:提取结构化字段(用户ID、目标、约束)持久化
  • Token 预算分配:为系统提示、记忆、工具描述、对话预留不同配额
1
2
3
4
5
预算示例(128k 上下文):
├── 系统提示 + 工具定义 15k
├── 长期记忆(检索结果) 10k
├── 工作记忆(进行中会话) 60k
└── 输出预算 + 预留 40k

3. 长期记忆的实现

长期记忆通常依赖向量数据库存储语义化记忆,并配合内容寻址与时效管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 伪代码:记忆写入
def write_memory(memory_store, content, metadata):
embedding = embed(content) # 语义向量化
memory_store.upsert(
id=uuid(),
vector=embedding,
payload={
"content": content,
"timestamp": now(),
"user_id": metadata["user_id"],
"importance": score(content), # 重要性评分
"type": metadata["type"]
},
namespace=f"user:{metadata['user_id']}"
)

记忆的关键属性设计

  • 相关性检索:按问题语义检索最相关的历史记忆,而非逐条读取
  • 重要性衰减:高频/重要记忆权重更高,久远记忆逐步淡出
  • 冲突消解:新信息与旧记忆矛盾时,保留带时间戳的版本
  • 写入策略:对话结束后异步提炼要点写入,避免实时高频写入

4. 记忆的提取与组织

不是所有对话都值得记住。需要「记忆蒸馏」流程:

环节 说明
识别 判断哪些信息有长期价值(偏好、事实、进展)
结构化 提炼为「实体-属性-关系」或因果片段
压缩 去除冗余,控制存入体积
写入 带 metadata 持久化,供后续检索

5. 会话隔离与多租户

生产环境中必须控制记忆的可见范围,防止信息越界:

  • 命名空间隔离:按 用户/会话/Agent/租户 分层隔离
  • 权限继承:记忆的可读范围与对应数据源的权限一致
  • 生命周期:设置 TTL,过期自动清理 / 脱敏
  • 可删除:遵循数据合规,支持用户删除自己的记忆

6. 记忆失真的缓解

记忆检索引入不确定性的常见问题与对策:

  • 检索不到:相关记忆未写入或 embedding 召回不佳 → 补充写入与多路召回
  • 过度记忆:把噪音当事实 → 重要性评分 + 置信度门槛
  • 记忆冲突:旧记忆与新事实矛盾 → 时间戳版本 + 显式覆盖
  • 隐私泄漏:检索出越权信息 → 严格的权限过滤

7. 设计小结

  1. 分层存储:短期用摘要、长期用向量,别把一切塞进上下文
  2. 记忆要「蒸馏」:只存有长期价值的结构化信息
  3. 强隔离:按用户/租户命名空间隔离,支持删除与 TTL
  4. 可观测:记录每次记忆的读/写,便于定位状态漂移
  5. 从简开始:先用会话级摘要,业务需要再引入向量长期记忆