02.1 — 记忆分类与架构
定位: Agent 记忆系统的基石——深入理解四种记忆类型及其在 Agent 中的实现架构 面试高频度: ⭐⭐⭐⭐⭐ 考查方式: 概念对比题(四种记忆的区别)、架构设计题(设计 Agent 的记忆系统)、辨析题(短期 vs 长期记忆的实现差异)
一、这是什么?为什么需要它?
是什么
Agent 的记忆系统是一套让 Agent 能够在不同时间尺度上存储、检索和利用信息的技术架构。它借鉴了人类记忆的分类方式,将记忆分为短期工作记忆、长期语义记忆、情景记忆等不同类型。
为什么需要记忆?
❌ 没有记忆的 Agent:
每次对话都是"初见"
"我刚才说了什么?"— 不记得
"上次你也是这么做的,结果错了" — 不记得
每次都需要把全部上下文重传
✅ 有记忆的 Agent:
知道用户偏好
记住过去的成功和失败
跨会话保持一致性
能积累和学习核心洞察:没有记忆的 Agent 是"鱼的记忆"——7 秒后重来。记忆让 Agent 从"一次性工具"进化为"持续助手"。
定位到知识体系
Agent 整体架构中,记忆系统的作用:
┌──────────┐
│ LLM 核 │
└────┬─────┘
│ 注入
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────┐
│短期记忆 │ │ 长期记忆 │ │ 工具结果 │
│(上下文) │ │ (RAG) │ │ (临时) │
└────────┘ └──────────┘ └──────────┘二、原理拆解
2.1 四种记忆类型详解
借鉴认知科学,Agent 的记忆分为四个层次:
① 短期工作记忆(Working Memory)
| 属性 | 说明 |
|---|---|
| 存储内容 | 当前对话的 messages、当前任务的上下文 |
| 存储位置 | LLM 的 context window(in-context) |
| 容量限制 | 受限于 context window 大小(8K-200K tokens) |
| 持续时间 | 当前会话(临时的) |
| 丢失机制 | 会话结束 / context window 溢出被截断 |
python
# 短期记忆的典型实现——messages 数组
working_memory = [
{"role": "system", "content": "你是一个有帮助的助手"},
{"role": "user", "content": "帮我写一个 Python 脚本"},
{"role": "assistant", "content": "好的,这是你要的脚本..."},
{"role": "tool", "content": "脚本执行结果: ..."},
# ... 会话继续,messages 不断追加
]为什么需要它:LLM 是无状态的——每次调用都是独立事件。短期记忆通过把所有上下文放在 prompt 中,让 LLM"看起来"有记忆。
局限性:context window 溢出时,最早的信息会被"遗忘"。
② 长期记忆(Long-term Memory)
| 属性 | 说明 |
|---|---|
| 存储内容 | 跨会话的重要信息、用户偏好、知识库 |
| 存储位置 | 外部存储(向量数据库、文件系统、SQL) |
| 容量限制 | 几乎无限(取决于外部存储) |
| 持续时间 | 持久化(跨会话、跨天) |
| 丢失机制 | 主动删除/遗忘策略 |
python
# 长期记忆的典型实现——向量数据库
class LongTermMemory:
def __init__(self):
self.vector_db = ChromaDB() # 或其他向量数据库
def store(self, content: str, metadata: dict):
embedding = embed(content)
self.vector_db.add(embedding, content, metadata)
def retrieve(self, query: str, top_k: int = 5):
query_embedding = embed(query)
return self.vector_db.similarity_search(query_embedding, k=top_k)为什么需要它:短期记忆"记不住"跨会话的信息。长期记忆让 Agent 能够积累知识。
③ 情景记忆(Episodic Memory)
| 属性 | 说明 |
|---|---|
| 存储内容 | 过去的交互事件、具体的经验("上次用户这样问的时候,我那样回答导致他不满意") |
| 存储形式 | 事件序列 + 结果反馈 |
| 用途 | 从过往经验中学习、避免重复错误 |
python
# 情景记忆的典型数据结构
class EpisodicMemory:
episodes = [
{
"timestamp": "2026-07-15T10:30:00",
"task": "生成数据分析报告",
"actions": ["读取CSV", "计算统计量", "生成图表"],
"result": "success",
"user_feedback": "图表颜色需要调整",
"lesson": "下次使用更鲜明的配色"
},
# ... 更多事件
]
def recall_similar(self, current_task: str) -> list:
"""检索类似情景,提取经验教训"""
pass为什么需要它:语义记忆知道"通常怎么做",情景记忆知道"上次这么做导致了什么结果"。后者让 Agent 能从具体经验中学习。
④ 语义记忆(Semantic Memory)
| 属性 | 说明 |
|---|---|
| 存储内容 | 事实性知识、概念、规则("Python 是一种动态类型语言") |
| 存储形式 | 知识图谱 / 向量化的事实陈述 |
| 用途 | 为 Agent 提供常识和专业知识 |
python
# 语义记忆的典型实现——知识图谱
semantic_memory = {
"Python": {
"type": "programming_language",
"paradigm": ["object-oriented", "functional", "procedural"],
"typing": "dynamic",
"use_cases": ["web", "data science", "automation"],
"related_to": ["JavaScript", "Java", "C++"]
},
# ...
}为什么需要它:LLM 训练数据中已经有大量语义知识,但可能过时或不准确。语义记忆可以让 Agent 访问定制化/更新的知识。
2.2 记忆架构对比
| 维度 | 短期记忆 | 长期记忆 | 情景记忆 | 语义记忆 |
|---|---|---|---|---|
| 存储位置 | In-context | 外部 DB | 外部 DB | 外部 DB / 模型参数 |
| 访问速度 | 纳秒级 | 毫秒级 | 毫秒级 | 毫秒级 |
| 容量 | ~200K tokens | 几乎无限 | 几乎无限 | 几乎无限 |
| 持久性 | 会话级 | 持久化 | 持久化 | 持久化 |
| 实现复杂度 | ⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 与 LLM 集成 | 原生(prompt 中) | RAG 注入 | 特殊 prompt 模板 | 微调 / RAG |
2.3 Agent 记忆的读写流程
写操作(Agent 学习):
经验/交互 → 重要性评估 → 是否值得存储?
├── 是 → 选择记忆类型 → 编码 → 存储
└── 否 → 丢弃
读操作(Agent 回忆):
当前上下文 → 触发检索 → 搜索各记忆层
├── 短期: 直接在 context window 中
├── 长期: 向量相似度检索
├── 情景: 相似事件匹配
└── 语义: 知识图谱查询
→ 融合 → 注入 prompt → LLM 生成三、图解全景
┌─────────────────────────────────────────────────────────────┐
│ Agent 记忆系统架构图 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ LLM Context Window │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ System │ │ Messages │ │ Retrieved │ │ │
│ │ │ Instruction │ │ (短期记忆) │ │ Memories │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ 注入 │
│ ┌──────────────────────┴──────────────────────────────┐ │
│ │ 记忆管理层 │ │
│ │ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ 重要性 │ │ 检索器 │ │ 遗忘策略 │ │ │
│ │ │ 评分器 │ │ Retriever │ │ Forgetting │ │ │
│ │ └────────────┘ └────────────┘ └──────────────┘ │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌──────────────────────┴──────────────────────────────┐ │
│ │ 存储层 │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │ │
│ │ │ 向量数据库 │ │ 知识图谱 │ │ 文件/数据库 │ │ │
│ │ │ (长期/情景)│ │ (语义) │ │ (原始数据) │ │ │
│ │ └────────────┘ └────────────┘ └────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘四、实战验证
4.1 实现一个简单的双层记忆 Agent
python
import json
from typing import List, Dict
class DualMemoryAgent:
"""短期 + 长期双层记忆 Agent"""
def __init__(self):
self.short_term: List[Dict] = [] # 短期:messages 列表
self.long_term: Dict[str, str] = {} # 长期:简单的 key-value 存储
def add_to_short_term(self, role: str, content: str):
self.short_term.append({"role": role, "content": content})
# 保持短期记忆窗口大小
if len(self.short_term) > 20:
# 把最早的消息压缩到长期记忆
self._compress_to_long_term()
self.short_term = self.short_term[-10:]
def _compress_to_long_term(self):
"""将早期短期记忆摘要后存入长期记忆"""
early_msgs = self.short_term[:-10]
summary = self._summarize(early_msgs)
self.long_term[f"session_{id(self)}"] = summary
def _summarize(self, messages: List[Dict]) -> str:
"""简单的摘要——实际使用需要 LLM 调用"""
topics = [m["content"][:50] for m in messages]
return f"会话摘要: {'; '.join(topics)}"
def get_context(self) -> List[Dict]:
"""获取完整的上下文(短期 + 长期注入)"""
context = []
# 注入长期记忆摘要
if self.long_term:
context.append({
"role": "system",
"content": f"【长期记忆】\n" + "\n".join(self.long_term.values())
})
# 加入短期记忆
context.extend(self.short_term)
return context
# 使用验证
agent = DualMemoryAgent()
# 第一轮对话
agent.add_to_short_term("user", "我喜欢喝咖啡")
agent.add_to_short_term("assistant", "好的,我记住了")
print("短期记忆长度:", len(agent.short_term))
print("长期记忆条数:", len(agent.long_term))
# 模拟多轮对话
for i in range(25):
agent.add_to_short_term("user", f"这是第{i}条消息")
agent.add_to_short_term("assistant", f"回应第{i}条消息")
print("\n压缩后——")
print("短期记忆长度:", len(agent.short_term))
print("长期记忆条数:", len(agent.long_term))4.2 基准测试:有无记忆的效果对比
bash
# 测试场景:跨会话任务(记住用户偏好)
# Agent A:无记忆(每次重新开始)
# Agent B:有长期记忆(记住用户偏好)
# 测试方法:
# 第一轮:用户说"我喜欢简洁的回答风格"
# 第二轮:用户说"帮我写个报告"(期望:简洁风格)
# 结果:
# Agent A(无记忆): 生成长篇详细报告 ❌
# Agent B(有记忆): 生成简洁风格报告 ✅
# 记忆带来的提升:偏好符合度 40% → 90%五、面试视角
| 追问 | 答案要点 |
|---|---|
| Agent 的四种记忆类型及其区别? | 短期(会话级,in-context)、长期(持久化,外部存储)、情景(具体事件经验)、语义(通用知识)。类比人类记忆系统理解 |
| 短期记忆溢出怎么处理? | 滚动窗口(丢弃最早消息)、摘要压缩(LLM 总结旧内容)、分层存储(先压缩再转长期)、显式记忆检索(只注入相关记忆) |
| 情景记忆和语义记忆的区别? | 情景记忆是"具体事件"(上次这样做失败了),语义记忆是"抽象知识"(这样做通常不行)。情景是"实例",语义是"规律" |
| Agent 记忆系统和 RAG 的关系? | RAG 是长期记忆的一种实现方式。但 Agent 记忆系统更全面,包含短期/长期/情景/语义多种类型。RAG 主要解决长期语义记忆的检索问题 |
| 如何设计记忆的重要性评分? | 维度:时效性(越新越重要)、相关性(与任务相关度)、用户反馈(明确的记忆指令)、使用频率(经常被检索的更重要)。加权融合 |
| Agent 会"遗忘"吗?应该怎么设计遗忘机制? | 应该。遗忘机制:时间衰减(旧记忆权重降低)、容量限制(淘汰最不重要的)、明确遗忘(用户说"忘记这个")、冲突解决(新信息覆盖旧信息) |
📚 相关链接
- **RAG与长期记忆** — 长期记忆的 RAG 实现
- **记忆管理与检索** — 记忆生命周期管理策略
- **什么是 AI Agent** — Agent 基础
- **RAG 知识库** — RAG 的深入技术细节
- ← 返回 **Agent记忆系统索引**