跳转到正文
技术教程·

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;或使用独立的向量数据库服务。

进阶学习

总结

  • 滑动窗口处理短期记忆,简单有效
  • 摘要压缩保留早期信息要点,节省 token
  • 向量检索实现长期记忆的语义检索
  • 实际项目通常三种方案组合使用

---

本文最后更新于 2026-07-27。代码示例基于当前常见版本,请根据最新 API 文档调整。*

常见问题

相关推荐

获取更多 AI 内容

订阅更新,第一时间获取新教程和工具推荐。