人类之所以能够进行复杂的推理、持续的学习并完成长周期的任务,是因为我们拥有极其精密的记忆系统。当我们解一道数学题时,我们会记住中间的计算结果;当我们与他人交谈时,我们会记得五分钟前说过的话;当我们面对困难时,我们会调取多年前学到的知识。
对于当前火爆的 AI Agent(人工智能体)而言,大语言模型(LLM)就是它的“大脑”,而记忆系统则是赋予这个大脑连续性、_context(上下文)和学习能力的“灵魂”。没有记忆的 Agent,就像是一个患有严重失忆症的天才,每次对话都只能从零开始。
构建一个高质量的 AI Agent,其核心挑战往往不在于让 LLM 写出更华丽的辞藻,而在于如何优雅、高效地管理和调度记忆。本文将带你深入剖析 AI Agent 的三大核心记忆机制:短期记忆、长期记忆,以及常常被忽视但至关重要的工作记忆,并配合实战代码,揭示如何构建一个真正“长情”且高效的智能体。
一、 记忆系统的演进:从“金鱼脑”到“长情”的 Agent
在深入技术细节之前,我们需要理解为什么 Agent 需要复杂的记忆系统。
大模型的基础推理单位是 Token,模型本身是无状态的。你发给它的 Prompt,就是它所知的一切。这种机制导致了几个致命问题:
- 上下文窗口限制:即使目前主流模型的上下文已经达到 128K 甚至 1M Token,也无法容纳企业级知识库或长达数月的交互记录。
- 幻觉与失忆:当对话过长,模型会“遗忘”早期的设定,甚至产生幻觉。
- 缺乏演进能力:无状态的模型无法从过去的错误中学习,每次交互都在“原地踏步”。
为了解决这些问题,我们借鉴认知心理学中的人类记忆模型,为 AI Agent 构建了多级存储体系。
二、 短期记忆:Agent 的“瞬时直觉”
定义与概念
短期记忆主要负责存储当前会话上下文中的信息。它类似于人类在聊天时脑海中短暂保留的几个关键词。对于 AI Agent 来说,短期记忆的载体通常就是 LLM 的 上下文窗口。
技术特征与挑战
- 容量受限:受限于 Token 限制。
- 易失性:一旦会话结束(关闭浏览器或清除 Session),短期记忆就会清空。
- 注意力衰减:著名的“迷失在中间”问题。研究表明,当 Prompt 过长时,LLM 对上下文中间部分的信息提取能力会显著下降。
工程实现方案
在实际工程中,维护短期记忆最直观的方式是对话历史列表。但在多轮对话后,我们不能盲目地将所有历史塞入 Prompt,而是需要采用滑动窗口结合滚动摘要的策略。
代码示例:基于滑动窗口与摘要的短期记忆管理
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
| from typing import List, Dict import tiktoken
class ShortTermMemory: def __init__(self, max_tokens: int = 4000, model: str = "gpt-3.5-turbo"): self.history: List[Dict[str, str]] = [] self.max_tokens = max_tokens self.encoding = tiktoken.encoding_for_model(model) def count_tokens(self, messages: List[Dict[str, str]]) -> int: """粗略计算消息列表的 Token 数""" num_tokens = 0 for message in messages: num_tokens += 4 for key, value in message.items(): num_tokens += len(self.encoding.encode(value)) return num_tokens
def add_message(self, role: str, content: str): """添加新消息""" self.history.append({"role": role, "content": content}) self._trim_history() def _trim_history(self): """当超过最大 Token 限制时,裁剪历史记录""" system_messages = [m for m in self.history if m['role'] == 'system'] conversational_messages = [m for m in self.history if m['role'] != 'system'] while self.count_tokens(system_messages + conversational_messages) > self.max_tokens and len(conversational_messages) > 1: conversational_messages.pop(0) self.history = system_messages + conversational_messages
def get_context(self) -> List[Dict[str, str]]: """获取当前可用的短期记忆上下文""" return self.history
|
工程避坑指南:
单纯依靠截断历史会丢失重要信息。更高级的做法是引入 **Memory Reflection(记忆反思)**机制:当历史即将超出限制时,提取早期的对话,让 LLM 生成一段包含关键信息的摘要(例如:“用户之前询问了关于Python的问题,并表示他是一名后端初学者”),并将摘要注入到 System Prompt 中,从而实现“无损压缩”。
三、 长期记忆:Agent 的“终极知识库”
定义与概念
长期记忆用于跨会话、跨时间段地保存信息。它是 Agent 能够记住“老用户”的喜好,或者掌握企业内部海量私有数据的关键。如果说短期记忆是内存(RAM),那么长期记忆就是硬盘(ROM/SSD)。
认知科学视角的分类
在认知心理学中,长期记忆被细分为几类,这在 AI Agent 中同样适用:
- 陈述性记忆:事实、概念和事件。
- AI 映射:基于 RAG(检索增强生成)的向量数据库、知识图谱。
- 程序性记忆:如何做事的技能(如骑自行车)。
- AI 映射:Agent 掌握的工具使用流程(Tool Calls)、微调好的模型权重或预设的 SOP(标准操作程序)。
技术特征与挑战
- 海量存储:几乎可以存储无限的文本、向量或键值对。
- 检索难度(召回率与精确度):如何从海量记忆中精准地找到当前需要的部分,是长期记忆设计的核心痛点。
- 持久化:依赖于外部数据库(如 PostgreSQL, Pinecone, Milvus, Neo4j)。
工程实现方案:RAG 与向量检索
现代 Agent 的长期记忆几乎无一例外地依赖 向量数据库。Agent 将需要记住的文本切分、转化为高维向量并存储。在需要回忆时,根据当前上下文的相似度进行检索。
代码示例:基于向量数据库的长期记忆
以下代码展示了如何用 ChromaDB(一个轻量级的向量数据库)构建一个 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
| import chromadb from chromadb.utils import embedding_functions
class LongTermMemory: def __init__(self, collection_name: str = "agent_memory"): self.client = chromadb.Client() self.embedder = embedding_functions.SentenceTransformerEmbeddingFunction(model_name="all-MiniLM-L6-v2") self.collection = self.client.get_or_create_collection( name=collection_name, embedding_function=self.embedder ) def memorize(self, text: str, metadata: dict = None, doc_id: str = None): """将知识/经历存入长期记忆""" if doc_id is None: doc_id = f"mem_{hash(text)}" self.collection.add( documents=[text], metadatas=[metadata if metadata else {}], ids=[doc_id] ) print(f"✅ 知识已存入长期记忆: {text[:30]}...")
def recall(self, query: str, top_k: int = 3) -> list: """根据当前情境,从长期记忆中检索最相关的信息""" results = self.collection.query( query_texts=[query], n_results=top_k ) recalled_memories = [] if results and results['documents']: for doc in results['documents'][0]: recalled_memories.append(doc) return recalled_memories
ltm = LongTermMemory()
ltm.memorize("用户喜欢用 Python 写后端,并且习惯使用 FastAPI 框架,不喜欢 Django。", metadata={"user_id": "user_123", "type": "preference"})
print("检索结果:", ltm.recall("我应该推荐什么 Web 框架给这个用户?"))
|
进阶思考:遗忘机制
人类之所以能高效思考,不仅因为我们能“记住”,更因为我们能“遗忘”。高级 Agent 系统需要引入记忆衰减机制。可以通过在数据库中为每条记忆增加 timestamp 和 access_count,每次检索时计算权重(例如:时间越久远且从未被检索过的记忆,得分越低),从而让 Agent 逐渐“忘掉”不重要的细枝末节。
四、 工作记忆:Agent 的“草稿本”与“执行引擎”
定义与概念
工作记忆是认知心理学中一个极其重要的概念。它不同于短期记忆(仅仅存储信息),工作记忆负责在执行复杂任务时,临时保存和处理(计算、推理)信息。
在 AI Agent 的语境下,工作记忆是 Agent 在执行某一个具体任务循环(Thought -> Action -> Observation)期间,保持和更新其行动计划、中间状态和工具执行结果的地方。
如果缺乏工作记忆,Agent 在进行需要多步推理的任务(如解数独、规划复杂的旅行路线、编写并运行代码)时,就会出现“想到后面忘了前面”的逻辑断裂。
技术特征与挑战
- 动态读写:随着 Agent 的每一步行动(Step)不断被覆写和更新。
- 结构化:不仅是文本,更包含状态机、待办列表、环境变量等。
- 容量极小但极度重要:它是 LLM 进行上下文学习的直接抓手。
工程实现方案:Scratchpad 与状态机
工作记忆在工程实现上,往往表现为 Agent 的 Scratchpad(草稿本) 或 黑板系统。在 ReAct (Reasoning and Acting) 框架中,Agent 一步步的推理过程和工具调用的结果,就被记录在工作记忆中。
代码示例:构建一个带有工作记忆的任务执行器
下面的代码演示了工作记忆如何在 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
| from pydantic import BaseModel, Field from typing import List, Optional
class TaskStep(BaseModel): step_id: int thought: Optional[str] = None action: Optional[str] = None observation: Optional[str] = None is_completed: bool = False
class WorkingMemory(BaseModel): """Agent 的工作记忆,用于追踪当前复杂任务的分解与执行状态""" overall_goal: str = Field(..., description="最终要达成的目标") task_plan: List[TaskStep] = [] current_step_index: int = 0
def formulate_plan(self, steps: List[str]): """Agent 将大目标拆解为小步骤""" self.task_plan = [TaskStep(step_id=i, action=step) for i, step in enumerate(steps)] def update_thought(self, thought: str): """记录当前步骤的思考""" if self.current_step_index < len(self.task_plan): self.task_plan[self.current_step_index].thought = thought def record_observation(self, observation: str): """记录工具执行后的环境反馈""" if self.current_step_index < len(self.task_plan): self.task_plan[self.current_step_index].observation = observation self.task_plan[self.current_step_index].is_completed = True self.current_step_index += 1
def get_context_for_prompt(self) -> str: """将当前的工作记忆状态转化为 LLM 可以理解的 Prompt""" context = f"当前最终目标: {self.overall_goal}\n\n执行状态:\n" for step in self.task_plan: status = "✅" if step.is_completed else "⏳" context += f"{status} Step {step.step_id + 1}: {step.action}\n" if step.thought: context += f" - 思考: {step.thought}\n" if step.observation: context += f" - 结果: {step.observation}\n" if self.current_step_index < len(self.task_plan): context += f"\n下一步你需要执行: Step {self.current_step_index + 1}" else: context += "\n所有步骤已完成,请总结最终答案。" return context
wm = WorkingMemory(overall_goal="帮我查询北京的天气,并推荐适合今天穿的衣服。")
wm.formulate_plan(["调用天气API查询北京今日天气", "根据天气情况分析温度和风力", "根据分析结果推荐穿搭"])
wm.update_thought("需要获取天气信息,准备调用 get_weather 工具。") wm.record_observation("北京,晴,气温 5℃,风力 3 级。")
print(wm.get_context_for_prompt())
|
为什么工作记忆如此关键?
大模型在没有提示的情况下,往往不具备良好的系统二(System 2)慢思考能力。通过强制模型将推理过程和中间变量写入工作记忆,我们实际上是在引导模型进行思维链推理,这极大地降低了模型在复杂任务中的幻觉率和逻辑错误率。
五、 融会贯通:构建三位一体的记忆架构
单一的记忆机制无法支撑起一个强大的 Agent。真正的企业级 AI Agent(如 Devin, AutoGPT 等)往往是一个融合了三种记忆的精密系统。
让我们通过一个实际的业务场景,来看看这三种记忆是如何协同工作的:
场景:Agent 化身资深私人健康助理。
-
用户首次交互:
- 用户说:“我今天跑了5公里,感觉很累。另外,我对花生过敏。”
- 短期记忆 (STM) 负责维持这轮对话的上下文,让 Agent 能够回答“跑步后吃什么好”。
- 同时,Agent 识别出重要信息(过敏史),调用内部逻辑,将其存入 长期记忆 (LTM) 的向量数据库中。
-
几个月后,用户再次发起交互:
- 用户说:“我想吃点坚果补充脂肪。”
- 长期记忆 (LTM) 被触发,Agent 通过检索用户的喜好和历史,发现了“对花生过敏”的记忆,并在回答前注入上下文:“考虑到您对花生过敏,建议您选择杏仁或核桃…”。
-
执行复杂任务:
- 用户继续说:“帮我制定一个下周的无花生减脂食谱,并自动去超市 APP 下单。”
- 这是一个复杂任务,工作记忆 (WM) 开始发挥作用。
- Agent 在工作记忆中写下计划:Step 1: 查询减脂食谱 -> Step 2: 剔除含花生成分 -> Step 3: 提取食材列表 -> Step 4: 调用超市API下单。
- 在执行过程中,工具调用的结果(比如“超市API显示缺货牛奶”)会被写入工作记忆,Agent 据此调整下一步行动。
系统架构全景图
你可以将这三种记忆的协同抽象为以下的工作流:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| [用户输入] | v +-----------------------------------------+ | Controller (LLM 大脑) | +-----------------------------------------+ | | ^ v v | [短期记忆] ---> [工作记忆] ---> 组装 Prompt (对话历史) (当前任务状态) | ^ | | v +------------ <检索> --------- [长期记忆] (Vector DB / KG)
|
在每一个 Tick(循环)中:
- Agent 从短期记忆中提取最近的对话。
- 从长期记忆中检索与当前话题相关的久远知识。
- 将上述信息与当前的任务进度(工作记忆)合并,组装成巨大的 Prompt。
- LLM 思考后,生成回复或工具调用,并更新工作记忆与短期记忆。
六、 总结与未来展望
AI Agent 正在从“好玩的玩具”向“有用的生产力工具”演进。这个演进的核心驱动力,正是记忆系统的成熟。
- 短期记忆让 Agent 能够在单次对话中保持连贯,目前面临着上下文窗口利用率与有效信息提取的挑战。
- 长期记忆让 Agent 拥有了跨会话的经验和知识积累,目前的主流解法是基于 Embedding 的 RAG,并在向知识图谱(GraphRAG)等更复杂的结构化记忆发展。
- 工作记忆让 Agent 能够胜任复杂的逻辑推理和多步骤规划,是系统二(System 2)思考的基石。
未来趋势:主动遗忘与记忆重构
在未来的 Agent 系统中,工程师们不仅要关注“如何记住”,更要关注“如何忘记”。如同人脑在睡眠期间进行的记忆巩固一样,高级 Agent 将会在空闲时间进行记忆整理:
- 将短期记忆中的废话丢弃。
- 将反复出现的规律抽象为常识写入权重。
- 合并矛盾的长期记忆。
当 Agent 能够像人类一样自然地记住老朋友、总结过去的错误、并在专注解题时充分利用草稿纸时,真正的通用人工智能(AGI)也许就不再遥远。
构建一个好的记忆系统,本质上是在构建 Agent 的“灵魂”。希望本文能为你开发下一个强大的 AI Agent 提供清晰的架构思路与工程指导。