用户和 AI 助手协作了一周,确认了代码规范、技术偏好、项目背景。第八天打开对话,AI 一脸茫然------之前讨论的所有偏好和规范全部消失,又回到了"通用助手"模式。这不是假设场景,这是 2024 年之前绝大多数 Agent 产品的真实状态。Agent 从"能用"到"好用",卡住的不是单次推理能力,而是记忆。 本文是记忆系统系列的开篇理论篇,先搞清楚"记忆到底是什么",建立完整的认知框架,再谈工程实现。

一、为什么 Agent 需要记忆?
在谈记忆之前,先回到一个基本事实:LLM 本质是一个无状态函数。每次 API 调用都是独立的,模型不会自动记住上一轮说了什么。所谓"对话上下文",是应用层把历史消息拼成 messages 数组重新传给模型------这不是记忆,这是"每次考试都把草稿纸重新抄一遍"。
用一个 Python 类比来说明:
bash
# LLM 本质上是一个纯函数 ------ 无状态
def llm_call(messages: list[dict]) -> str:
"""
每次调用都是独立的。
模型不记得上一次调用传了什么,
所有"上下文"都是通过 messages 参数传入的。
这不是记忆,是"每次重传草稿纸"。
"""
response = openai.chat.completions.create(
model="gpt-4",
messages=messages # 所有历史都在这里
)
return response.choices[0].message.content
# 两次调用之间,模型没有任何记忆
result1 = llm_call([{"role": "user", "content": "我叫张三"}])
result2 = llm_call([{"role": "user", "content": "我叫什么?"}])
# result2 不会知道 result1 里说过"张三"
当 Agent 需要处理真实场景的复杂任务时,这种无状态特性带来了四个核心问题:
1. 跨会话连续性:昨天确认的代码规范、项目约定,今天新会话里全忘了。用户不得不重复说明同样的规则------这不是"智能助手",这是"金鱼助手"。
2. 个性化服务:记住用户偏好、技术栈、工作习惯。一个知道用户偏好 Java + Spring Boot 的 Agent,和一个每次都推荐 Python 方案的 Agent,使用体验完全不同。
3. 任务状态管理:长周期任务中维护进度和中间结论。一个需要三天完成的迁移任务,每天要能接着前一天的进度继续,而不是从零开始。
4. 知识积累:从历史交互中学习,避免重复踩坑。上次部署踩过的坑、用户纠正过的错误,下次不应该再犯。
以上四个维度是业界对 Agent 记忆需求的共识性总结,腾讯云、掘金社区等多篇实践文章均有类似归纳。
腾讯云数据库团队在 TencentDB Agent Memory 的实践总结中明确指出:"Agent 从'能用'走向'好用',卡住的不是单次推理,而是记忆"。这是他们在生产级 Agent 记忆系统建设中的核心观察,精准地指出了当前 Agent 工程的瓶颈所在。
本篇的定位很明确:先把记忆的认知模型和工程映射搞清楚,建立完整的分层思维。框架选型、代码实现,留到下一篇。
二、记忆分类体系------从认知科学到工程映射
人类的记忆系统经过了几十年的认知科学研究。Agent 的记忆设计不需要从零发明------站在认知科学的肩膀上,把人类记忆的分类映射到工程实现,是最可靠的路径。
2.1 五层记忆模型
下面的表格把认知科学的记忆分类和 Agent 工程实现做了一一映射:
| 认知概念 | Agent 对应 | 存储位置 | 特点 | 生命周期 |
|---|---|---|---|---|
| 工作记忆 | Context Window | LLM 上下文(不落库) | 容量约 7±2 组块 → 对应 token 窗口限制 | 秒级 |
| 短期记忆 | Session Buffer | Redis / 内存(TTL) | 会话级,结束后清除 | 分钟~小时 |
| 情景记忆 | Interaction Log | 向量库(pgvector / Milvus) | 带时间戳的具体交互事件 | 天~月 |
| 语义记忆 | Knowledge Base | 结构化存储 + 知识图谱 | 从多段经历蒸馏的抽象知识 | 月~永久 |
| 程序记忆 | Skills / Procedures | 技能库 / 固定流程源 | "怎么做"的操作记忆 | 近永久 |
逐层展开。
工作记忆(Working Memory)------ Context Window
LLM 的 Context Window 就是工作记忆。认知科学经典研究表明(Miller, 1956; Baddeley, 2000),人类工作记忆容量约 7±2 个组块 ,持续 20-30 秒。对应到 LLM,就是 token 窗口限制------128K tokens 看似很大,但塞满系统提示、工具定义、历史消息、检索结果之后,真正留给"当前任务"的空间并不富裕。
bash
Context Window 的组成(典型分配):
┌─────────────────────────────────────────┐
│ System Prompt + 工具定义 ~2000 tokens │
│ 用户画像 + 偏好注入 ~500 tokens │
│ 检索到的相关记忆 ~1000 tokens │
│ 最近 N 轮对话历史 ~3000 tokens │
│ 当前任务上下文 ~2000 tokens │
│ ─────────────────────────────────────── │
│ 总计 ~8500 tokens │
│ 剩余可用(128K 窗口) ~119K tokens │
└─────────────────────────────────────────┘
看似富余,但长任务中很容易逼近上限。
核心认知:工作记忆不是"存"出来的,是"管"出来的。上下文管理------裁剪、摘要、选择性注入------的本质就是管理"什么进入工作记忆"。MemGPT(后更名 Letta)把这个思想推到了极致:把 Context Window 类比成虚拟内存,Agent 自己决定什么进上下文、什么"换出"到外部存储。
短期记忆(Short-term Memory)------ Session Buffer
Session 级缓冲,对话结束后清除。类比人类打电话时临时记住一个号码------拨完就忘。工程上用 Redis List + TTL 实现,典型场景是当前会话内最近 N 轮对话的滑动窗口。
bash
# 短期记忆的典型实现:Redis + TTL
import redis
class SessionBuffer:
"""会话级短期记忆 ------ 对话结束后自动清除"""
def __init__(self, session_id: str, ttl_seconds: int = 3600):
self.redis = redis.Redis()
self.key = f"session:{session_id}:messages"
self.ttl = ttl_seconds
def add(self, role: str, content: str):
self.redis.rpush(self.key, json.dumps({"role": role, "content": content}))
self.redis.expire(self.key, self.ttl) # TTL 自动过期
def get_recent(self, n: int = 10) -> list[dict]:
"""获取最近 N 轮对话"""
messages = self.redis.lrange(self.key, -n, -1)
return [json.loads(m) for m in messages]
# 会话结束后,TTL 到期自动清除 ------ 不需要手动管理
它解决的是"这次对话里不要断片",而不是"下次还记得"。
情景记忆(Episodic Memory)------ Interaction Log
带时间戳的具体交互事件。认知科学定义情景记忆有三个要素:
- What:发生了什么(具体内容)
- When:何时发生的(时间戳)
- Where / With whom:在什么场景下、和谁(上下文)
对应到 Agent,就是"2026-08-10,用户要求把部署流程从 Docker Compose 迁移到 K8s,最终选定了 ArgoCD 方案"这样一条有具体时间、具体内容的记录。
工程上用向量数据库存储(pgvector、Milvus),检索时结合语义相似度 + 时间衰减 + 重要性评分。Generative Agents 论文中的检索公式是经典范式:
bash
Score = α × semantic_similarity + β × recency + γ × importance
参考:Park, J.S., O'Brien, J.C., Cai, C.J., Morris, M.R., Liang, P. & Bernstein, M.S. (2023). Generative Agents: Interactive Simulacra of Human Behavior. arXiv:2304.03442
bash
# 情景记忆的数据模型
class EpisodicMemory:
"""带时间戳的交互事件记忆"""
id: str
user_id: str
content: str # 事件描述
embedding: list[float] # 向量化表示
timestamp: datetime # 发生时间
importance: float # 重要性评分(0-1)
metadata: dict # 附加上下文(session_id, tool_used 等)
def compute_score(self, query_embedding: list[float],
now: datetime,
alpha: float = 1.0,
beta: float = 1.0,
gamma: float = 1.0) -> float:
"""Generative Agents 经典三维评分"""
sim = cosine_similarity(self.embedding, query_embedding)
age_hours = (now - self.timestamp).total_seconds() / 3600
recency = 0.99 ** age_hours # 时间衰减
return alpha * sim + beta * recency + gamma * self.importance
语义记忆(Semantic Memory)------ Knowledge Base
从多段经历中蒸馏出的抽象知识。比如"用户偏好 Java + Spring Boot"这条知识,是从多次对话中归纳出来的------它和具体某次对话脱钩了,变成了独立的事实。
工程上用结构化存储实现:PostgreSQL 中的 rules / facts / status 表,或者知识图谱的三元组 (user, prefers, Java)。
bash
# 语义记忆的数据模型 ------ 三种类型
class SemanticMemory:
"""从多段经历蒸馏出的抽象知识"""
# 1. Rules ------ 用户设定的规则
# "代码必须用 Java 17+,禁止使用 Lombok"
rules: list[Rule]
# 2. Facts ------ 从对话中提取的事实
# "用户偏好 Java + Spring Boot + PostgreSQL"
facts: list[Fact]
# 3. Status ------ 当前状态
# "正在进行的项目:Dream-SaaS,进度 70%"
status: list[Status]
# 知识图谱表示(三元组)
# (user_123, prefers_language, Java)
# (user_123, prefers_framework, Spring_Boot)
# (user_123, working_on, Dream-SaaS)
Mem0 的 add/search API 本质上就是在管理语义记忆------提取事实、去重、更新。
程序记忆(Procedural Memory)------ Skills / Procedures
"怎么做"的操作流程。类比人类的肌肉记忆------骑自行车不需要想每一步。Agent 的程序记忆就是 Skills、固定流程、操作模板。
bash
程序记忆的例子:
├── deploy_k8s_skill.md # K8s 部署标准流程
├── code_review_checklist.md # 代码审查清单
├── incident_response.md # 故障应急响应流程
└── onboarding_workflow.md # 新人入职引导流程
特点:
- 不需要每次交互重新学习
- 变化频率极低(几个月才更新一次)
- 通常以文件形式存在,版本控制
2.2 两层关键动态关系
五层记忆不是各自独立的孤岛,它们之间存在关键的动态关系。最重要的是两个:
情景 → 语义的蒸馏:多次对话中用户反复提到"我用 Java"、"项目用 Spring Boot"、"数据库是 PostgreSQL",系统从这些具体的情景记忆中归纳出规则------"偏好语言=Java,框架=Spring Boot,数据库=PostgreSQL"。这就是从具体经历到抽象知识的蒸馏,是记忆系统的核心价值之一。
bash
蒸馏过程示意:
情景记忆(具体) 语义记忆(抽象)
┌─────────────────────┐
│ 8/1: "我用 Java" │──┐
├─────────────────────┤ │ ┌──────────────────────────┐
│ 8/3: "项目 Spring" │──┼───>│ rule: prefers_java=true │
├─────────────────────┤ │ │ rule: framework=Spring │
│ 8/5: "DB 用 PG" │──┘ │ rule: database=PostgreSQL│
└─────────────────────┘ └──────────────────────────┘
从 3 条具体对话 → 蒸馏出 3 条抽象规则
语义 → 情景的引导:已有的语义知识会影响新情景的解读和处理。知道用户是 Java 开发者后,他问"怎么做依赖注入"时 Agent 会优先给 Spring 的方案,而不是一本正经地介绍 Dagger 或 Guice。语义记忆充当了"先验知识"的角色,让 Agent 在面对新交互时不用从零开始。
2.3 关键洞察
一句话总结:不同记忆类型的边界不是"存储方式不同",而是"抽象程度和生命周期不同"。工作记忆活几秒,短期记忆活一个会话,情景记忆活几周到几个月,语义记忆可以永久存在,程序记忆几乎不变。抽象程度从低到高:具体对话 → 交互事件 → 抽象规则 → 操作流程。
理解了这个维度,记忆系统的设计就有了清晰的坐标轴。
三、记忆生命周期------五阶段闭环
记忆不是"存进去就完事"。一个完整的记忆系统有五个阶段,形成闭环:
bash
编码(Encoding) → 存储(Storage) → 检索(Retrieval) → 巩固(Consolidation) → 遗忘(Forgetting)
↑ |
└──────────────────────── 反馈循环 ────────────────────────────────────────┘
3.1 编码:不是所有信息都值得记住
编码是将原始输入转化为可存储的记忆表示的过程。人类大脑每秒接收约 1100 万 bit 的感觉输入,但工作记忆只能处理约 50 bit/s------绝大部分信息在编码阶段就被过滤掉了。
Agent 也一样。Mem0 的做法是:用 LLM 从对话中提取事实性内容 → 向量化 → 搜索是否已存在同类记忆 → 决定新增、更新还是忽略。这个过程本身就是有选择性的提取,而不是"对话全文存下来"。
bash
# Mem0 风格的编码过程(教学代码,实际项目用 Java + Spring AI)
def encode_memory(conversation: list[dict], user_id: str) -> list[Memory]:
"""
编码过程:从对话中提取可存储的记忆
不是全量保存,是有选择性的提取
"""
# Step 1: LLM 提取事实
extraction_prompt = f"""
从以下对话中提取用户的事实性信息:
- 偏好、习惯
- 项目信息
- 技术栈
- 明确的要求和规则
对话:{conversation}
输出 JSON 格式:[{{"fact": "...", "category": "...", "confidence": 0.0-1.0}}]
"""
facts = llm_call(extraction_prompt)
# Step 2: 去重检查 ------ 是否已存在同类记忆
memories = []
for fact in facts:
existing = search_memory(user_id, fact["fact"])
if existing and existing.similarity > 0.9:
# 已存在高度相似的记忆,考虑更新而非新增
update_memory(existing, fact)
else:
# 新事实,编码为新记忆
memories.append(Memory(
user_id=user_id,
content=fact["fact"],
category=fact["category"],
confidence=fact["confidence"],
embedding=embed(fact["fact"]),
timestamp=datetime.now()
))
return memories
设计要点:编码质量决定了整个记忆系统的信噪比。如果什么都在编码阶段放过来,后面的检索会被噪声淹没。工程上通常用 LLM 做结构化抽取------提取 user_id、fact、category、confidence 等字段,而不是存原始文本。
3.2 存储:分层存放,各司其职
不同类型的记忆存在不同的地方,这是工程实现的基本分工:
| 记忆类型 | 存储方式 | 特点 | 访问模式 |
|---|---|---|---|
| 工作记忆 | Prompt(临时拼装) | 请求结束即消失 | 每次请求必访问 |
| 短期记忆 | Redis List + TTL | 自动过期,无需手动清理 | 会话内高频读写 |
| 情景记忆 | 向量库(pgvector / Milvus) | 语义检索,支持相似度查询 | 按需检索 |
| 语义记忆 | PostgreSQL + 知识图谱 | 结构化存储,支持精确查询 | 按需检索 + 直接注入 |
| 程序记忆 | Skills 源文件 / 配置 | 静态存储,版本控制 | 任务触发时加载 |
关键原则:存储选型跟着访问模式走。需要语义搜索的用向量库,需要精确查询的用关系型数据库,需要快速读写的用 Redis。不存在一种存储解决所有问题的方案。
3.3 检索:三维评分是核心
检索是记忆系统中最影响用户体验的环节。Generative Agents 论文提出了经典的三维检索公式:
bash
Score = α × semantic_similarity + β × recency + γ × importance
参考:Park, J.S., O'Brien, J.C., Cai, C.J., Morris, M.R., Liang, P. & Bernstein, M.S. (2023). Generative Agents: Interactive Simulacra of Human Behavior. arXiv:2304.03442
不同框架对三个维度的权重分配差异很大:
| 框架 | α (语义相似度) | β (时间衰减) | γ (重要性) |
|---|---|---|---|
| Generative Agents(Stanford) | 1.0 | 1.0 | 1.0 |
| CrewAI | 0.5 | 0.3 | 0.2 |
| Mem0 V3 | semantic + BM25 + entity | --- | --- |
CrewAI 权重取自其 v1.15 版本 LongTermMemory 模块默认配置,Generative Agents 权重取自论文原文。数据来源于各框架源码及社区文档。
这里有一个容易被忽视的问题------冷启动困境:新用户只有少量记录时,所有记忆的语义相似度都很低。这时候不注入记忆比注入不相关的记忆更好。工程上需要设置相似度阈值,低于阈值的记忆宁可不检索出来,避免引入噪声。
bash
def retrieve_memories(query: str, user_id: str, threshold: float = 0.3) -> list[Memory]:
"""带阈值的记忆检索"""
query_embedding = embed(query)
candidates = vector_db.search(user_id=user_id, embedding=query_embedding, top_k=20)
# 三维评分
scored = []
for mem in candidates:
score = mem.compute_score(query_embedding, datetime.now())
if score >= threshold: # 低于阈值的不注入
scored.append((mem, score))
# 按分数排序,取 Top-K
scored.sort(key=lambda x: x[1], reverse=True)
return [mem for mem, score in scored[:5]]
3.4 巩固:从短期到长期的蒸馏
人类在睡眠时,大脑会把白天的重要经历从海马体转移到大脑皮层,完成从短期到长期的巩固。Agent 也有类似的机制------但实现方式不同。
以腾讯云 TencentDB Agent Memory 的分层蒸馏方案为例,其核心思路是将记忆按抽象程度分为四层:
bash
分层蒸馏模型(腾讯云 TencentDB Agent Memory):
L0 原始对话 ────────> 原始对话的全量备份,不做任何加工
│ 作为后续蒸馏的原料
▼ 提取(LLM 抽取事实)
L1 原子记忆 ────────> 从对话中自动抽取独立的事实片段
│ "用户偏好 Java"、"项目用 PostgreSQL"
│ 每条都是可独立理解的原子信息
▼ 归纳(模式识别)
L2 场景归纳 ────────> 多条原子记忆按任务维度自动聚合
│ 形成更高一级的模式识别
│ "用户倾向于使用 Java 生态的全套方案"
▼ 综合(画像生成)
L3 用户画像 ────────> 综合所有层级信息
持续蒸馏出稳定的用户画像
这是最高层级的抽象
每一层蒸馏都是信息压缩------用 LLM 从低层级的多条记录中提取、归纳出高层级的抽象知识。这比简单的"短期记忆到期搬到长期"要有效得多。
OpenAI 也推出了类似的 Dreaming 机制------后台自动从多轮对话中合成记忆,本质上也是巩固过程的自动化。巩固做得好,长期记忆里是高质量的蒸馏知识;做不好,就是一堆噪声。
3.5 遗忘:不是缺陷,是必要功能
没有遗忘机制的 Agent 会遇到三个严重问题:
- Token 成本攀升:记忆越来越多,每次检索和注入的 token 消耗持续增长
- 过期信息干扰:三个月前的偏好大概率已经变了,但它还在影响检索结果
- 噪声积累:大量低重要性记忆稀释了高价值记忆的召回率
工程上常用的三种遗忘策略:
| 策略 | 实现方式 | 适用场景 |
|---|---|---|
| 时间衰减 | R = e^(-t/S),记忆强度 S 越大衰减越慢 | 偏好类、事实类记忆 |
| 重要性阈值 | importance < threshold 时标记为可清理 | 低价值交互记录 |
| 主动清理 | 用户显式要求"忘掉这个"时立即删除 | 隐私敏感信息 |
以上三种遗忘策略综合自 Generative Agents 论文(Park et al., 2023)和腾讯云 Agent Memory 工程实践。
Ebbinghaus 遗忘曲线的工程映射公式:
bash
R = e^(-t/S)
R = 记忆保留率(0-1)
t = 距上次访问的时间
S = 记忆强度(由 importance 和访问频率决定)
高 importance → S 大 → 衰减慢
低 importance → S 小 → 衰减快
多次访问 → S 增大 → 衰减变慢(类似人类的"复习效应")
该公式在 Generative Agents 论文中被直接采用作为记忆衰减的工程实现。
bash
def compute_retention(importance: float, access_count: int,
hours_since_access: float) -> float:
"""Ebbinghaus 遗忘曲线的工程实现"""
# 记忆强度 = 基础强度 × (1 + 访问次数加成)
S = importance * (1 + 0.1 * access_count)
# 保留率 = e^(-t/S)
R = math.exp(-hours_since_access / (S * 24)) # S 以天为单位
return R
# 示例
print(compute_retention(0.9, 5, 1)) # 高重要性,多次访问,1天后 → 0.99
print(compute_retention(0.3, 0, 168)) # 低重要性,未再访问,7天后 → 0.13
四、开源框架横评------六大记忆方案对比
理论框架清楚了,落地时用什么?以下是当前主流开源记忆方案的横向对比:
| 框架 | 定位 | 核心能力 | 记忆分层 | 图记忆 | 语言 | 成熟度 |
|---|---|---|---|---|---|---|
| Mem0 | 通用记忆层 | 事实提取 + 多信号检索 + 更新决策 | 扁平(add/search) | 可选 | Python | ★★★★ |
| Zep | 长期记忆服务 | 时序知识图谱 | 对话摘要 + 实体 | 内置核心 | Go | ★★★☆ |
| MemGPT / Letta | 虚拟上下文管理 | Agent 自主编辑记忆 | Core / Archival / Recall | 无 | Python | ★★★☆ |
| Spring AI | Java 框架原生 | ChatMemory + Advisor 拦截 | 短期 / 长期 | 无 | Java | ★★★☆ |
| LangChain / LangMem | 通用编排框架 | 多层 Memory + Prompt 优化 | Buffer / Entity / Summary | 可选 | Python | ★★★★ |
| 腾讯云 Agent Memory | 生产级方案 | 分层蒸馏 + 冲突仲裁 | L0-L3 四级 | 可选 | --- | ★★★☆ |
信息综合自各框架官方文档及社区资料
逐一点评
Mem0 :目前应用最广的通用记忆层。API 设计优雅------add / search / update / delete 四个操作覆盖了记忆管理的基本需求。但记忆本质上是扁平的,没有内建的分层机制。V3 版本的多信号检索(semantic + BM25 + entity matching)是目前开源方案中最好的检索设计。
bash
# Mem0 的核心 API 示例
from mem0 import Memory
m = Memory()
# 添加记忆 ------ LLM 自动提取事实
m.add("我喜欢用 Java,项目用 Spring Boot", user_id="user_123")
# 内部:提取出 [{fact: "prefers Java"}, {fact: "uses Spring Boot"}]
# 搜索记忆 ------ 多信号检索
results = m.search("用户的技术栈偏好", user_id="user_123")
# V3: semantic + BM25 + entity matching 三路召回
# 更新记忆 ------ 自动判断是否需要更新
m.add("我现在改用 Go 了", user_id="user_123")
# 内部:检测到与 "prefers Java" 冲突,执行更新
Zep:时序知识图谱是独特优势。它不仅记录事实,还记录事实的时间关系------"用户 3 月说偏好 A,5 月改成了 B"。适合需要关系推理和偏好演化的长期记忆场景。但独立部署增加了运维成本,对中小项目来说有些重。
MemGPT / Letta :最有开创性的思想------"上下文即虚拟内存"。让 Agent 自主决定什么信息进入 Context Window、什么信息换出到外部存储,而不是框架自动管理。
bash
# MemGPT 的核心思想(简化示意)
# Agent 自己管理记忆的"换入换出",类似操作系统的虚拟内存
class MemGPTAgent:
def step(self, user_message: str):
# Agent 自主决定是否需要从外部存储加载记忆
if self.needs_more_context():
# "换入":从 Archival Memory 检索相关记忆到 Core Memory
relevant = self.archival.search(user_message)
self.core_memory.make_room(relevant) # 腾出空间
# Agent 自主决定是否要把当前信息"换出"到长期存储
if self.core_memory.is_full():
to_archive = self.decide_what_to_archive()
self.archival.store(to_archive)
self.core_memory.remove(to_archive)
return self.generate_response(user_message)
这个理念影响了后续几乎所有记忆框架的设计思路。但框架本身比较重,适合研究型项目。
Spring AI:Java 生态最自然的选择。ChatMemory 接口 + Advisor 拦截模式的设计合理,和 Spring 生态的集成非常顺滑。
bash
// Spring AI 的 ChatMemory 接口
public interface ChatMemory {
void add(String conversationId, List<Message> messages);
List<Message> get(String conversationId, int lastN);
void clear(String conversationId);
}
// Advisor 模式 ------ 自动注入历史消息
ChatClient client = ChatClient.builder(chatModel)
.defaultAdvisors(
new MessageChatMemoryAdvisor(chatMemory) // 短期记忆
)
.build();
但长期记忆方案目前还不够成熟,社区提供的方案(AutoMemoryTools / Redis 向量库)各有局限,需要自己补齐巩固和遗忘机制。
LangChain / LangMem:功能最全但复杂度也最高。传统 Memory 模块(Buffer / Entity / Summary)正在被 LangGraph 的新方案替代。适合需要灵活组合多种记忆策略的场景,但学习曲线陡峭。
腾讯云 Agent Memory:最接近"生产级"的思路------分层蒸馏(L0→L3)+ 质量门控 + 冲突仲裁。这套方案直接影响了 Dream-SaaS 的记忆架构设计。它的核心贡献是把"巩固"这个环节做成了显式的、可配置的流程,而不是隐含在 add API 里的黑箱操作。
选型建议
没有银弹。关键是想清楚你的 Agent 需要什么层次的记忆:
- 只需要基本的短期对话 + 事实存储 → Mem0 足够
- 需要关系推理和偏好演化 → Zep 的图谱能力有价值
- Java 技术栈 → Spring AI 是基础,按需集成 Mem0 或自建巩固链
- 需要 Agent 自主管理上下文 → Letta(MemGPT)的思路值得借鉴
- 追求生产级稳定性 → 参考腾讯云方案的分层蒸馏 + 质量门控
五、三个被低估的设计决策
理论框架和框架选型之外,工程实践中有三个容易被忽略但影响深远的设计决策。
5.1 检索评分中"时间衰减"比"语义相似度"更重要
大部分人在设计检索时把主要精力放在语义相似度上------选择最好的 Embedding 模型、调优向量索引参数。但工程实践表明,对于偏好类记忆,时间衰减的权重往往被严重低估。
原因很直接:用户的偏好会变。一个月前说"喜欢用 MySQL",现在可能已经迁移到 PostgreSQL 了。如果给旧偏好和最新偏好相同的权重,Agent 会在关键时刻给出过时的建议。
bash
# 反模式:只看语义相似度
results = vector_db.search(query_embedding, top_k=5)
# 问题:1 个月前的 "prefers MySQL" 和今天的 "switched to PostgreSQL"
# 都可能被检索到,且相似度接近
# 正确做法:给时间衰减更高的权重
results = vector_db.search_with_scoring(
query_embedding,
weights={"semantic": 0.3, "recency": 0.5, "importance": 0.2}
# 偏好类记忆:recency 权重最高
)
建议:对偏好类、事实类记忆给更高的时间衰减权重,让最新的信息在检索中占据优势。
5.2 巩固不是"复制"而是"蒸馏"
很多人把短期记忆"到期后存到长期"理解成简单的数据迁移------TTL 过期了,从 Redis 搬到 PostgreSQL。这是错误的。
巩固的本质是信息压缩和知识提取:LLM 从多轮对话中提取事实、归纳模式、更新用户画像------这是一次有损压缩,把大量原始对话浓缩成几条高质量的结构化知识。
bash
错误理解:
短期记忆(Redis TTL 到期)──复制──> 长期记忆(PostgreSQL)
结果:长期记忆里全是碎片化的对话片段,噪声多
正确理解:
短期记忆(Redis TTL 到期)
│
▼ LLM 提取、归纳、压缩
高质量结构化知识 ──> 长期记忆(PostgreSQL)
结果:长期记忆里是蒸馏后的精华
这步做不好,长期记忆里全是碎片化的噪声,检索出来的东西质量很低,不如不用。腾讯云的分层蒸馏(L0→L1→L2→L3)是对这个问题最系统的回答。
5.3 偏好管理需要独立于记忆检索
用户说"我喜欢 Java",这条信息应该同时存在于两个地方:
- 偏好面板:直接注入每次请求的 System Prompt(保证 100% 可见)
- 语义记忆库:作为可检索的知识(补充上下文)
bash
双写机制:
用户说 "我喜欢 Java"
│
├──> 语义记忆(向量库)── 可检索,但有概率检索不到
│
└──> 偏好面板(结构化存储)── 每次请求直接注入 Prompt
保证 Agent 一定知道
注入 Prompt 时:
System: "你是 XX 助手。
用户偏好:Java, Spring Boot, PostgreSQL
[来自偏好面板的直接注入,不依赖检索]"
如果只在语义记忆里靠检索召回,可能出现一个尴尬的场景------用户明确告诉 Agent "我用 Java",但下一次对话时 Agent 没有检索到这条记忆,又推荐了 Python 方案。
工程上需要双写 + 去重机制:写入语义记忆的同时,更新偏好面板;检索时优先查偏好面板,语义检索作为补充。
结语
记忆系统的核心不是"怎么存",而是存什么、什么时候存、怎么检索、怎么遗忘。这五个问题的答案共同决定了 Agent 从"无状态工具"进化为"有记忆的伙伴"的质量上限。
五层记忆模型提供了认知框架,五阶段生命周期提供了工程闭环,六大框架提供了选型参照。理论到位了,下一步是落地。
下一篇,从理论进入工程实战------如何把五层记忆落到一个可插拔的 Pipeline 架构里,以 Dream-SaaS 的真实实现为例,讲清楚编码、存储、检索、巩固、遗忘每一环的代码级设计。
有问题评论区见,欢迎交流~
📖 深入理解 AI Agent 系列 · 记忆系统 01
参考资料:
认知科学
- Miller, G.A. (1956). The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information. Psychological Review, 63(2), 81--97.
- Baddeley, A.D. (2000). The episodic buffer: a new component of working memory? Trends in Cognitive Sciences, 4(11), 417--423.
Agent 记忆论文
- Park, J.S., O'Brien, J.C., Cai, C.J., Morris, M.R., Liang, P. & Bernstein, M.S. (2023). Generative Agents: Interactive Simulacra of Human Behavior. arXiv:2304.03442.
- MemGPT: Towards LLMs as Operating Systems(2023).
工程实践
- 腾讯云 TencentDB Agent Memory 实践 --- 记忆系统分层设计
- 腾讯云 TencentDB Agent Memory 实践 --- 记忆检索与蒸馏
- 腾讯云 TencentDB Agent Memory 实践 --- 冲突仲裁与质量门控
- 掘金社区:Agent Memory 分类与工程实现
- OpenAI: ChatGPT Memory Dreaming
开源框架