从“金鱼脑”到“过目不忘”:深度解析 AI Agent 的三层记忆系统架构与实战

引言:为什么 AI Agent 需要记忆?

在大语言模型(LLM)爆发的初期,我们与之交互的方式通常是“无状态”的。你输入一个 Prompt,它返回一个 Answer。这种模式下,LLM 就像是一个拥有极其渊博知识,但只有“7秒记忆”的金鱼。一旦对话刷新,它就会把刚才发生的事情忘得一干二净。

然而,当技术的浪潮从“对话助手”迈向“自主智能体”时,这种“无状态”的设计就成了致命的瓶颈。

试想一下,如果你让一个 Agent 帮你规划一次为期一周的日本旅行并预订机票,它如果在执行到预订酒店时,已经忘记了你的预算限制和出发城市,那将是一场灾难。真正的 Agent 必须具备在多轮交互、长时间跨度内保持状态、积累经验并动态调整行为的能力。这就是 AI Agent 的记忆系统。

人类的记忆系统极其复杂,心理学家通常将其分为感觉记忆、短期记忆、工作记忆和长期记忆。借鉴认知心理学,当前的 AI Agent 架构也演化出了一套成熟的记忆范式。本文将深入探讨 AI Agent 的短期记忆长期记忆以及极其关键的工作记忆,并结合主流框架(如 LangChain、LlamaIndex),给出切实可行的架构设计与核心代码实战。


一、 短期记忆:Agent 的“短时抓手”

1.1 什么是短期记忆?

在 AI Agent 的语境下,短期记忆通常指的是当前交互上下文。它保留了 Agent 正在与用户进行的当前对话的历史记录,以及刚刚执行过的动作和观察到的结果。

短期记忆的核心特征是:

  • 容量受限: 直接受限于 LLM 的上下文窗口长度(如 8K, 32K, 128K Tokens)。
  • 瞬时性: 一旦会话结束或上下文窗口被塞满,未经处理的早期信息就会被“遗忘”。
  • 高精度: 由于信息直接存在于 Prompt 中,LLM 对短期记忆的检索和利用精度极高,几乎不存在信息检索带来的“幻觉”损耗。

1.2 短期记忆的底层机制

在主流的 Agent 框架(如 LangChain)中,短期记忆在底层的实现往往是简单的列表或队列。每次调用 LLM 时,框架会将这个列表序列化为字符串拼接到 Prompt 中。

然而,随着对话的拉长,直接保留所有历史记录会导致 Token 爆炸。因此,短期记忆的管理往往需要配合以下策略:

  • 滑动窗口截断: 只保留最近的 KK 轮对话。
  • Token 长度截断: 动态计算历史记录的 Token 数,超出最大限制时移除最早的一条。
  • 对话摘要: 当历史记录过长时,利用另一个小参数 LLM 将早期对话总结成一段百字摘要,替换掉冗长的原文。

1.3 代码实战:基于滑动窗口与摘要的短期记忆

下面是一个使用 LangChain 管理短期记忆的典型例子。我们结合了 ConversationBufferWindowMemory(保留最近K轮)和 ConversationSummaryMemory(总结早期对话)的思想。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from langchain.memory import ConversationBufferWindowMemory, ConversationSummaryMemory
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI

# 初始化大语言模型
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 方案 A:简单的滑动窗口短期记忆 (保留最近 2 轮互动,即 4 条消息)
short_term_memory_window = ConversationBufferWindowMemory(
k=2,
return_messages=True
)

# 方案 B:摘要短期记忆 (适合超长对话,将早期对话压缩)
short_term_memory_summary = ConversationSummaryMemory(
llm=llm,
return_messages=True
)

# 使用滑动窗口记忆构建对话链
conversation = ConversationChain(
llm=llm,
memory=short_term_memory_window,
verbose=True
)

# 模拟连续提问
response1 = conversation.predict(input="你好,我叫张三,我是一名后端开发工程师。")
print(response1)

response2 = conversation.predict(input="我想了解如何学习 AI Agent 开发。")
print(response2)

# 此时短期记忆中只有最近两轮的记录,如果继续问“我刚才说我叫什么名字?”,它可能还能记住。
# 但如果中间再插入几轮其他话题,受限于 k=2,“张三”这个信息就会被从短期记忆中移除。

工程痛点: 短期记忆是脆弱的。一旦超出上下文限制,关键信息就会丢失。为了让 Agent 具备真正的“成长性”,我们需要引入长期记忆。


二、 长期记忆:Agent 的“海马体与大脑皮层”

2.1 什么是长期记忆?

长期记忆负责存储跨越多个会话、甚至跨越数月时间的信息。它是 Agent 了解用户偏好、积累领域知识、记住过去失败教训的核心。

如果 Agent 具备长期记忆,它就能做到:当你时隔一个月再次打开应用时,它仍然记得你喜欢喝冰美式,并且对花生过敏。

长期记忆通常分为两种:

  1. 语义记忆: 客观事实和知识。通常通过向量数据库(Vector Database,如 Chroma, Pinecone, Milvus)实现。
  2. 情景记忆: 过去发生的具体事件和经验。

2.2 向量检索:语义记忆的基石

在工程实现中,Agent 的长期记忆绝大多数依赖于 RAG(检索增强生成)架构

其工作流如下:

  1. 写入: Agent 判断当前对话中包含值得长期保存的信息(如用户的偏好、重要指令)。将其通过 Embedding 模型转化为高维向量,并存入 Vector DB。
  2. 检索: 在下一次新对话开始时,系统将用户的输入同样转化为向量,在 Vector DB 中进行相似度搜索(如余弦相似度),召回最相关的 TopKTop-K 条历史记忆。
  3. 注入: 将召回的长期记忆作为背景上下文,注入到当前的 Prompt 中,辅助 LLM 做出决策。

2.3 长期记忆的高级演化:知识图谱

虽然向量数据库擅长处理语义模糊搜索,但在处理复杂实体关系时(例如“张三的妻子是李四,李四的老板是王五”),纯向量检索往往会丢失逻辑关联。

因此,高级的 Agent 系统开始引入 图数据库(如 Neo4j)作为长期记忆的补充,这就是 LlamaIndex 中非常热门的 Knowledge Graph RAG。通过将文本抽取为节点和边,Agent 的记忆能够进行多跳推理。

2.4 代码实战:基于向量数据库的长期记忆

下面的代码展示了如何使用 LangChain 结合 FAISS(Facebook 开源的向量检索库)和 VectorStoreRetrieverMemory 构建一个具备跨会话记忆的 Agent。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import faiss
from langchain_openai import OpenAIEmbeddings
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import FAISS
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI

# 1. 初始化 Embedding 模型和向量数据库
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 创建一个空的 FAISS 索引
vectorstore = FAISS.from_texts(["初始化记忆"], embeddings, metadatas=[{"source": "system"}])

# 2. 创建检索器 (Top K = 2)
retriever = vectorstore.as_retriever(search_kwargs=dict(k=2))

# 3. 初始化长期记忆模块
long_term_memory = VectorStoreRetrieverMemory(retriever=retriever)

# 存入一些先验的"情景记忆"
long_term_memory.save_context(
{"input": "我最喜欢的食物是意大利面。"},
{"output": "好的,我记住了您喜欢意大利面。"}
)
long_term_memory.save_context(
{"input": "我下周二有一个重要的面试,有点紧张。"},
{"output": "别紧张,祝您下周二面试顺利!"}
)

# 4. 测试长期记忆的检索
# 当我们提问相关问题时,Agent 会从向量库中自动召回相关记忆
print("--- 测试长期记忆检索 ---")
print(long_term_memory.load_memory_variables({"prompt": "下周二我应该做什么准备?"})["history"])
# 输出结果将包含关于"下周二面试"的历史记忆,即使当前对话并没有直接提及。

# 5. 集成到 Agent Chain 中
llm = ChatOpenAI(model="gpt-4o")
# 注意:由于 VectorStoreRetrieverMemory 本身不保留短期上下文,实际工程中通常会组合使用。
# 这里为了演示,我们使用 ConversationChain
conversation = ConversationChain(
llm=llm,
memory=long_term_memory,
verbose=True
)

response = conversation.predict(input="你能给我推荐一家餐厅吗?")
print(response)
# LLM 会根据检索到的记忆(喜欢吃意大利面),推荐意大利餐厅。

三、 工作记忆:Agent 的“草稿纸与中央执行器”

在许多开发者看来,有了短期记忆(上下文)和长期记忆(向量库),Agent 就已经完美了。但在实际的复杂任务执行中,往往会遇到一种“认知过载”的情况。这时,我们需要引入第三层——工作记忆

3.1 短期记忆 vs 工作记忆

这是认知心理学中经常被混淆的两个概念,映射到 AI Agent 中:

  • 短期记忆是“存储”。 它是历史对话的堆栈,是被动存在于 Prompt 里的死文字。
  • 工作记忆是“处理”。 它是 Agent 当前正在思考的黑板草稿纸,或者是控制流程的状态机

工作记忆包含了当前任务的子目标、待办事项列表、中间计算结果,以及决定下一步该做什么的“计划”。

例如,Agent 的任务是“阅读三份财报并总结利润趋势”。

  • 长期记忆提供:Agent 过去学到的财务知识。
  • 短期记忆提供:刚才用户下达指令的原文。
  • 工作记忆维持:当前正在读第几份、前一份提取的利润数字是多少、下一步操作是读取还是计算。

3.2 实现工作记忆的主流架构

工作记忆不是简单的文本拼接,它需要结构化和状态管理。目前主流的实现方案包括:

1. Scratchpad (草稿本) 机制

在 ReAct (Reasoning and Acting) 框架中,Agent 循环生成 Thought(思考)、Action(动作)、Observation(观察)。这三者交替出现在 Prompt 中的专用区域,这块区域就是工作记忆的体现。它记录了问题解决的推理链条。

2. 状态机与状态图

复杂任务往往有多个分支。使用状态图(LangGraph 是目前该领域的王者)可以显式地定义当前 Agent 处于哪个工作节点,哪些数据在节点间传递。这种“图状态”就是最高级的工作记忆。

3. 结构化 JSON / 列表

通过 Function Calling 强制 LLM 输出包含 current_tasktodo_listextracted_data 的 JSON 结构,并在每轮循环中更新这个 JSON,以此模拟人类大脑的执行控制。

3.3 架构设计:基于 LangGraph 的工作记忆实战

LangGraph 通过图结构将 Agent 的状态(即工作记忆)作为节点间的流转数据。下面是一个简化版的“多步骤任务执行”工作记忆流转示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from typing import TypedDict, Annotated, List
import operator
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage

# 1. 定义工作记忆的数据结构
# 这里我们定义了当前任务、待办列表和已收集的信息
class AgentState(TypedDict):
task: str
plan: List[str]
current_step: str
results: Annotated[list[str], operator.add] # 累加收集到的结果

# 初始化 LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 2. 定义节点动作:规划器 (更新工作记忆中的 plan)
def planner(state: AgentState):
task = state['task']
prompt = [
SystemMessage(content="你是一个任务规划专家。将用户任务拆解为3个独立的子步骤。以JSON数组格式返回,不要任何其他文字。"),
HumanMessage(content=f"任务: {task}")
]
response = llm.invoke(prompt)
# 假设返回格式为 '["步骤1", "步骤2", "步骤3"]'
import json
plan = json.loads(response.content.replace("'", "\""))
return {"plan": plan, "current_step": plan[0]}

# 3. 定义节点动作:执行器 (读取工作记忆中的 current_step,并追加 results)
def executor(state: AgentState):
current_step = state['current_step']
# 这里本应是调用工具(如搜索引擎、数据库查询),为简化,直接模拟生成
mock_result = f"执行 '{current_step}' 后获得的结果:数据X=100"
return {"results": [mock_result]}

# 4. 定义路由逻辑:判断工作记忆中的任务是否完成
def should_continue(state: AgentState):
plan = state['plan']
current_step = state['current_step']

# 找到当前步骤在计划中的索引
try:
idx = plan.index(current_step)
except ValueError:
idx = -1

# 如果不是最后一步,更新工作记忆的 current_step 进入下一步循环
if idx < len(plan) - 1 and idx != -1:
return "next"
return "end"

def next_step(state: AgentState):
plan = state['plan']
current_step = state['current_step']
idx = plan.index(current_step)
return {"current_step": plan[idx + 1]}

# 5. 构建 LangGraph 状态图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("planner", planner)
workflow.add_node("executor", executor)
workflow.add_node("next_step", next_step)

# 设置工作流(工作记忆的流转路径)
workflow.set_entry_point("planner")
workflow.add_edge("planner", "executor")
workflow.add_conditional_edges(
"executor",
should_continue,
{
"next": "next_step",
"end": END
}
)
workflow.add_edge("next_step", "executor")

# 编译并运行
app = workflow.compile()

print("---开始执行带有工作记忆的 Agent---")
# 初始化空的 State (工作记忆开始为空白)
initial_state = {"task": "帮我调研目前主流的 AI Agent 框架并做对比", "plan": [], "current_step": "", "results": []}

# 运行图,监控工作记忆的演变
for output in app.stream(initial_state):
for key, value in output.items():
print(f"节点 [ {key} ] 输出的工作记忆变化: {value}")
print("---")

代码解析:
在这个架构中,AgentState 就是 Agent 的工作记忆。它不仅存储原始任务,还动态维护着待办列表(plan)、当前执行焦点(current_step)和中间结果(results)。通过 LangGraph,LLM 不再是无脑地对话,而是按照工作记忆中的状态按部就班地推进任务。这种设计是构建复杂、稳定 Agent 的基石。


四、 融合:构建完整的三层记忆系统架构

一个真正强大的企业级 AI Agent,绝不仅仅依赖单一的记忆模式。它需要像一个真正的人类大脑一样,让短期、长期和工作记忆协同工作。

以下是我们在实际工业落地中总结的标准三层记忆融合架构

  1. 输入感知层: 捕获用户当前的请求。
  2. 路由与检索(长期记忆唤醒):
    • 收到请求后,系统首先将 Query 向量化。
    • 从 Vector DB(长期记忆)和知识图谱中检索相关的历史偏好、文档知识。
  3. 上下文构建(短期记忆填充):
    • 从 Session/Redis 中提取当前会话最近 5 轮的对话(短期记忆)。
  4. 注入工作记忆(中央控制):
    • 将 [用户请求] + [检索到的长期记忆] + [近期对话上下文] 统一打包。
    • 将其送入工作记忆调度器(如 LangGraph 中的 State)。
    • LLM 读取工作记忆,进行推理、调用工具,并动态更新工作记忆中的“待办列表”。
  5. 记忆的沉淀与遗忘(后台异步任务):
    • 任务完成后,工作记忆将重要的“提取结果”或“用户偏好”通过后台异步任务写入向量数据库(转化为长期记忆)。
    • 对于不再相关的历史长期记忆,系统可以定期进行评分和“遗忘”(降低权重或物理删除),避免记忆库变成堆积如山的垃圾场。

记忆管理的高级技巧:反思机制

在高级的 Agent 系统(如 MemGPT 架构)中,Agent 被赋予了“自我反思”的能力。
这意味着 Agent 不是机械地把所有对话都存入长期记忆,而是通过 LLM 进行一道过滤:

  • “用户刚才说他要出门买杯咖啡” -> LLM 判断:这是临时信息,不写入长期记忆。
  • “用户提到他对青霉素严重过敏” -> LLM 判断:这是关键的医疗偏好,主动写入长期记忆,并打上高优先级标签。

这种基于大模型自身的记忆路由和反思机制,是目前 Agent 领域最前沿的研究方向之一。


五、 总结与展望

在本文中,我们从认知心理学的角度出发,深入剖析了 AI Agent 的三层记忆系统:

  1. 短期记忆: 是短时的上下文抓手,负责维持当前会话的连贯性,受限于 Token 长度。
  2. 长期记忆: 是大脑皮层,基于向量数据库和知识图谱,实现跨会话的知识沉淀和个性化体验。
  3. 工作记忆: 是中央执行器和草稿纸,负责在复杂任务中维护当前状态、执行计划和中间结果,通常基于状态机(如 LangGraph)实现。

AI 正在经历从“被动响应的模型”向“主动思考的智能体”的伟大跃迁。如果说 LLM 提供了 Agent 的智商(IQ),工具赋予了 Agent 双手,那么记忆系统则塑造了 Agent 的人格经验(EQ & Experience)

未来,随着模型原生支持 KV Cache 的无限拉长,以及类似 MemGPT 这种分页虚拟内存架构的成熟,Agent 的记忆管理将变得更加智能和无感。作为开发者,深入理解这三层记忆架构的底层逻辑,不仅能让我们在使用 LangChain、LlamaIndex 等框架时游刃有余,更能赋予我们在构建下一代超级智能体时打破天花板的架构视野。