引言
本文约 2500 字,阅读时间 8 分钟。建议收藏后阅读。
如果你正在开发 AI Agent,一定会遇到这个灵魂拷问:"为什么我的 Agent 聊着聊着就忘了前面说过什么?"
这正是记忆系统的价值所在。作为 AI Agent 的核心组件之一,记忆系统决定了 Agent 能否像人类一样保持对话连贯性、积累经验和持续学习。
今天,我将从工程实践角度,深度解析 AI Agent 记忆系统的设计与实现。
一、为什么 Agent 需要记忆?
1.1 LLM 的本质局限
大语言模型(LLM)本质上是无状态的文本生成器。每次 API 调用都是独立的,模型不会自动记住之前的对话内容。
# 伪代码:LLM 的调用方式
response = llm.generate("你好") # 模型不知道你是谁
response = llm.generate("我叫小明") # 模型依然不知道
response = llm.generate("我叫什么?") # 模型:我不知道
1.2 记忆系统的价值
| 能力 | 无记忆 Agent | 有记忆 Agent |
|---|---|---|
| 多轮对话 | ❌ 每轮独立 | ✅ 上下文连贯 |
| 用户偏好 | ❌ 重复询问 | ✅ 自动记住 |
| 任务进度 | ❌ 容易中断 | ✅ 持续追踪 |
| 经验积累 | ❌ 从零开始 | ✅ 越用越聪明 |
二、记忆系统的三层架构
2.1 感知记忆(Sensory Memory)
作用:临时存储当前对话的原始输入
特点:
- 生命周期极短(通常一次请求)
- 存储原始文本、图像、音频等多模态数据
- 用于即时理解和响应
class SensoryMemory:
"""感知记忆:存储当前输入的原始信息"""
def __init__(self):
self.current_input = None
self.timestamp = None
def store(self, input_data):
self.current_input = input_data
self.timestamp = time.time()
def retrieve(self):
return self.current_input
2.2 短期记忆(Short-term Memory)
作用:维护当前对话的上下文窗口
核心问题:LLM 的上下文长度有限(通常 4K-128K tokens),如何高效利用?
解决方案:
方案 A:滑动窗口(Sliding Window)
class SlidingWindowMemory:
"""滑动窗口记忆:保留最近 N 轮对话"""
def __init__(self, max_turns=10):
self.messages = []
self.max_turns = max_turns
def add(self, role, content):
self.messages.append({"role": role, "content": content})
# 只保留最近 N 轮
if len(self.messages) > self.max_turns * 2:
self.messages = self.messages[-self.max_turns * 2:]
def get_context(self):
return self.messages
方案 B:摘要压缩(Summarization)
当对话过长时,对早期内容进行摘要:
class SummarizationMemory:
"""摘要记忆:对历史对话进行压缩"""
def __init__(self, llm, max_tokens=2000):
self.llm = llm
self.raw_messages = []
self.summary = ""
self.max_tokens = max_tokens
def add(self, message):
self.raw_messages.append(message)
# 检查是否需要摘要
if self._estimate_tokens() > self.max_tokens:
self._compress()
def _compress(self):
# 使用 LLM 生成摘要
prompt = f"""请对以下对话进行摘要,保留关键信息:
{self.raw_messages[:-5]} # 保留最近 5 条不摘要
"""
self.summary = self.llm.generate(prompt)
self.raw_messages = self.raw_messages[-5:]
2.3 长期记忆(Long-term Memory)
作用:跨会话持久化存储用户信息和知识
技术选型对比:
| 存储方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 关系型数据库 | 结构化用户数据 | 事务支持、查询灵活 | 不适合语义检索 |
| Redis | 会话缓存 | 高性能、TTL 支持 | 内存限制 |
| 向量数据库 | 语义记忆 | 相似度检索 | 需要 Embedding |
| 图数据库 | 关系记忆 | 关系推理 | 学习成本高 |
向量记忆实现示例
import numpy as np
from typing import List, Dict
class VectorMemory:
"""向量记忆:基于语义相似度的长期记忆"""
def __init__(self, embedding_model, vector_store):
self.embedder = embedding_model
self.store = vector_store
def memorize(self, content: str, metadata: Dict = None):
"""存储记忆"""
embedding = self.embedder.encode(content)
self.store.add(
ids=[f"mem_{time.time()}"],
embeddings=[embedding],
documents=[content],
metadatas=[metadata or {}]
)
def recall(self, query: str, top_k: int = 5) -> List[str]:
"""检索相关记忆"""
query_embedding = self.embedder.encode(query)
results = self.store.query(
query_embeddings=[query_embedding],
n_results=top_k
)
return results['documents'][0]
三、记忆系统的进阶设计
3.1 记忆分层检索策略
class HierarchicalMemory:
"""分层记忆系统:按优先级检索"""
def __init__(self):
self.sensory = SensoryMemory()
self.short_term = SlidingWindowMemory()
self.long_term = VectorMemory()
def retrieve(self, query: str) -> str:
"""分层检索记忆"""
context_parts = []
# 1. 感知记忆(最高优先级)
sensory_data = self.sensory.retrieve()
if sensory_data:
context_parts.append(f"当前输入: {sensory_data}")
# 2. 短期记忆
recent_context = self.short_term.get_context()
context_parts.append("近期对话:\n" +
"\n".join([f"{m['role']}: {m['content']}"
for m in recent_context]))
# 3. 长期记忆(语义检索)
relevant_memories = self.long_term.recall(query)
if relevant_memories:
context_parts.append("相关历史:\n" +
"\n".join(relevant_memories))
return "\n\n".join(context_parts)
3.2 记忆的重要性评分
不是所有记忆都同等重要,需要设计遗忘机制:
class ScoredMemory:
"""带重要性评分的记忆"""
def __init__(self, content: str, importance: float = 1.0):
self.content = content
self.importance = importance # 1.0 - 10.0
self.created_at = time.time()
self.access_count = 0
def calculate_retention_score(self) -> float:
"""计算记忆保留分数"""
time_decay = 1 / (1 + 0.1 * (time.time() - self.created_at) / 86400)
access_boost = 1 + 0.1 * self.access_count
return self.importance * time_decay * access_boost
def access(self):
"""访问记忆,增加访问计数"""
self.access_count += 1
3.3 记忆的类型化设计
from enum import Enum
class MemoryType(Enum):
FACT = "fact" # 事实性记忆
PREFERENCE = "preference" # 用户偏好
EVENT = "event" # 事件记忆
SKILL = "skill" # 技能记忆
class TypedMemory:
"""类型化记忆系统"""
def __init__(self):
self.memories = {t: [] for t in MemoryType}
def add(self, content: str, mem_type: MemoryType,
importance: float = 1.0):
memory = ScoredMemory(content, importance)
self.memories[mem_type].append(memory)
def recall_by_type(self, query: str, mem_type: MemoryType):
"""按类型检索记忆"""
candidates = self.memories[mem_type]
# 按保留分数排序
candidates.sort(key=lambda m: m.calculate_retention_score(),
reverse=True)
return candidates[:5]
四、生产环境的最佳实践
4.1 隐私与安全
class PrivacyAwareMemory:
"""隐私感知的记忆系统"""
SENSITIVE_PATTERNS = [
r'\b\d{16,19}\b', # 银行卡号
r'\b\d{18}\b', # 身份证号
r'password[:\s]+\S+', # 密码
]
def sanitize(self, content: str) -> str:
"""敏感信息脱敏"""
for pattern in self.SENSITIVE_PATTERNS:
content = re.sub(pattern, '[REDACTED]', content)
return content
def memorize(self, content: str, **kwargs):
safe_content = self.sanitize(content)
return super().memorize(safe_content, **kwargs)
4.2 记忆同步与并发
import asyncio
from contextlib import asynccontextmanager
class AsyncMemory:
"""异步记忆系统"""
def __init__(self):
self._lock = asyncio.Lock()
self._cache = {}
@asynccontextmanager
async def _transaction(self):
async with self._lock:
yield
async def memorize(self, key: str, value: str):
async with self._transaction():
self._cache[key] = value
await self._persist(key, value)
async def _persist(self, key: str, value: str):
"""持久化到存储"""
# 异步写入数据库或缓存
pass
4.3 性能优化
| 优化策略 | 实现方式 | 效果 | ||
|---|---|---|---|---|
| 缓存热点记忆 | Redis | 减少 90% 数据库查询 | ||
| 批量写入 | 异步队列 | 优化策略 | 实现方式 | 效果 |
| --------- | --------- | ------ | ||
| 缓存热点记忆 | Redis | 减少 90% 数据库查询 | ||
| 批量写入 | 异步队列 | 降低 I/O 压力 | ||
| 索引优化 | 向量索引 + 倒排索引 | 检索速度提升 10x | ||
| 分层存储 | 热/温/冷数据分层 | 降低存储成本 |
五、实战案例:构建一个带记忆的客服 Agent
class CustomerServiceAgent:
"""带记忆系统的客服 Agent"""
def __init__(self):
self.memory = HierarchicalMemory()
self.llm = OpenAI()
async def handle(self, user_id: str, message: str):
# 1. 加载用户长期记忆
user_profile = await self.load_user_profile(user_id)
# 2. 检索相关历史对话
relevant_history = self.memory.long_term.recall(message)
# 3. 构建上下文
context = self.build_context(
user_profile=user_profile,
history=relevant_history,
recent_chat=self.memory.short_term.get_context()
)
# 4. 生成回复
response = await self.llm.chat(context + message)
# 5. 更新记忆
self.memory.short_term.add("user", message)
self.memory.short_term.add("assistant", response)
# 6. 提取重要信息存入长期记忆
await self.extract_and_memorize(message, response)
return response
async def extract_and_memorize(self, user_msg: str, assistant_msg: str):
"""从对话中提取重要信息"""
extraction_prompt = f"""
从以下对话中提取需要记住的关键信息(偏好、事实、事件):
用户: {user_msg}
助手: {assistant_msg}
只输出 JSON 格式:{{"facts": [], "preferences": [], "events": []}}
"""
extracted = await self.llm.generate(extraction_prompt)
data = json.loads(extracted)
# 存入长期记忆
for fact in data.get("facts", []):
self.memory.long_term.memorize(
fact,
metadata={"type": "fact", "timestamp": time.time()}
)
六、总结与展望
6.1 核心要点回顾
- 记忆分层:感知记忆 → 短期记忆 → 长期记忆,每层解决不同问题
- 检索策略:分层检索 + 语义相似度 + 重要性评分
- 工程实践:隐私保护、并发控制、性能优化缺一不可
6.2 未来趋势
- 多模态记忆:不仅存储文本,还包括图像、音频、视频
- 个性化记忆:基于用户画像的个性化记忆权重
- 联邦记忆:在保护隐私前提下,跨 Agent 共享知识
- 自适应记忆:Agent 自主决定记住什么、遗忘什么
参考资料
💡 思考题:你在开发 Agent 时遇到过哪些记忆相关的问题?欢迎在评论区分享讨论!
如果这篇文章对你有帮助,请点赞 👍 收藏 ⭐ 关注,我会持续输出更多 AI 工程实践干货!