AI Agent 记忆管理教程:短期记忆、长期记忆和向量库
AI Agent 记忆管理教程:从对话上下文到长期记忆,教你用滑动窗口、摘要压缩和向量检索三种方式管理 Agent 记忆,解决上下文窗口限制和信息遗忘问题。
这篇教程适合你吗
你在搭 AI Agent,发现聊了几轮后模型就「忘记」了之前说过的话,或者上下文太长导致成本飙升。你需要一套记忆管理系统,让 Agent 既能记住重要信息,又不会浪费 token。
前置知识:了解 AI Agent 基本概念。建议先看 AI Agent 是什么。 最终产物:一套包含短期记忆、长期记忆和向量检索的 Agent 记忆管理方案。为什么需要记忆管理
大模型的上下文窗口是有限的。即使你用 长上下文窗口模型,也有两个问题:
- 成本:token 越多越贵,长对话的费用会快速增长
- 注意力稀释:上下文太长,模型对早期信息的关注度会下降
所以你需要「管理」记忆——决定什么保留、什么压缩、什么检索。
记忆的三种类型
短期记忆(当前对话)
- 最近的对话轮次
- 直接放在上下文窗口里
- 容量有限,用完即丢
工作记忆(当前任务上下文)
- 当前任务的相关信息
- 从长期记忆中检索
- 动态加载
长期记忆(跨会话持久化)
- 用户偏好、历史对话、学到的知识
- 存在数据库中
- 按需检索
方案一:滑动窗口(短期记忆)
最简单的方案——只保留最近 N 轮对话:
class SlidingWindowMemory:
def __init__(self, max_turns: int = 10):
self.max_turns = max_turns
self.messages = []
def add(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
# 超过最大轮数,丢弃最早的
if len(self.messages) > self.max_turns 2:
self.messages = self.messages[-(self.max_turns 2):]
def get_messages(self) -> list:
return self.messages
# 使用
memory = SlidingWindowMemory(max_turns=10)
memory.add("user", "你好")
memory.add("assistant", "你好!有什么可以帮你的?")
# ... 更多对话
# 发送给 LLM 时只取最近的对话
response = client.chat.completions.create(
model="gpt-4o",
messages=memory.get_messages()
)
优点:简单、可控。
缺点:早期信息完全丢失。
方案二:摘要压缩
用 LLM 把旧对话压缩成摘要,节省 token:
class SummaryMemory:
def __init__(self, client, max_recent_turns: int = 5):
self.client = client
self.max_recent_turns = max_recent_turns
self.summary = ""
self.recent_messages = []
def add(self, role: str, content: str):
self.recent_messages.append({"role": role, "content": content})
# 最近对话太多时,压缩旧的
if len(self.recent_messages) > self.max_recent_turns 2:
old_messages = self.recent_messages[:-(self.max_recent_turns 2)]
self.recent_messages = self.recent_messages[-(self.max_recent_turns 2):]
self._compress(old_messages)
def _compress(self, messages: list):
"""用 LLM 压缩旧对话为摘要"""
old_text = "\n".join([f"{m['role']}: {m['content']}" for m in messages])
prompt = f"之前的对话摘要:\n{self.summary}\n\n新的对话内容:\n{old_text}\n\n请生成一个简洁的综合摘要,保留关键信息。"
response = self.client.chat.completions.create(
model="gpt-4o-mini", # 摘要用便宜模型就够了
messages=[{"role": "user", "content": prompt}]
)
self.summary = response.choices[0].message.content
def get_messages(self) -> list:
messages = []
if self.summary:
messages.append({"role": "system", "content": f"之前的对话摘要:\n{self.summary}"})
messages.extend(self.recent_messages)
return messages
优点:保留了早期信息的要点。
缺点:摘要过程会丢失细节;每次压缩都要调用 LLM。
方案三:向量检索(长期记忆)
把对话存入向量库,需要时检索相关片段:
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
class VectorMemory:
def __init__(self):
self.vectorstore = Chroma(
persist_directory="./agent_memory",
embedding_function=OpenAIEmbeddings()
)
self.recent_messages = []
def add(self, role: str, content: str):
self.recent_messages.append({"role": role, "content": content})
# 把对话存入向量库
self.vectorstore.add_texts(
texts=[content],
metadatas=[{"role": role}]
)
# 保持最近对话简短
if len(self.recent_messages) > 10:
self.recent_messages = self.recent_messages[-10:]
def recall(self, query: str, k: int = 3) -> list:
"""根据当前话题检索相关历史记忆"""
results = self.vectorstore.similarity_search(query, k=k)
return [doc.page_content for doc in results]
def get_messages(self, current_query: str) -> list:
messages = []
# 先检索相关记忆
memories = self.recall(current_query)
if memories:
memory_text = "\n".join([f"- {m}" for m in memories])
messages.append({
"role": "system",
"content": f"以下是之前对话中的相关信息:\n{memory_text}"
})
messages.extend(self.recent_messages)
return messages
优点:能检索任意历史信息;语义匹配比关键词更准。
缺点:需要向量数据库;检索有延迟;检索结果可能不完全准确。
组合使用
实际项目中通常组合三种方案:
class HybridMemory:
def __init__(self, client):
self.short_term = SlidingWindowMemory(max_turns=5)
self.long_term = VectorMemory()
def add(self, role: str, content: str):
self.short_term.add(role, content)
self.long_term.add(role, content)
def get_messages(self, current_query: str) -> list:
# 短期记忆(最近对话)+ 长期记忆(相关历史)
messages = self.long_term.get_messages(current_query)
messages.extend(self.short_term.get_messages())
return messages
记忆的生命周期
新对话 → 短期记忆(滑动窗口)
↓ 超出窗口
摘要压缩 → 保存摘要
↓
向量存储 → 长期记忆
↓ 需要时
语义检索 → 加载到工作记忆
常见问题与排错
检索到不相关的内容
原因:向量相似度不等于语义相关度。 解决:在检索后加一层 LLM 过滤,判断检索到的内容是否真的和当前话题相关。记忆占用太多 token
原因:检索了太多历史片段。 解决:限制检索数量(k=2-3);对检索结果做摘要压缩再放入上下文。跨会话记忆丢失
原因:向量数据库没有持久化。 解决:确保 Chroma 设置了persist_directory;或使用独立的向量数据库服务。
进阶学习
- 想了解 Agent 概念?看 AI Agent 是什么
- 想了解上下文窗口?看 大模型上下文窗口是什么
- 想了解向量数据库?看 向量数据库是什么
- 想搭建多 Agent 系统?看 多 Agent 协作教程
总结
- 滑动窗口处理短期记忆,简单有效
- 摘要压缩保留早期信息要点,节省 token
- 向量检索实现长期记忆的语义检索
- 实际项目通常三种方案组合使用
---
本文最后更新于 2026-07-27。代码示例基于当前常见版本,请根据最新 API 文档调整。*
常见问题
相关推荐
AI Agent 是什么?从实际工作场景理解智能体
AI Agent 是什么?从实际开发经验出发,解释 Agent 的工作原理、与普通 AI 的区别、主流框架选择,以及落地时的真实边界。
大模型上下文窗口是什么?长文本能力到底影响什么
大模型上下文窗口是什么?解释上下文窗口的概念、大小对模型能力的影响,以及如何根据任务选择合适的上下文长度。
向量数据库是什么?为什么 RAG 和 Agent 都需要它
向量数据库是什么?从实际项目需求出发,解释向量数据库解决什么问题、和传统数据库的区别、主流产品怎么选,以及什么场景不需要它。
AI 工作流是什么?Agent、自动化和低代码平台的关系
AI 工作流是什么?解释 AI 工作流的概念、与传统自动化的区别,以及 Dify、Coze 等平台如何构建 AI 工作流。
获取更多 AI 内容
订阅更新,第一时间获取新教程和工具推荐。