2026.06.03 | youres | 27次围观
为什么大多数AI Agent都是"健忘症"患者?
你有没有发现,和AI助手聊了半天,它转头就忘了你之前说过什么?这不是bug,而是当前大多数AI Agent架构设计的根本缺陷。
传统的对话系统使用简单的消息列表作为"记忆",就像人类的短期记忆。但真正的智能需要三层记忆系统:即时感知、工作记忆和长期记忆。今天我们来深度拆解如何为AI Agent构建这套系统。
AI Agent记忆系统的三层架构
| 维度 | 即时感知 | 工作记忆 | 长期记忆 |
|---|---|---|---|
| 存储时长 | 毫秒~秒 | 会话期间 | 永久 |
| 容量 | 极小 | 中等(受限于上下文窗口) | 极大 |
| 检索方式 | 直接获取 | 按需读取 | 向量检索 |
| 实现技术 | 输入解析 | 消息列表/变量字典 | 向量数据库 |
| 是否持久化 | 否 | 否 | 是 |
第一层:即时感知(Perception)
这是Agent对当前输入的即时理解,包括:
- 用户输入的文字内容
- 上传的图片、文档
- 语音的转录文本
- 当前的环境状态(时间、位置、设备信息)
class Perception:
"""即时感知模块"""
def __init__(self, user_input: str, attachments: list = None):
self.raw_input = user_input
self.attachments = attachments or []
self.intent = None
self.entities = []
def parse(self):
# 意图识别
self.intent = self._extract_intent()
# 实体提取
self.entities = self._extract_entities()
return self
第二层:工作记忆(Working Memory)
工作记忆是Agent的"便签本",存储当前会话的上下文。关键是上下文窗口管理。
问题:LLM的上下文窗口有限(即使200K token也有成本)。
解决方案:智能截断 + 摘要压缩
class WorkingMemory:
"""工作记忆管理"""
def __init__(self, max_tokens=8000):
self.messages = []
self.max_tokens = max_tokens
def add_message(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
# 智能截断
if self._count_tokens() > self.max_tokens:
self._compress_history()
def _compress_history(self):
# 保留最近5轮对话
recent = self.messages[-10:]
# 摘要 older 对话
older = self.messages[:-10]
summary = self._summarize(older)
self.messages = [{"role": "system", "content": summary}] + recent
第三层:长期记忆(Long-term Memory)
这是区分"玩具Demo"和"生产级Agent"的关键。长期记忆需要:
1. 向量数据库选型
| 方案 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| Pinecone | 全托管,无需维护 | 成本高 | 快速原型、小团队 |
| Chroma | 轻量,本地运行 | 大规模性能一般 | 个人项目、本地部署 |
| Qdrant | 性能强,支持混合检索 | 需要自己部署 | 生产环境、高并发 |
| Milvus | 分布式,支持十亿级向量 | 运维复杂 | 企业级、超大规模 |
2. 记忆的存储策略
不是所有对话都值得永久存储。需要设计重要性评分机制:
- 用户显式标记:"/记住这个"
- 自动提取:从对话中提取事实性信息(姓名、偏好、事实)
- 时间衰减:最近的信息权重更高
- 访问频率:经常提及的信息更重要
class LongTermMemory:
"""长期记忆(向量数据库)"""
def __init__(self, vector_db):
self.db = vector_db
def store(self, content: str, metadata: dict):
"""存储记忆"""
embedding = self._get_embedding(content)
self.db.upsert(
vector=embedding,
metadata={
"content": content,
"timestamp": time.time(),
"importance": metadata.get("importance", 1),
**metadata
}
)
def retrieve(self, query: str, top_k=5):
"""检索相关记忆"""
query_vector = self._get_embedding(query)
results = self.db.search(query_vector, top_k=top_k)
# 时间衰减加权
for r in results:
age = time.time() - r.metadata["timestamp"]
decay = 0.95 ** (age / 86400) # 每天衰减5%
r.score *= decay
return sorted(results, key=lambda x: x.score, reverse=True)
实战案例:给OpenClaw添加长期记忆
OpenClaw默认只支持会话级记忆。我们来扩展它:
Step 1: 安装向量数据库
# 使用Qdrant(Docker一键启动)
docker run -p 6333:6333 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant
Step 2: 集成到OpenClaw Skill
创建memory_skill,在每次对话后自动提取记忆:
# memory_skill/SKILL.md
name: memory
description: 长期记忆管理(自动提取+检索)
# 每次对话后自动调用
hooks:
post_chat:
- extract_facts # 提取事实
- store_memory # 存储到向量库
pre_chat:
- retrieve_memory # 检索相关记忆
- inject_context # 注入到prompt
Step 3: 自动提取事实
async def extract_facts(conversation: list) -> list:
"""从对话中提取事实"""
prompt = f"""分析以下对话,提取关键事实信息(用户名、偏好、重要事件等):
{conversation}
输出JSON格式:
[
{"type": "preference", "content": "用户喜欢简洁的回答", "importance": 2},
{"type": "fact", "content": "用户在使用OpenClaw", "importance": 1}
]
"""
response = await llm_call(prompt)
return json.loads(response)
性能优化:让记忆系统快如闪电
1. 缓存热点记忆
将高频访问的记忆缓存在Redis:
class CachedMemory:
def __init__(self, vector_db, redis_client):
self.db = vector_db
self.cache = redis_client
def retrieve(self, query: str):
# 先查缓存
cache_key = f"mem:{hash(query)}"
cached = self.cache.get(cache_key)
if cached:
return json.loads(cached)
# 缓存未命中,查向量库
results = self.db.search(query)
self.cache.setex(cache_key, 3600, json.dumps(results)) # 缓存1小时
return results
2. 异步存储
存储记忆不应阻塞主流程,使用消息队列异步处理:
import asyncio
from asyncio import Queue
memory_queue = Queue()
async def memory_worker():
"""异步存储worker"""
while True:
fact = await memory_queue.get()
await vector_db.store(fact)
memory_queue.task_done()
# 启动worker
asyncio.create_task(memory_worker())
# 使用中
async def post_chat_hook():
facts = extract_facts(conversation)
for fact in facts:
await memory_queue.put(fact) # 非阻塞
常见坑点与解决方案
坑点1:记忆污染
现象:检索到的记忆和当前对话无关,反而干扰LLM判断。
解决:
- 提高检索阈值(只返回score>0.7的结果)
- 在注入prompt时标注"以下是历史记忆,仅供参考"
- 使用Rerank模型二次过滤
坑点2:存储爆炸
现象:向量数据库越来越大,查询变慢,成本飙升。
解决:
- 设置TTL(30天自动删除低重要性记忆)
- 定期合并相似记忆
- 只存储"事实",不存储完整对话
坑点3:时间混淆
现象:Agent把3个月前的事情当成昨天的。
解决:在记忆元数据中强制记录时间戳,检索时显式展示"X天前"
def format_memory(memory: dict) -> str:
"""格式化记忆,显式展示时间"""
age_days = (time.time() - memory["timestamp"]) / 86400
return f'[约{int(age_days)}天前] {memory["content"]}'
相关资源
- 了解更多AI Agent技术,参考我们的AI Agent从入门到精通系列
- OpenClaw部署实战,查看OpenClaw一键部署教程
- 向量数据库选型指南,阅读2026年向量数据库对比
总结
AI Agent的记忆系统不是简单的"存数据库",而是需要精心设计的层次化架构:
- 即时感知:理解当前输入 → 用输入解析+意图识别
- 工作记忆:管理上下文窗口 → 智能截断+摘要压缩
- 长期记忆:跨会话知识积累 → 向量数据库+重要性评分
做好这三层,你的Agent将从"金鱼记忆"进化为"过目不忘"的真正智能助手。
实践出真知。现在就给你的Agent加上记忆系统吧!
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论