一文搞懂 AI Agent 的记忆系统:从短期到长期,从本地到向量数据库
TL;DR:AI Agent 为什么能「记住」你之前说的话?背后的记忆系统分为三层:短期记忆(上下文窗口)、长期记忆(向量数据库)、工作记忆(当前会话状态)。本文详解三层记忆的原理、存储方式和代码实现。
1. 为什么 AI Agent 需要记忆系统
对话系统有上下文窗口限制。GPT-4o 最大 128K Tokens,Claude 3 200K Tokens——听起来很大,但一个中型项目的代码库往往超过 100 万 Tokens。
如果每次对话都把所有历史塞进上下文:
- 每次请求的 Token 成本飙升
- 超出上下文上限后无法处理
- 模型注意力分散,效果下降
解决方案:分层记忆系统。
三层记忆架构
用户输入 ↓ ┌─────────────────────────────────────┐ │ Layer 1: 工作记忆(Working Memory) │ │ 当前会话的核心信息,LLM 直接访问 │ └─────────────────────────────────────┘ ↓(压缩 → 存储) ┌─────────────────────────────────────┐ │ Layer 2: 长期记忆(Long-term Memory)│ │ 向量数据库,支持语义检索 │ └─────────────────────────────────────┘ ↓(历史归档) ┌─────────────────────────────────────┐ │ Layer 3: 档案记忆(Archive Memory) │ │ 历史会话归档,冷存储 │ └─────────────────────────────────────┘
2. 第一层:工作记忆(Working Memory)
📌 位置:LLM 上下文窗口
容量:当前模型的最大上下文窗口(如 128K / 200K Tokens)
生命周期:单次对话
工作记忆是 LLM 直接能「看到」的信息。你的 Prompt、历史对话、检索到的内容——都在这里。
工作记忆的管理策略:
2.1 滑动窗口策略
保留最近 N 条对话,旧的自动丢弃:
Python - 滑动窗口实现
class SlidingWindowMemory: def __init__(self, max_messages: int = 20): self.max_messages = max_messages self.messages = [] def add(self, role: str, content: str): self.messages.append({"role": role, "content": content}) # 超出窗口大小时,从旧到新丢弃 if len(self.messages) > self.max_messages: self.messages.pop(0) def get_context(self) -> list: return self.messages def count_tokens(self) -> int: from tiktoken import encoding_for_model enc = encoding_for_model("gpt-4o") return len(enc.encode(" ".join(m["content"] for m in self.messages))) # 使用示例 memory = SlidingWindowMemory(max_messages=10) memory.add("user", "我想开发一个博客系统") memory.add("assistant", "好的,你想要什么技术栈?") memory.add("user", "用 FastAPI + Vue") # 只保留最近 10 条2.2 摘要压缩策略
当对话太长时,用 LLM 压缩历史:
Python - 摘要压缩
async def summarize_and_compress(messages: list, client) -> list: """当 token 超限时,压缩历史对话""" old_messages = messages[:-5] # 保留最近 5 条,其余压缩 summary_prompt = f"""请将以下对话压缩成一个摘要: {messages_to_text(old_messages)} 摘要要求: 1. 保留关键信息(需求、决策、技术选型) 2. 忽略无关细节 3. 输出格式:{key_info: ..., decisions: ..., pending: ...}""" summary_response = await client.chat.completions.create( model="deepseek-ai/DeepSeek-V3", messages=[{"role": "user", "content": summary_prompt}] ) # 压缩后的摘要 + 最近 5 条对话 compressed = [ {"role": "system", "content": f"【会话摘要】{summary_response.choices[0].message.content}"} ] + messages[-5:] return compressed3. 第二层:长期记忆(Long-term Memory)
📌 位置:向量数据库(Qdrant / Chroma / Milvus)
容量:无限制
生命周期:持久化
长期记忆是 AI Agent 的「外部大脑」。当工作记忆不够用时,从长期记忆里检索相关信息,拼进上下文。
3.1 为什么要用向量数据库
普通数据库只能做「精确匹配」(WHERE name = '张三')。
但人类的记忆是「语义」的——你记不住「张三」这个名字,但能记住「那个帮我修过 Bug 的同事」。
向量数据库做的就是这件事:语义检索。你问「帮我回忆一下上周讨论的技术方案」,向量数据库能找到语义相近的历史记录。
3.2 完整记忆系统实现
Python - 完整 Agent 记忆系统
import chromadb import openai from datetime import datetime # ========== 1. 初始化向量数据库 ========== client_db = chromadb.Client() collection = client_db.create_collection("agent_memory") # ========== 2. 嵌入模型 ========== embedding_client = openai.OpenAI( api_key="your-api-key", base_url="https://api.siliconflow.cn/v1" ) def get_embedding(text: str) -> list: response = embedding_client.embeddings.create( model="text-embedding-3-small", input=text ) return response.data[0].embedding # ========== 3. 存储记忆 ========== def store_memory(content: str, metadata: dict): """存储一条记忆到向量数据库""" memory_id = f"memory_{datetime.now().strftime('%Y%m%d_%H%M%S')}" embedding = get_embedding(content) collection.add( ids=[memory_id], embeddings=[embedding], documents=[content], metadatas=[{**metadata, "created_at": datetime.now().isoformat()}] ) print(ff"✅ 已存储记忆:{memory_id}") # ========== 4. 检索记忆 ========== def retrieve_memories(query: str, top_k: int = 5) -> list: """语义检索相关记忆""" query_embedding = get_embedding(query) results = collection.query( query_embeddings=[query_embedding], n_results=top_k ) memories = [] for i, doc in enumerate(results["documents"][0]): memories.append({ "content": doc, "metadata": results["metadatas"][0][i], "score": results["distances"][0][i] }) return memories # ========== 5. 记忆衰减策略 ========== def decay_memories(threshold: float = 0.8): """删除不重要/太久远的记忆,释放空间""" import time all_memories = collection.get() for memory in all_memories["ids"]: metadata = collection.get(where={"id": memory})["metadatas"][0] # 1. 时间衰减:超过 30 天的重要性 -0.5 created = datetime.fromisoformat(metadata["created_at"]) days_old = (datetime.now() - created).days importance = metadata.get("importance", 0.5) - (days_old / 60) if importance < threshold: collection.delete(ids=[memory]) print(ff"🗑️ 删除记忆:{memory}")3.3 自动存储记忆的时机
不是所有对话都要存储。以下几个时机触发存储:
| 触发时机 | 存储内容 | 重要性 |
|---|---|---|
| 用户明确的需求 | 需求描述、决策结论 | ⭐⭐⭐⭐⭐ |
| Agent 执行的关键步骤 | 执行结果、遇到的问题 | ⭐⭐⭐⭐ |
| 代码变更 | 改了什么文件、为什么改 | ⭐⭐⭐⭐⭐ |
| 错误和修复 | Bug 原因、修复方案 | ⭐⭐⭐⭐⭐ |
| 日常闲聊 | 不存储 | — |
4. 第三层:档案记忆(Archive Memory)
📌 位置:本地文件 / 对象存储(S3)
容量:无限制
生命周期:永久归档
档案记忆是「记忆的记忆」——长期记忆经过压缩后,归档到冷存储。
Python - 档案归档
import json import os from datetime import datetime ARCHIVE_DIR = "./memory_archive" def archive_session(session_id: str, messages: list): """归档一个完整的会话到本地文件""" os.makedirs(ARCHIVE_DIR, exist_ok=True) archive_file = f"{ARCHIVE_DIR}/{session_id}_{datetime.now().strftime('%Y%m%d')}.json" with open(archive_file, "w", encoding="utf-8") as f: json.dump({ "session_id": session_id, "archived_at": datetime.now().isoformat(), "messages": messages }, f, ensure_ascii=False, indent=2) print(ff"📦 会话 {session_id} 已归档到 {archive_file}") def load_archive(session_id: str) -> list: """读取归档的会话""" for filename in os.listdir(ARCHIVE_DIR): if filename.startswith(session_id): with open(f"{ARCHIVE_DIR}/{filename}", encoding="utf-8") as f: data = json.load(f) return data["messages"] return []5. 完整 Agent 记忆系统集成
Python - Agent 记忆系统主类
class AgentMemory: def __init__(self): # 三层记忆 self.working = SlidingWindowMemory(max_messages=20) self.longterm = LongTermMemory() # 基于 Chroma self.archive = ArchiveMemory() async def process_message(self, user_input: str, client) -> str: # Step 1: 从长期记忆检索相关内容 relevant_memories = self.longterm.retrieve(user_input) # Step 2: 构建 Prompt(工作记忆 + 相关长期记忆) system_prompt = f"""你是 Agent,你的记忆如下: 【相关长期记忆】 {relevant_memories} """ # Step 3: 调用 LLM response = await client.chat.completions.create( model="deepseek-ai/DeepSeek-V3", messages=[ {"role": "system", "content": system_prompt} ] + self.working.get_context() + [{"role": "user", "content": user_input}] ) answer = response.choices[0].message.content # Step 4: 自动存储重要内容到长期记忆 self.longterm.store_if_important(user_input, answer) # Step 5: 更新工作记忆 self.working.add("user", user_input) self.working.add("assistant", answer) return answer6. 常见问题
Q1:Token 爆炸怎么办?
三层记忆各司其职:工作记忆满了 → 压缩 → 归档到长期记忆 → 定期清理。
Q2:向量数据库选哪个?
| 数据库 | 适用场景 | 推荐度 |
|---|---|---|
| Chroma | 轻量开发/本地 | ⭐⭐⭐⭐⭐ |
| Qdrant | 生产环境/云部署 | ⭐⭐⭐⭐ |
| Milvus | 超大规模数据 | ⭐⭐⭐ |
| Pinecone | 不想运维 | ⭐⭐⭐⭐ |
Q3:隐私数据怎么处理?
向量数据库可以本地部署(如 Chroma/Qdrant),数据不经过第三方服务器。如果对隐私要求极高,建议自建。
7. 总结
| 层级 | 存储 | 容量 | 检索方式 | 生命周期 |
|---|---|---|---|---|
| 工作记忆 | 内存 | 128K-200K Tokens | 直接访问 | 单次会话 |
| 长期记忆 | 向量数据库 | 无限制 | 语义检索 | 持久化 |
| 档案记忆 | 本地文件/S3 | 无限制 | 精确匹配 | 归档 |
三层记忆系统的核心思想:热数据放工作记忆,温数据放长期记忆,冷数据归档。这样既保证了检索速度,又不受上下文窗口限制。
如果对你有帮助,欢迎在评论区聊聊你实现的记忆系统。
