目录
[2.1 第一层:工作记忆(Working Memory)](#2.1 第一层:工作记忆(Working Memory))
[2.2 第二层:短期记忆(Short-term Memory)](#2.2 第二层:短期记忆(Short-term Memory))
[2.3 第三层:长期记忆(Long-term Memory)](#2.3 第三层:长期记忆(Long-term Memory))
[2.4 第四层:永久记忆(Persistent Memory / Knowledge)](#2.4 第四层:永久记忆(Persistent Memory / Knowledge))
[3.1 四层记忆分层对比](#3.1 四层记忆分层对比)
[3.2 四层记忆的协同机制](#3.2 四层记忆的协同机制)
一、为什么需要记忆系统
- 持续性:期望实现跨会话保持上下文;
- 个性化:记住用户偏好和历史;
- 自我进化:积累经验,提升能力;
- 效率:减少获取重复信息;
二、记忆系统的分层
Agent的记忆系统分为四层------工作记忆(即时推理)、短期记忆(当前会话)、长期记忆(跨会话积累)、永久记忆(结构化知识)。各层职责明确,协同工作,共同支撑Agent的持续对话和个性化服务能力。
2.1 第一层:工作记忆(Working Memory)
- 定义: Agent当前推理过程中的即时工作区;
- 生命周期:当前推理步骤(毫秒级~秒级);
- 存储位置:进程内存;
- 容量:极小(几个关键变量)
- 存储内容:1)当前任务的中间状态;2)思考链(Thought Chain);3)工具调用的输入输出;4)临时计算结果;5)决策过程中的关键判断;
python
class WorkingMemory:
"""工作记忆:Agent推理时的即时工作台"""
def __init__(self):
self.variables = {} # 变量存储
self.thought_chain = [] # 思考链
self.step_context = {} # 当前步骤上下文
def set_var(self, key, value):
"""设置变量"""
self.variables[key] = value
def get_var(self, key, default=None):
"""获取变量"""
return self.variables.get(key, default)
def think(self, thought):
"""记录思考步骤"""
self.thought_chain.append({
"thought": thought,
"step": len(self.thought_chain) + 1
})
def get_thought_chain_text(self):
"""获取思考链文本"""
return "\n".join([
f"[思考{i}] {t['thought']}"
for i, t in enumerate(self.thought_chain, 1)
])
def set_step_context(self, step_name, context):
"""设置当前步骤的上下文"""
self.step_context[step_name] = context
def get_step_context(self, step_name):
"""获取某步骤的上下文"""
return self.step_context.get(step_name)
def clear(self):
"""清空工作记忆(新任务开始时)"""
self.variables = {}
self.thought_chain = []
self.step_context = {}
2.2 第二层:短期记忆(Short-term Memory)
- 定义:当前会话周期内的对话上下文;
- 生命周期:当前会话(分钟级~小时级);
- 存储位置:内存 / Redis会话存储;
- 容量:有限(通常10-20轮对话)
- 存储内容:1)当前会话的所有对话轮次;2)当前任务的中间结果;3)未完成的后续事项;4)当前会话中建立的临时结论;
- 过期处理:1)会话结束自动清除;2)重要内容摘要后转入长期记忆;3)超容量时删除最旧的轮次
python
class ShortTermMemory:
"""短期记忆:基于轮次的上下文管理"""
def __init__(self, max_turns=10):
self.max_turns = max_turns
self.turns = [] # 对话轮次列表
def add_turn(self, user_input, agent_output, metadata=None):
"""添加一轮对话"""
turn = {
"user": user_input,
"agent": agent_output,
"metadata": metadata or {},
"timestamp": datetime.now().isoformat()
}
self.turns.append(turn)
# 超容量时删除最旧的轮次
if len(self.turns) > self.max_turns:
self.turns.pop(0)
def get_full_context(self):
"""获取完整上下文"""
return "\n".join([
f"用户: {t['user']}\n助手: {t['agent']}"
for t in self.turns
])
def get_recent_turns(self, n=3):
"""获取最近N轮对话"""
return self.turns[-n:]
def get_turn_count(self):
"""获取对话轮数"""
return len(self.turns)
def summarize_to_long_term(self, llm):
"""将会话摘要后存入长期记忆"""
if len(self.turns) == 0:
return ""
conversation = self.get_full_context()
summary = llm.invoke(f"""
请对以下对话进行简短摘要(100字以内):
{conversation}
摘要:
""")
return summary
def clear(self):
"""清空短期记忆"""
self.turns = []
2.3 第三层:长期记忆(Long-term Memory)
- 定义: 跨会话积累的重要信息和经验
- 生命周期:会话之间持续(天级~月级)
- 存储位置:向量数据库(Pinecone/Milvus/Weaviate)
- 容量:大(可存储多年数据)
- 存储内容:1)重要会话的摘要;2)用户偏好和习惯;3)达成的重要结论和决策;4)解决方案和经验积累;5)问题和应对的处理方式;
- 检索方式:1)向量相似度检索(语义检索);2)关键词检索(BM25);3)时间衰减(越近的记忆权重越高)
python
class LongTermMemory:
"""长期记忆:基于向量数据库的跨会话记忆"""
def __init__(self, vector_store, user_id):
self.vector_store = vector_store
self.user_id = user_id
def store(self, content, memory_type="general", importance=1.0):
"""
存储记忆到长期记忆
Args:
content: 记忆内容文本
memory_type: 记忆类型(preference/decision/experience等)
importance: 重要程度(0-1),用于后续清理时参考
"""
vector = self.embed(content)
self.vector_store.insert({
"id": f"{self.user_id}_{uuid.uuid4()}",
"values": vector,
"text": content,
"metadata": {
"user_id": self.user_id,
"type": memory_type,
"importance": importance,
"created_at": datetime.now().isoformat()
}
})
def retrieve(self, query, top_k=5, memory_types=None):
"""
从长期记忆中检索相关内容
Args:
query: 查询文本
top_k: 返回数量
memory_types: 只检索特定类型的记忆
"""
query_vector = self.embed(query)
# 构建过滤条件
filter_cond = {"user_id": self.user_id}
if memory_types:
filter_cond["type"] = {"$in": memory_types}
results = self.vector_store.query(
vector=query_vector,
top_k=top_k,
filter=filter_cond,
include_metadata=True
)
# 应用时间衰减
return self.apply_time_decay(results)
def apply_time_decay(self, results):
"""应用时间衰减:越新的记忆权重越高"""
now = datetime.now()
scored_results = []
for r in results:
created_at = datetime.fromisoformat(r["metadata"]["created_at"])
age_days = (now - created_at).days
# 指数衰减,半衰期30天
decay = math.exp(-age_days / 30)
final_score = r["score"] * decay
scored_results.append({
"content": r["text"],
"original_score": r["score"],
"decay_score": decay,
"final_score": final_score,
"metadata": r["metadata"]
})
# 按最终分数排序
scored_results.sort(key=lambda x: x["final_score"], reverse=True)
return scored_results
def get_user_preferences(self):
"""获取用户偏好(专门检索偏好类记忆)"""
return self.retrieve("用户偏好", memory_types=["preference"], top_k=10)
def get_relevant_experiences(self, problem):
"""获取相关经验(用于解决新问题)"""
return self.retrieve(problem, memory_types=["experience"], top_k=5)
2.4 第四层:永久记忆(Persistent Memory / Knowledge)
- 定义: 持久化的结构化知识,包括用户画像、系统配置、专业知识;
- 生命周期:永久(直到显式删除);
- 存储位置:结构化数据库(PostgreSQL/MongoDB);
- 容量:理论无限(需有效管理);
- 存储内容:1)用户画像(用户基本信息、偏好设置、会员等级、标签、账户状态);2)领域知识(产品知识库、业务流程规范、常见问题解答、专业领域知识);3)Agent经验(成功的解决方案模式、失败的教训;优化记录)
python
class PersistentMemory:
"""永久记忆:结构化的持久化存储"""
def __init__(self, db):
self.db = db # 数据库连接
# ============ 用户画像 ============
def get_user_profile(self, user_id):
"""获取用户画像"""
user = self.db.users.find_one({"user_id": user_id})
if user:
return {
"basic_info": user.get("basic_info", {}),
"preferences": user.get("preferences", {}),
"tags": user.get("tags", []),
"membership_level": user.get("membership_level", "普通"),
"created_at": user.get("created_at"),
"updated_at": user.get("updated_at")
}
return self._create_empty_profile(user_id)
def update_user_profile(self, user_id, updates):
"""更新用户画像"""
self.db.users.update_one(
{"user_id": user_id},
{
"$set": {
**updates,
"updated_at": datetime.now().isoformat()
}
},
upsert=True
)
def add_user_tag(self, user_id, tag):
"""添加用户标签"""
self.db.users.update_one(
{"user_id": user_id},
{
"$addToSet": {"tags": tag},
"$set": {"updated_at": datetime.now().isoformat()}
}
)
# ============ 知识库 ============
def save_knowledge(self, category, question, answer, metadata=None):
"""保存知识条目"""
self.db.knowledge.insert_one({
"category": category,
"question": question,
"answer": answer,
"metadata": metadata or {},
"created_at": datetime.now().isoformat(),
"usage_count": 0,
"last_used": None
})
def search_knowledge(self, query, category=None, top_k=5):
"""搜索知识库"""
filter_cond = {}
if category:
filter_cond["category"] = category
# 简单实现:基于关键词匹配
results = self.db.knowledge.find({
"$or": [
{"question": {"$regex": query}},
{"answer": {"$regex": query}}
],
**filter_cond
}).limit(top_k)
return list(results)
# ============ Agent经验 ============
def save_agent_experience(self, agent_id, experience):
"""保存Agent经验"""
self.db.agent_experiences.insert_one({
"agent_id": agent_id,
"experience": experience,
"created_at": datetime.now().isoformat()
})
def get_agent_experiences(self, agent_id, limit=20):
"""获取Agent经验"""
experiences = self.db.agent_experiences.find(
{"agent_id": agent_id}
).sort("created_at", -1).limit(limit)
return list(experiences)
三、记忆分层对比及协同机制
3.1 四层记忆分层对比
| 维度 | 工作记忆 | 短期记忆 | 长期记忆 | 永久记忆 |
|---|---|---|---|---|
| 生命周期 | 单次推理 | 当前会话 | 跨会话 | 永久 |
| 存储位置 | 进程内存 | 内存/Redis | 向量数据库 | 结构化DB |
| 容量 | 极小 | 小(10-20轮) | 大 | 无限 |
| 访问频率 | 最高 | 高 | 中 | 低 |
| 检索方式 | 直接访问 | 顺序遍历 | 向量检索 | 条件查询 |
| 过期策略 | 随任务清除 | 会话结束/摘要 | 时间衰减 | 手动删除 |
| 类比 | 工作台 | 短期记忆 | 长期记忆 | 知识库 |
| 数据特征 | 即时状态 | 对话记录 | 经验积累 | 结构化画像 |
3.2 四层记忆的协同机制
- 四层记忆协同目标:让Agent在每次对话时都能获取"完整的上下文";
- 协同原则 :
- 热数据优先(当前任务状态 > 会话上下文 > 历史经验);
- 按需下沉(重要信息逐层沉淀,不重要信息及时清理);
- 容量平衡(各层有容量限制,通过压缩/清理维持平衡);
- 统一输出(最终整合为LLM可直接使用的prompt);
- 四层记忆写入流程 :
- 每一轮推理后,立即写入Working Memory;
- 轮次结束时写入(对话记录),立即写入Short-term Memory;
- 会话结束/重要交互时写入Long-term Memory;
- 识别到明确偏好/决策时写入Persistent Memory;
- 四层记忆读取流程:每一轮对话,依次获取工作记忆、短期记忆、中期记忆、长期记忆,最终构建统一prompt,给到LLM
最后,我们以一个「订机票场景记忆协同」的案例,来说明一下四层记忆的协同机制:
python
┌─────────────────────────────────────────────────────────────┐
│ 订机票场景记忆协同 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【第一轮对话】 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 用户: "我想订明天去北京的机票" │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ 写入流程: │
│ • Working: task=订机票, destination=北京, date=明天 │
│ • Short: [用户: "我想订明天去北京的机票"] │
│ • Long: 不写入(非重要交互) │
│ • Persistent: 不写入(非偏好/决策) │
│ ↓ │
│ 读取流程: │
│ • Working: 提供当前任务状态 │
│ • Short: 空(第一次对话) │
│ • Long: 检索相关历史(可能找到之前的订票经验) │
│ • Persistent: 获取用户画像 │
│ ↓ │
│ Context整合: │
│ "用户VIP会员,之前偏好国航,不坐红眼航班,常用出发地..." │
│ ↓ │
│ LLM回复 + 写入Short │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ │
│ 【第二轮对话】 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 用户: "对,帮我看看国航的" │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ 写入流程: │
│ • Working: airline=国航(更新状态) │
│ • Short: 添加第二轮对话 │
│ • Long: 不写入 │
│ • Persistent: 不写入 │
│ ↓ │
│ 读取流程: │
│ • Working: 提供当前任务状态(订机票、国航) │
│ • Short: 提供第一轮对话上下文 │
│ • Long: 检索国航相关的历史经验 │
│ • Persistent: 获取用户画像中的偏好 │
│ ↓ │
│ Context整合: │
│ "当前:订机票,国航,明天北京 │
│ 会话:用户想订明天去北京的机票 │
│ 偏好:用户是VIP,偏好国航,不坐红眼航班" │
│ ↓ │
│ LLM回复 + 写入Short │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ │
│ 【第三轮对话:用户确认偏好】 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 用户: "我喜欢靠窗的位置,记得存一下" │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ 写入流程: │
│ • Working: seat_preference=靠窗 │
│ • Short: 添加第三轮对话 │
│ • Long: 存储偏好经验("喜欢靠窗位置") │
│ • Persistent: ★ 写入用户画像(重要偏好!) │
│ │ 更新 persistent storage: │
│ │ preferences.seat = "靠窗" │
│ ↓ │
│ 读取流程: │
│ • Working: 当前状态 │
│ • Short: 完整会话 │
│ • Long: 检索相关偏好历史 │
│ • Persistent: ★ 获取完整用户画像 │
│ │ 包括刚才保存的"靠窗"偏好 │
│ ↓ │
│ Context整合: │
│ "用户VIP,偏好国航,不坐红眼航班,喜欢靠窗位置, │
│ 常用出发地...(完整画像)" │
│ ↓ │
│ LLM回复 + 写入各层记忆 │
│ │
└─────────────────────────────────────────────────────────────┘