2026年AI Agent记忆架构设计完全指南
2026年AI Agent记忆架构设计完全指南
如果你在2026年还在把AI Agent当成"无状态的一问一答",那你已经落后了。现实是:记忆系统才是AI Agent真正的瓶颈。大模型本身的能力已经足够强大,但一个没有记忆的Agent,就像一个失忆的天才——每次对话都要从零开始,永远无法积累经验、形成偏好、理解上下文。
2025年下半年开始,业界对Agent记忆架构的关注度急剧上升。LangGraph推出了原生的Memory模块,MemGPT项目正式并入LangChain生态,各大厂商纷纷发布自己的Agent记忆方案。本文将系统性地拆解AI Agent的四种记忆类型,给出完整的LangGraph实现代码,并分享生产环境中的实战经验。
为什么记忆是Agent的核心瓶颈?
先看一组数据对比:
| 记忆类型 | 容量 | 持久性 | 检索延迟 | 典型实现 |
|---|---|---|---|---|
| 感知记忆 | 极小(当前输入) | 毫秒级 | ~1ms | 原始输入缓冲 |
| 工作记忆 | 小(4-32K tokens) | 会话级 | ~10ms | 对话历史窗口 |
| 情景记忆 | 中(事件片段) | 天-月级 | ~50ms | 向量数据库+时间索引 |
| 长期记忆 | 大(知识+偏好) | 永久级 | ~100ms | 向量数据库+知识图谱 |
一个成熟的Agent系统必须同时管理这四种记忆,并在它们之间高效地流转信息。接下来我们逐一拆解。
一、感知记忆(Sensory Memory)
感知记忆是Agent接收原始输入的第一层缓冲。它的作用类似于人类的感官记忆——短暂地保留原始信号,供后续模块提取特征。
核心特点:
- 生命周期极短,通常只在一个推理步骤内有效
- 保留原始输入的完整信息(文本、图像、音频等)
- 不做任何压缩或抽象
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Optional
@dataclass
class SensoryMemory:
raw_input: Any
input_type: str # "text", "image", "audio", "multimodal"
timestamp: datetime = field(default_factory=datetime.now)
metadata: dict = field(default_factory=dict)
def extract_features(self) -> dict:
if self.input_type == "text":
return {
"length": len(self.raw_input),
"has_code": "```" in self.raw_input,
"language_hint": self._detect_language(),
}
return {}
def _detect_language(self) -> str:
chinese_chars = sum(1 for c in self.raw_input if '\u4e00' <= c <= '\u9fff')
if chinese_chars / max(len(self.raw_input), 1) > 0.3:
return "zh"
return "en"
感知记忆通常不需要持久化,但建议在调试模式下保留原始输入的哈希值,方便问题追溯。
二、工作记忆(Working Memory)
工作记忆是Agent当前推理的"草稿纸",对应对话上下文窗口。2026年的关键挑战是:如何在有限的token预算内,保留最相关的信息?
策略对比:
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 滑动窗口 | 保留最近N轮对话 | 简单高效 | 丢失早期重要信息 |
| 摘要压缩 | 对旧对话生成摘要 | 节省token | 摘要可能丢失细节 |
| 重要性评分 | 按重要性选择性保留 | 精准 | 需要额外LLM调用 |
| 混合策略 | 摘要+滑动窗口 | 兼顾效率与质量 | 实现复杂度较高 |
推荐:混合策略——对最近3轮保持原文,3-10轮生成摘要,10轮以上只保留关键决策点。
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
from langgraph.graph.message import MessagesState
class WorkingMemoryManager:
def __init__(self, llm, recent_window: int = 3, summary_window: int = 10):
self.llm = llm
self.recent_window = recent_window
self.summary_window = summary_window
self._summary_cache: str = ""
def compress(self, messages: list) -> list:
if len(messages) <= self.recent_window:
return messages
recent = messages[-self.recent_window:]
older = messages[:-self.recent_window]
if len(older) > self.summary_window:
key_decisions = [m for m in older if self._is_key_decision(m)]
to_summarize = older[-self.summary_window:]
else:
key_decisions = []
to_summarize = older
if to_summarize:
self._summary_cache = self._generate_summary(to_summarize)
result = []
if self._summary_cache:
result.append(SystemMessage(content=f"[对话摘要] {self._summary_cache}"))
result.extend(key_decisions)
result.extend(recent)
return result
def _is_key_decision(self, message) -> bool:
keywords = ["决定", "确认", "选择", "decided", "confirmed", "chose"]
return any(kw in message.content for kw in keywords)
def _generate_summary(self, messages: list) -> str:
conversation = "\n".join(
f"{'用户' if isinstance(m, HumanMessage) else '助手'}: {m.content}"
for m in messages
)
prompt = f"请用2-3句话总结以下对话的关键信息:\n{conversation}"
return self.llm.invoke(prompt).content
三、情景记忆(Episodic Memory)
情景记忆记录Agent的"经历"——特定事件、交互结果和上下文片段。它让Agent能回忆起"上次用户遇到类似问题时,我是怎么解决的"。
设计要点:
- 每条记录包含:事件描述、时间戳、上下文、结果、相关度评分
- 检索时同时考虑语义相似度和时间衰减
- 定期合并相似事件,避免冗余
from datetime import datetime, timedelta
import math
@dataclass
class EpisodicRecord:
event: str
context: str
outcome: str
timestamp: datetime
importance: float = 0.5
embedding: list[float] = field(default_factory=list)
class EpisodicMemory:
def __init__(self, vector_store, time_decay_factor: float = 0.1):
self.vector_store = vector_store
self.time_decay_factor = time_decay_factor
async def store(self, record: EpisodicRecord):
record.embedding = await self.vector_store.embed(record.event)
await self.vector_store.add(
text=record.event,
embedding=record.embedding,
metadata={
"context": record.context,
"outcome": record.outcome,
"timestamp": record.timestamp.isoformat(),
"importance": record.importance,
}
)
async def recall(self, query: str, top_k: int = 5) -> list[EpisodicRecord]:
query_embedding = await self.vector_store.embed(query)
results = await self.vector_store.search(query_embedding, top_k=top_k * 2)
now = datetime.now()
scored = []
for r in results:
ts = datetime.fromisoformat(r.metadata["timestamp"])
days_ago = (now - ts).days
time_score = math.exp(-self.time_decay_factor * days_ago)
importance = r.metadata.get("importance", 0.5)
final_score = r.score * time_score * importance
scored.append((final_score, r))
scored.sort(key=lambda x: x[0], reverse=True)
return [r for _, r in scored[:top_k]]
四、长期记忆(Long-term Memory)
长期记忆是Agent的"知识库+人格",包含用户偏好、领域知识和行为模式。这是最复杂也最有价值的记忆类型。
三种长期记忆子类型:
| 子类型 | 内容 | 更新频率 | 示例 |
|---|---|---|---|
| 语义记忆 | 事实性知识 | 低 | "Python用缩进表示代码块" |
| 程序记忆 | 技能和流程 | 中 | "用户喜欢先看示例再看解释" |
| 偏好记忆 | 用户个性化设置 | 高 | "用户偏好中文回复" |
@dataclass
class LongTermMemoryEntry:
content: str
memory_type: str # "semantic", "procedural", "preference"
confidence: float
last_accessed: datetime
access_count: int = 0
source: str = "learned" # "learned", "explicit", "inferred"
class LongTermMemory:
def __init__(self, vector_store, knowledge_graph=None):
self.vector_store = vector_store
self.knowledge_graph = knowledge_graph
self._cache: dict[str, LongTermMemoryEntry] = {}
async def learn(self, entry: LongTermMemoryEntry):
embedding = await self.vector_store.embed(entry.content)
await self.vector_store.add(
text=entry.content,
embedding=embedding,
metadata={
"memory_type": entry.memory_type,
"confidence": entry.confidence,
"source": entry.source,
}
)
if self.knowledge_graph and entry.memory_type == "semantic":
await self.knowledge_graph.add_fact(entry.content)
async def retrieve(self, query: str, memory_types: list[str] = None) -> list:
filters = {}
if memory_types:
filters["memory_type"] = {"$in": memory_types}
results = await self.vector_store.search(
await self.vector_store.embed(query),
filters=filters,
top_k=10,
)
return results
async def consolidate(self):
entries = await self.vector_store.get_all()
groups = self._group_similar(entries, threshold=0.92)
for group in groups:
if len(group) > 1:
merged = self._merge_entries(group)
for old in group:
await self.vector_store.delete(old.id)
await self.learn(merged)
完整LangGraph实现
下面是一个整合四种记忆的完整Agent实现:
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import MessagesState
from langgraph.checkpoint.memory import MemorySaver
from langchain_openai import ChatOpenAI
class AgentMemoryState(MessagesState):
sensory: SensoryMemory
episodic_results: list
long_term_results: list
user_preferences: dict
def perceive(state: AgentMemoryState) -> dict:
last_message = state["messages"][-1]
sensory = SensoryMemory(
raw_input=last_message.content,
input_type="text",
)
return {"sensory": sensory}
def recall_memories(state: AgentMemoryState, config: dict) -> dict:
query = state["sensory"].raw_input
user_id = config["configurable"]["user_id"]
episodic_memory = config["configurable"]["episodic_memory"]
long_term_memory = config["configurable"]["long_term_memory"]
episodic_results = await episodic_memory.recall(query, top_k=3)
long_term_results = await long_term_memory.retrieve(
query, memory_types=["preference", "procedural"]
)
user_prefs = await long_term_memory.retrieve(
"user preferences", memory_types=["preference"]
)
return {
"episodic_results": episodic_results,
"long_term_results": long_term_results,
"user_preferences": {r.text: r.metadata for r in user_prefs},
}
def generate_response(state: AgentMemoryState, config: dict) -> dict:
llm = config["configurable"]["llm"]
working_memory_mgr = config["configurable"]["working_memory_mgr"]
compressed = working_memory_mgr.compress(state["messages"])
memory_context = ""
if state.get("episodic_results"):
memory_context += "\n[相关历史经验]\n"
for r in state["episodic_results"][:3]:
memory_context += f"- {r.text} → {r.metadata.get('outcome', '')}\n"
if state.get("long_term_results"):
memory_context += "\n[相关知识]\n"
for r in state["long_term_results"][:3]:
memory_context += f"- {r.text}\n"
enhanced_messages = []
if memory_context:
enhanced_messages.append(SystemMessage(content=memory_context))
enhanced_messages.extend(compressed)
response = llm.invoke(enhanced_messages)
return {"messages": [response]}
def store_experience(state: AgentMemoryState, config: dict) -> dict:
episodic_memory = config["configurable"]["episodic_memory"]
query = state["messages"][-2].content if len(state["messages"]) >= 2 else ""
response = state["messages"][-1].content
record = EpisodicRecord(
event=query,
context=state.get("sensory", {}).raw_input if state.get("sensory") else "",
outcome=response,
timestamp=datetime.now(),
importance=0.5,
)
await episodic_memory.store(record)
return {}
def build_memory_agent():
graph = StateGraph(AgentMemoryState)
graph.add_node("perceive", perceive)
graph.add_node("recall", recall_memories)
graph.add_node("respond", generate_response)
graph.add_node("store", store_experience)
graph.add_edge(START, "perceive")
graph.add_edge("perceive", "recall")
graph.add_edge("recall", "respond")
graph.add_edge("respond", "store")
graph.add_edge("store", END)
checkpointer = MemorySaver()
return graph.compile(checkpointer=checkpointer)
记忆持久化与向量存储
生产环境中,记忆必须持久化到外部存储。以下是使用Chroma和PostgreSQL的实现方案:
import chromadb
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
import asyncpg
class PersistentMemoryStore:
def __init__(self, chroma_path: str, pg_dsn: str):
self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
self.chroma = Chroma(
persist_directory=chroma_path,
embedding_function=self.embeddings,
)
self.pg_dsn = pg_dsn
async def init_pg(self):
self.pg_pool = await asyncpg.create_pool(self.pg_dsn)
await self.pg_pool.execute("""
CREATE TABLE IF NOT EXISTS agent_memory (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL,
memory_type TEXT NOT NULL,
content TEXT NOT NULL,
importance FLOAT DEFAULT 0.5,
created_at TIMESTAMPTZ DEFAULT NOW(),
accessed_at TIMESTAMPTZ DEFAULT NOW(),
access_count INT DEFAULT 0,
metadata JSONB DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_memory_user_type
ON agent_memory(user_id, memory_type);
CREATE INDEX IF NOT EXISTS idx_memory_accessed
ON agent_memory(accessed_at DESC);
""")
async def save(self, user_id: str, memory_type: str, content: str,
importance: float = 0.5, metadata: dict = None):
await self.pg_pool.execute(
"""INSERT INTO agent_memory
(user_id, memory_type, content, importance, metadata)
VALUES ($1, $2, $3, $4, $5)""",
user_id, memory_type, content, importance,
json.dumps(metadata or {})
)
await self.chroma.aadd_texts(
texts=[content],
metadatas=[{"user_id": user_id, "type": memory_type}],
)
async def search(self, user_id: str, query: str, top_k: int = 5) -> list:
results = await self.chroma.asimilarity_search(
query, k=top_k,
filter={"user_id": user_id}
)
await self.pg_pool.execute(
"""UPDATE agent_memory SET accessed_at = NOW(), access_count = access_count + 1
WHERE user_id = $1 AND content = ANY($2)""",
user_id, [r.page_content for r in results]
)
return results
5个常见陷阱
| # | 陷阱 | 后果 | 解决方案 |
|---|---|---|---|
| 1 | 把所有对话历史当工作记忆 | Token超限、成本飙升 | 使用混合压缩策略 |
| 2 | 忽略记忆的时间衰减 | 检索到过时信息 | 加入指数时间衰减因子 |
| 3 | 长期记忆不做合并 | 冗余记忆堆积 | 定期执行consolidate |
| 4 | 向量检索不考虑用户隔离 | 用户A看到用户B的记忆 | 所有查询加user_id过滤 |
| 5 | 情景记忆和长期记忆混淆 | 该记住的没记住 | 严格区分事件性vs知识性 |
10个常见错误排查
| # | 错误现象 | 可能原因 | 排查方法 |
|---|---|---|---|
| 1 | Agent"忘记"了之前的对话 | 工作记忆窗口太小 | 检查recent_window和summary_window配置 |
| 2 | 检索到不相关的记忆 | Embedding模型不匹配 | 确认存储和检索使用同一模型 |
| 3 | 记忆检索延迟过高 | 向量库索引未优化 | 检查HNSW参数,考虑量化 |
| 4 | Chroma数据丢失 | 未调用persist() | 确认persist_directory配置正确 |
| 5 | PostgreSQL连接池耗尽 | 未限制并发数 | 配置asyncpg.create_pool(max_size=20) |
| 6 | 长期记忆越存越多 | 缺少consolidate | 设置定时任务执行合并 |
| 7 | 用户偏好不生效 | 偏好检索未加入prompt | 检查generate_response中是否注入偏好 |
| 8 | 跨会话记忆丢失 | Checkpointer未持久化 | 使用SqliteSaver或PostgresSaver |
| 9 | 记忆内容包含敏感信息 | 未做脱敏处理 | 存储前执行PII检测和脱敏 |
| 10 | LangGraph状态序列化失败 | 自定义对象不可pickle | 使用dataclass或Pydantic模型 |
高级优化技巧
1. 分层缓存
对高频访问的记忆加LRU缓存,避免每次都查向量库:
from functools import lru_cache
@lru_cache(maxsize=256)
def get_user_preferences(user_id: str) -> dict:
return await long_term_memory.retrieve(
"user preferences", memory_types=["preference"]
)
2. 异步预加载
在用户发起请求前,预加载其长期记忆到缓存:
async def preload_user_memory(user_id: str):
prefs = await long_term_memory.retrieve("preferences", memory_types=["preference"])
cache.set(f"prefs:{user_id}", prefs, ttl=3600)
3. 记忆评分衰减
对长期不访问的记忆降低检索权重,模拟人类遗忘曲线:
def compute_relevance(entry, current_time):
days_since_access = (current_time - entry.last_accessed).days
access_bonus = math.log1p(entry.access_count)
time_decay = math.exp(-0.05 * days_since_access)
return entry.importance * access_bonus * time_decay
4. 多模态记忆
2026年的Agent需要处理文本、图像、音频等多种模态的记忆。使用统一的embedding空间进行跨模态检索:
from langchain_openai import OpenAIEmbeddings
multimodal_embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
工具推荐
在构建Agent记忆系统的过程中,以下工具可以帮你处理数据格式和编码问题:
- JSON格式化工具 — 处理记忆元数据的JSON序列化和调试,确保存储结构正确
- Base64编码工具 — 对二进制记忆数据(如图像embedding)进行编码传输
- 哈希计算工具 — 为记忆条目生成唯一指纹,用于去重和变更检测
总结:AI Agent的记忆架构不是"锦上添花",而是"不可或缺"。四种记忆类型各有分工——感知记忆抓输入,工作记忆管推理,情景记忆记经历,长期记忆存知识。用LangGraph的StateGraph把它们串起来,配上向量库做持久化,加上时间衰减和合并策略做优化,你就拥有了2026年最前沿的Agent记忆系统。记住:一个有记忆的Agent,才是一个真正的Agent。
本站提供浏览器本地工具,免注册即可试用 →