Post

智能体与记忆体概述

随着以Claude Code和Open Claw为代表的一众智能体项目爆火,大语言模型(LLM)迸发出许多超越传统聊天机器人的潜力。越来越多的程序员、科学家以及各行各业的从业者开始使用AI进行项目开发、艺术创作、新闻获取、蛋白质合成、系统维护等工作,AI/智能体/记忆体/LLM已经成了当代人们不可或缺的强大生产力工具。相信不少人已经安装并日常使用Open Claw和Claude Code(如果还没有,请你先安装使用这两个工具再阅读本文,否则可能会难以理解一些概念),但对其中的数学模型和运行原理还不完全清晰。本文希望以一种简明易懂的方式介绍围绕在大语言模型周围的智能体和记忆体是如何工作的,以及当前在学界和工业界有哪些进展。

什么是智能体和记忆体?

智能体、记忆体、大语言模型、人工智能(AI)对很多普通人来说感觉像是一回事,因为用户界面都是一个聊天窗口或是终端 —— 你问一句,背后的AI回复你一句。再仔细一想,它中间可能有一些工具调用(tool calls),而且似乎还会记得你之前跟它说过的话,随着你代码或是文档的变动,它也能感知到并根据环境变化作出响应。这是怎么做到的呢?它背后的工作原理是什么?为了说清楚这个问题,我觉得最好的方法是用一套数学语言来描述这个任务。

定义 $\mathbb{I} = \{ 1, …, N \}$ 表示智能体的下标(index) —— 现在有很多multi-agent的工作流,智能体个数可能不止1个而是有N个。用 $\mathbb{S}$ 表示环境的状态空间(state space),在每一时刻 $t$,环境都会根据下面这个随机过程模型进行演进。

\[\mathbb{S}_{t+1} \sim \Psi(\mathbb{S}_{t+1} | s_t, a_t)\]

这里 $a_t$ 表示在时刻 $t$ 执行的一步动作(action)。每个智能体 $i \in \mathbb{I}$ 接收一个如下的观察结果。

\[o_t^i=\mathbb{O}_i(\mathbb{S}_t, h_t^i, \Omega)\]

这里 $h_t^i$ 表示智能体 $i$ 在 $t$ 时刻可见的交互历史; $\Omega$ 表示任务描述(如用户提示词、目标描述等),这里被视作一个常量,也就是说,我们这里描述的是用户把任务描述写好以后,提交给AI的一轮交互,在这一轮交互内,AI就会有多个步骤进行演进,产生从 $0$ 到 $T$个不同时刻的状态和动作。

智能体的功能就是使用一系列的动作来影响这个环境,这些动作都属于一个动作空间(action space),每个智能体 $i$ 会遵循如下的一个策略(policy)做出动作:

\[a_t = \pi_i (o_t^i, m_t^i, \Omega)\]

其中的 $m_t^i$ 是一个由记忆系统产生的信号。这一个动作内部可能会产生多步骤的推理链(reasoning chains), 隐式思考(latent deliberation)等等。一次完整的系统演进会产生这样一系列的轨迹:

\[\tau = (\mathbb{S}_0, o_0, a_0, \mathbb{S}_1, o_1, a_1, ..., \mathbb{S}_{T})\]

那记忆体和智能体之间的区别和联系是什么呢?智能体 $i$ 会获得一个当前时刻的观察结果 $o_t^i$,但这个观察结果通常是不足以让智能体做出一个有效决策的,因此我们需要从之前的交互中获取额外的信息。这个额外的信息就需要由记忆体或者说记忆系统(memory systems)来提供。我们可以把这个记忆能力用下面的演进状态来描述

\[M_t \in \mathbb{M}\]

这里的 $M_t$ 可以是一个字符缓冲区,key-value的字典形式,向量数据库,或是任何一种可以用来储存信息的方式。

针对一个记忆系统,生命周期之内通常有三件事要做:构建(formation)、演进(evolution)、抽取(retrieval)。我们可以用三个算子来描述。

构建算子(Formation Operator): $M_{t+1}^{form} = F(M_t, \phi_t)$。在每一个时刻 $t$,智能体提供信息产物 $\phi_t$,这可能是它生成的一个开发计划,根据你的提问做出的回答,或者是写到磁盘的一些文件等等。

演进算子(Evolution Operator): $M_{t+1} = E(M_{t+1}^{form})$。构建算子得到的结果往往不会直接存入记忆系统,而是需要经过压缩、整理、去重,删掉不重要的信息,归档到markdown文件,或者是向量化存到数据库中等等。

抽取算子(Retrieval Operator): $m_t^i = R(M_t, o_t^i, \Omega)$。记忆只有被抽取以后放入模型的上下文内,才能供给智能体/LLM使用。如何从记忆系统存储的数据中取回相关信息也是一个尚未被完全解决的问题,有大量研究工作在这个领域开展,比如各类RAG(Retrieval-Augmented Generation)相关的项目。

根据前述的数学模型,相信大家现在对智能体和记忆体应该有一个比较清晰的认知了,概括来说,智能体负责处理、编排各项事务,记忆体负责给智能体提供相关的外部信息,也负责从智能体生成的内容中提取重要信息,它们相辅相成,共同构成了现在用户体验到的人工智能。

再强调一下智能体和大语言模型(LLM)的区别。大语言模型只会干一件事,就是文字接龙,它利用大模型公司给它训练好的参数,针对给定的词元(token)序列,生成更多的词元。智能体工程像是给大语言模型套上了一个缰绳,所以现在也被称为Harness Engineering。智能体决定如何组装提示词,把什么东西放进大语言模型的上下文窗口中,并针对大语言模型的输出进行一些判断以及工具调用等。一个加深印象的例子是,如果你直接对着原生的大语言模型问问题,它是不会回答问题的!之所以现在的ChatGPT,DeepSeek等模型会回答问题,是因为它背后默默地把你的提示词包在了一个称为对话模板(chat template)的系统提示词里面,模型根据对话模板的要求进行文字接龙,就形成了问答的效果。这种大模型内的上下文处理通常被称为Context Engineering,智能体在某种程度上做的和它一样,也是处理上下文,但因为它不在模型的层面,而是更与任务相关,包含工具调用等功能,所以把它称为Harness Engineering。

为什么智能体需要记忆系统?

为了回答这个问题,首先我们需要对大模型的工作原理有一个清晰的认知:大模型的调用是没有状态的。也就是说,每一次的模型调用,对模型来说,都是从头再来,它没有“记忆”任何东西,你必须把所有它需要知道的东西都写在提示词里,一起发给它,它会从头开始根据它内部的transformer模型进行它的文字接龙游戏。因此,如果智能体没有记忆系统,它是无法知道你之前跟它说过什么的,你的OpenClaw认不出你是谁,也不知道你给它了一个什么名字,它也无法了解你当前正在做的项目是什么。可见,记忆系统对智能体的生产能力来说是至关重要的,我们在这一章节更细致地描述记忆系统的作用。

注意,在模型层面有KV-Cache的优化策略,当你在使用智能体时,由于前部的大量系统提示词在每次调用模型时都是一样的,大量的token会命中KV-Cache,从而大幅减少计算资源的消耗。模型还可以通过在压缩后的空间进行QKV计算,多头注意力机制共享KV值,分组KV共享等策略减少KV-Cache占用的空间,从而增加上下文长度,我们暂时不讨论这种模型层面的内存优化策略。广义上来说,这种模型相关的内存优化策略是属于LLM Memory,也可以算是记忆系统的一部分;我们这里主要讨论Agent Memory,也就是和模型本身无关的,和任务更相关的记忆系统。

记忆根据时间长短可以被分为长期记忆(long-term memory)和短期记忆(short-term memory)。长期记忆可以再分为事实记忆(Factual Memory)和经验记忆(Experiential Memory)。事实记忆包含了智能体了解的客观事实、用户偏好、环境状态等。经验记忆包含了智能体过去的动作轨迹、失败成功经验等,使得智能体可以根据过去的经验改进自身。短期记忆主要是指当前的工作记忆(Working Memory),基本上就是上下文中已经存在和即将由模型生成的内容。

事实记忆

事实记忆又可以进一步分为用户事实记忆(User Factual Memory)和环境事实记忆(Environmental Factual Memory)。

用户事实记忆保存了和用户相关的事实,包括用户身份、偏好、例行事项、历史贡献等。对话连贯性(Dialogue Coherence)和目标一致性(Goal Consistency)构成了用户事实记忆的关键目标。

为保障对话连贯性,工程上通常采用启发式选择(heuristic selection)和语义抽取(semantic abstraction)两种策略。记忆系统通常不会将全部的记录保存下来,而是将过去的交互以结构化的方式抽取出来,根据相关性(relevance)、重要性(importance)、独特性(distinctiveness)、时效性(recency)等指标进行排序,把高价值的记录保存下来,并随着时间推移不断抽取、压缩成概要,从而使这部分重要记忆在每次调用模型时都能放入提示词内。除此之外,一些先进的记忆框架(如Think-in-Memory, Reflective Memory Management)还会对原始对话进行转换和抽取,把这些信息转换成向量形式,从而进行语义检索。为什么不能将全部的原始日志(raw log)保存下来放进提示词呢?一方面是上下文长度有限,原始日志很快会撑爆上下文窗口;另一方面是原始日志有大量其他不重要的信息,模型的注意力机制可能不能很好地捕捉最重要的内容。

为保障目标一致性,一些记忆系统(如RecurrentGPT, Memolet, MemGuide)会重点突出尚未解决的部分,根据任务目标进行抽取引导,从而帮助智能体将注意力重点放在尚未满足的约束上。还有一些系统(如A-Mem, H-Mem)会把记忆存储成图的形式,从而快速找出不同记忆事件之间的依赖关系。

环境事实记忆保存了像长文档、代码仓、工具、交互痕迹之类的信息。这部分记忆的主要目标是(1)保存关键的世界知识和领域知识,(2)帮助多智能体共享知识。

针对世界、领域知识管理,HippoRAG项目利用了知识图谱帮助证据传递,MemTree项目使用了多层结构优化知识积累。其他还有像MEMORYLLM, M+, WISE等项目允许记忆池训练,吸收新的记忆,还可以进行模型编辑,从而使得智能体可以适应环境变化,修改过时的记忆(比如”当前美国总统是谁?”这样具有时效性的知识),并保障预训练模型的稳定性。

针对多智能体共享记忆和协同工作,Memory Sharing框架允许智能体异步访问,并基于其他智能体的经验构建记忆,从而避免多智能体协同工作时出现相悖的结论,提升系统有效性。还有一些项目,像MetaGPTGameGPT利用了共享信息池作为中央工作区来发布计划和获取部分结果。这些工作将各智能体的记忆以某种方式共享,降低沟通延迟,并允许智能体们从过去的合作中吸取经验。

经验记忆

经验记忆将智能体长期积累的经验、历史轨迹、策略、交互结果抽取成可以持久储存的表示形式,帮助知识和经验进行传承。经验记忆是智能体进行持续学习(continual learning)和自我演进(self-evolution)的关键基础。通过结构化的经验记忆,智能体可以在不修改模型参数的情况下将交互反馈转化为可以再利用的知识。

经验记忆的一个核心能力是反思与自省(Reflection and Introspection)。智能体在完成一项任务后,会对自己的执行轨迹进行回顾和评估,识别出哪些策略是有效的、哪些步骤导致了失败。这一过程在经典框架Generative Agents中首次被系统化地提出:智能体在积累足够的观察后,会触发一个反思步骤,生成更高层次的抽象总结,这些总结随后被存入记忆流中,供未来的决策使用。后续工作如Reflexion进一步将反思结果以自然语言的形式保存为”自我修正指导”,使得智能体在后续遇到类似任务时可以显式地参考过去的失败教训,避免重复犯错。

另一个重要方向是基于案例的经验复用(Case-based Experience Reuse)。Voyager项目在Minecraft游戏中展示了这一思路的威力:智能体将成功完成的技能以代码形式存入一个”技能库”(skill library),当遇到新的子任务时,它会从技能库中检索最相关的已有技能,作为新任务解决的起点。类似地,ExpeL框架将任务解决过程中的成功轨迹和失败轨迹分别抽取为”洞察”(insights)和”正负例”(positive/negative demonstrations),使智能体在新任务中可以同时借鉴成功经验和失败教训。LEMUR项目则将经验组织为结构化的”经验文章”,通过一个经验管理器对过时或冗余的经验进行淘汰,保证经验库的时效性和精简性。

经验记忆还可以用于策略优化和流程改进AgentTuning项目收集了智能体在各种任务上的交互轨迹,通过偏好学习(preference learning)的方式将好的交互模式内化到模型中。MUSE项目则允许智能体根据历史执行结果动态调整自己的SOP(Standard Operating Procedure),使得工作流程可以随着经验的积累不断进化。这些工作表明,经验记忆不仅帮助智能体在推理时获取外部知识,还可以形成一种从经验中持续学习的闭环机制。

短期记忆

短期记忆指的是智能体在当前任务执行过程中持有的工作记忆(Working Memory),主要就是上下文窗口中已有的内容:系统提示词、对话历史、工具调用结果、以及模型即将生成的内容。短期记忆的特征是容量有限但访问速度极快——它不需要从外部存储中检索,而是直接参与当前前向传播(forward pass)的计算。

短期记忆的管理核心挑战在于上下文窗口的有效利用。上下文窗口的大小受限于GPU显存和模型架构,通常在数万到数十万token之间。虽然模型厂商不断扩展上下文长度(如Gemini的百万级token上下文),但在实际使用中,简单的填充策略(fill-the-context)并不能带来最好的效果。研究表明,当上下文中包含过多无关信息时,模型的注意力机制会被稀释,导致输出质量下降,这一现象被称为”迷失在中间”(Lost in the Middle)。因此,短期记忆管理的关键不是往上下文里塞尽可能多的信息,而是通过合理的取舍,让上下文中的每一段信息都有助于当前的决策。

工程实践中,短期记忆的管理通常涉及以下策略:上下文压缩(Context Compression)将冗长的对话历史或工具输出压缩为更紧凑的表示,只保留与当前任务最相关的部分;滑动窗口(Sliding Window)只保留最近的若干轮对话,更早的内容被丢弃或归档到长期记忆中;摘要生成(Summarization)定期对历史对话进行总结,用一段概要替代大量原始记录。这些策略在Claude Code和Open Claw等工具中都有体现——当上下文接近容量上限时,系统会自动触发压缩机制,将早期内容折叠为摘要,为新的交互腾出空间。

短期记忆和长期记忆之间存在紧密的协作关系:短期记忆中即将溢出的内容需要被长期记忆系统及时捕获和归档,而长期记忆系统中与当前任务相关的信息又需要被抽取回来,填充到短期记忆中。这种记忆的流入与流出(memory flow)是整个记忆系统设计的核心难题之一,我们将在后续章节中详细讨论。

记忆是以什么形式存储的?

在第一章的数学模型中,我们将记忆定义为 $M_t \in \mathbb{M}$,并提到它可以是字符缓冲区、键值字典、向量数据库或是任何能储存信息的方式。这一章我们来具体看看,在研究和工程实践中,记忆到底是以哪些形式被存储和组织的。不同的存储形式会直接影响记忆系统的构建算子 $F$、演进算子 $E$ 和抽取算子 $R$ 的设计选择。

自然语言文本

最直觉也最普遍的存储形式就是自然语言文本。智能体将重要的信息以人类可读的文本形式写入文件中,需要时再读取出来。Claude Code的记忆系统就是一个典型例子——它将用户偏好、项目背景、工作习惯等信息以Markdown格式写入一组 .md 文件中,每次启动新会话时自动加载这些文件到上下文中。这种方式的优势在于零额外依赖:不需要数据库、不需要向量模型,只需要一个文件系统。文本形式的记忆也是模型原生能理解和生成的格式,不需要额外的编解码过程。

然而,纯文本存储面临的核心挑战是检索效率。当记忆文件积累到一定规模后,将所有文件全部加载到上下文中既不经济也不可行。工程上的解决方案通常是维护一个索引文件(如Claude Code的 MEMORY.md),只包含各条记忆的标题和一句话概要,系统据此判断哪些记忆条目与当前任务相关,再按需加载完整内容。这种分层索引策略本质上是一种启发式检索(heuristic retrieval),用简单的文本匹配和规则来替代更复杂的检索算法。

文本记忆的另一个优势是可解释性和可编辑性。用户可以直接打开记忆文件查看智能体记住了什么,也可以手动修改或删除不准确的记忆条目。这种人机协作的记忆管理在当前的工具型智能体中非常实用。

键值对与结构化数据

键值对(Key-Value)和结构化数据是另一种常见的存储形式。记忆被组织为具有明确字段和类型的数据结构,例如JSON对象、数据库表、或者Schema约束下的记录。这种形式的优势在于精确检索:给定一个键(如用户ID、项目名称),系统可以O(1)地定位到对应的记忆条目,无需任何模糊匹配或语义计算。

许多智能体框架采用结构化存储来管理用户档案和偏好设置。例如,将用户的编程语言偏好、代码风格要求、常用框架等信息以结构化字段的形式存储,智能体在决策时可以精确引用这些字段。一些项目(如MemoryBank)将记忆组织为带有时间戳、重要性评分和访问频率等元数据的结构化记录,从而支持基于多种维度的排序和过滤。

结构化存储的局限在于灵活性不足。它要求预先定义好数据模式(schema),而智能体的交互中产生的信息往往是异构的、难以预先完全规约的。因此,在实践中,结构化存储通常与文本存储配合使用:结构化字段用于存储确定性的属性,文本字段用于存储开放性的描述信息。

向量嵌入

向量嵌入(Vector Embedding)是当前记忆系统中研究最为活跃的存储形式。其核心思想是将每条记忆通过一个嵌入模型(embedding model)映射到一个高维稠密向量空间 $\mathbb{R}^d$ 中的一个点,然后利用向量之间的距离(通常是余弦相似度)来衡量记忆之间的语义相关性。检索时,将查询(query)也编码为同一空间中的向量,通过最近邻搜索(nearest neighbor search)找到最相关的记忆条目。

向量存储的核心优势在于语义检索能力。即使用户的查询使用了与记忆原文完全不同的表述方式,只要语义相近,向量检索就能将其关联起来。例如,用户之前提到”我不喜欢写单元测试”,后来智能体在决定是否为某段代码生成测试时,通过语义匹配就能召回这条偏好。这种能力是纯文本匹配和结构化查询都无法实现的。

在工程实现上,向量存储通常依赖于专用的向量数据库,如FAISS、Milvus、Pinecone、ChromaDB等。这些数据库针对高维向量的近似最近邻搜索(ANN, Approximate Nearest Neighbor)进行了优化,可以在百万甚至亿级向量中实现毫秒级的检索。大多数RAG(Retrieval-Augmented Generation)系统的底层都采用了向量存储作为记忆后端。

向量存储也面临一些挑战。首先是嵌入质量的依赖:如果嵌入模型无法准确捕捉语义,那么再好的检索算法也无济于事。其次是粒度问题:一条记忆应该被切分为多大的块(chunk)再进行向量化?粒度过粗会包含过多无关信息,粒度过细则可能丢失上下文。此外,向量检索本质上是一种模糊匹配,它无法保证精确召回特定的事实条目,这在需要确定性答案的场景中可能成为问题。

知识图谱

知识图谱(Knowledge Graph)将记忆存储为节点(node)和(edge)构成的图结构。节点通常代表实体(如人物、概念、事件),边代表实体之间的关系(如”用户A偏好Python”、”项目B依赖框架C”)。这种存储形式的优势在于能够显式地表示实体间的关系和结构,支持多跳推理(multi-hop reasoning)。

HippoRAG项目是知识图谱记忆的一个代表性工作。它借鉴了人类海马体的记忆索引理论,将外部文档解析为知识图谱,通过个性化PageRank算法在图上进行证据传递,使得检索不仅能找到直接相关的信息,还能沿着关系链条发现间接但重要的关联。类似地,前文提到的A-MemH-Mem也采用图结构来组织记忆,从而支持记忆事件之间依赖关系的快速查找。

知识图谱存储的构建成本相对较高:它需要从非结构化的交互信息中抽取实体和关系,这一步通常依赖LLM来完成,不仅消耗额外的计算资源,还可能引入抽取错误。图谱的维护(如实体消歧、关系更新、冗余合并)也是一个复杂的问题。因此,知识图谱存储更适合于知识密集型关系复杂的任务场景,如科学研究辅助、复杂项目管理等。

参数化存储

参数化存储(Parametric Storage)是一种更为根本性的思路:它不将记忆存储在模型外部的独立系统中,而是直接修改模型自身的参数来编码新的知识。这包括模型编辑(model editing)、持续预训练(continual pre-training)、参数高效微调(PEFT, Parameter-Efficient Fine-Tuning)等方法。

前文提到的MEMORYLLM、M+、WISE等项目都属于这一方向。以MEMORYLLM为例,它将记忆分为两个互补的部分:一部分通过注入新的记忆向量来扩展模型的隐含知识,另一部分通过模型编辑技术来修正过时或错误的知识。这种方式的优势在于,记忆一旦被编码进参数,就不再占用任何上下文空间,也不会受到上下文窗口大小的限制——模型的每一次推理都自动利用了所有已编码的知识。

然而,参数化存储也面临灾难性遗忘(catastrophic forgetting)的经典难题:新知识的注入可能导致旧知识被覆盖或干扰。此外,参数化存储的可解释性极差——你无法像打开一个Markdown文件那样直接查看模型参数中编码了什么知识,也无法方便地进行精确的增删改操作。因此,参数化存储目前在实践中更多作为一种补充手段,与外部记忆系统配合使用。

混合存储

在实际系统中,上述存储形式往往不是单一使用的,而是组合为混合存储架构。一个典型的设计是:文本文件存储高层次的用户偏好和项目概要(便于人类审阅和编辑),向量数据库存储海量的交互记录和文档片段(支持语义检索),知识图谱存储实体间的关键关系(支持结构化推理),而上下文窗口则作为临时的工作空间,充当短期记忆的角色。

混合存储的设计需要在检索精度、存储效率、构建成本、可维护性等多个维度之间做出权衡,不存在一劳永逸的”最优”方案。不同的应用场景(如代码助手、科学研究、游戏智能体)对记忆的需求差异很大,存储形式的选择应该与具体的使用场景相匹配。

记忆系统是如何工作的?

在第一章中,我们用三个算子描述了记忆系统的生命周期:构建算子 $F$、演进算子 $E$ 和抽取算子 $R$。这一章我们就围绕这三个算子,系统地展开记忆系统的工作流程。

构建:记忆从哪里来

记忆的构建(Formation)解决的是”记忆从何而来”的问题。智能体在执行任务的过程中,会不断产生各种信息产物(information artifacts) $\phi_t$,这些产物就是记忆构建的原材料。具体来说,构建阶段的输入可能包括:

  • 对话摘要:对用户指令的复述、关键约束的提炼、任务目标的拆解
  • 执行轨迹:工具调用的序列、命令的返回结果、中间产生的文件内容
  • 反思结果:智能体对自身行为的复盘、成功经验和失败教训的提炼
  • 用户反馈:用户对输出的修正、确认或否定

构建算子 $M_{t+1}^{form} = F(M_t, \phi_t)$ 的设计需要回答一个核心问题:$\phi_t$ 中的哪些信息值得被保存?这个判断可以由规则驱动(rule-based),也可以由模型驱动(model-based)。

规则驱动的方法通常基于固定的指标进行筛选。例如,当检测到对话中出现了用户的偏好声明(如”我偏好用Python而非Java”),则将其提取为一条独立的偏好记忆。当工具调用返回了错误信息时,将其归档为一条失败经验记录。这种方式简单、可控,但需要人工设计大量规则,难以覆盖复杂多样的场景。

模型驱动的方法则让LLM来判断哪些信息重要。在一些框架中,智能体在每轮交互结束后会额外调用一次模型,让它评估当前产生的 $\phi_t$ 是否值得存入记忆,并给出理由。例如,Reflexion框架中的反思过程本质上就是一种模型驱动的构建——模型生成反思结论,这些结论被显式地写入记忆文件,供后续任务使用。

演进:记忆如何变化

构建算子输出的中间状态 $M_{t+1}^{form}$ 通常不会直接成为新的记忆状态 $M_{t+1}$,而是需要经过演进算子 $M_{t+1} = E(M_{t+1}^{form})$ 的处理。演进阶段的核心任务是对记忆进行压缩、整理和重组,以保持记忆库的健康状态。

压缩与摘要是最常见的演进操作。随着交互次数的增加,原始记录会快速膨胀,超出存储空间和检索效率的容忍范围。演进算子会将相似的记忆条目合并,将冗长的描述压缩为简洁的摘要,将低频访问的记录归档到深层存储中。这一过程可以由定时任务触发(如每天凌晨对记忆文件进行整理),也可以由容量阈值触发(如当向量数据库中的记录数超过上限时自动压缩)。

去重与一致性维护是另一个关键功能。如果两条记忆表达了相互矛盾的信息,演进算子需要有能力检测并处理这种冲突。简单的方法是保留更新的记忆、丢弃旧的;复杂的方法则可能需要引入投票机制或让模型判断哪条信息更可靠。此外,演进算子还需要处理过时信息的更新问题:当用户的偏好发生变化时,旧偏好应该被标记为失效或直接替换,而不是与新偏好并存造成混淆。

结构重组允许记忆的组织形式随时间演进。例如,最初记忆是以纯文本形式存储的,但随着记忆规模增长,系统可能决定将部分记忆迁移到向量数据库中,或者将高频关联的记忆合并为一个知识图谱子图。演进算子负责执行这些结构层面的变化,使得记忆系统的组织形式能够适应不断变化的需求。

演进算子的设计需要谨慎处理——过于激进的压缩可能导致重要信息丢失,过于保守的演进则会使记忆库迅速膨胀。如何在这两者之间取得平衡,是记忆系统设计中的一个持续挑战。

抽取:记忆如何被使用

抽取(Retrieval)是将记忆转化为可用信息的关键环节。记忆只有被抽取出来,装入模型的上下文窗口中,才能在推理时发挥作用。抽取算子 $m_t^i = R(M_t, o_t^i, \Omega)$ 接收三个输入:当前的记忆状态 $M_t$、智能体的观察 $o_t^i$、以及任务描述 $\Omega$。

基于查询的检索(Query-based Retrieval)是最直观的抽取方式。给定当前的任务描述 $\Omega$,从记忆库 $M_t$ 中检索出与之相关的记忆片段。检索可以基于关键词匹配、语义向量相似度、知识图谱路径等多种方式。在RAG系统中,这种”提问-检索-注入”的范式已经非常成熟。

基于上下文的被动触发(Context-triggered Retrieval)是一种更隐式的抽取方式。与其显式地构建一个检索查询,不如让抽取算子直接分析当前的上下文 $o_t^i$,自动识别出哪些记忆应该被加载。例如,当模型在阅读一段Python代码时,与Python相关的经验记忆和工具偏好记忆可以自动浮现在上下文中,而无需用户显式请求。这种方式的优势在于降低了用户的认知负担,劣势在于隐式触发可能不准确,引入无关信息反而干扰决策。

记忆的优先级与排序也是抽取算子需要解决的问题。在大多数场景下,抽取出的记忆条目数量可能远超上下文窗口的容纳能力,抽取算子必须对候选记忆进行排序,优先放入最重要、最相关的内容。前文提到的相关性(relevance)、重要性(importance)、时效性(recency)等指标都可以作为排序依据。一些系统还会考虑记忆的访问历史:被频繁召回的记忆条目可能更稳定可靠,应该在排序中获得更高权重。

构建、演进、抽取的协同

三个算子并非孤立运行,而是紧密协作形成一个循环。抽取出的记忆 $m_t^i$ 参与了智能体的决策过程(第28行的策略公式),决策产生新的信息产物 $\phi_t$,这些产物经由构建算子转化为中间记忆,再经由演进算子整合进记忆状态 $M_{t+1}$,为下一轮抽取做好准备。这个闭环可以用下面的流程图描述:

\[M_t \xrightarrow{R} m_t^i \xrightarrow{\pi} \phi_t \xrightarrow{F} M_{t+1}^{form} \xrightarrow{E} M_{t+1} \xrightarrow{R} \cdots\]

值得注意的是,这个循环不是每一步都要完整执行的。在实际系统中,抽取几乎是每轮推理都要进行的,但构建演进的触发可以更稀疏。例如,构建操作可以每完成一个子任务后触发一次,而演进操作可以每天或每周执行一次。合理地调度这三个算子的执行频率,是记忆系统工程实现中的一个重要工程决策。

另外,三个算子的实现深度也因场景而异。在轻量级的实现中(如Claude Code的纯文本记忆),构建可能只是把重要对话追加到文件中,演进可能只是定期手动整理,而抽取可能只是通过grep或简单搜索。而在一个复杂的向量+知识图谱混合系统中,构建需要调用LLM进行摘要生成,演进需要运行图数据库的维护任务,抽取需要执行复杂的混合检索算法。

记忆的流动:短期与长期的桥梁

第一章提到,短期记忆中即将溢出的内容需要被归档到长期记忆,而长期记忆中与当前任务相关的信息需要被抽取到短期记忆中。这两种方向的记忆流动是记忆系统工作流程中的核心协调机制。

从短期到长期的流动发生在上下文即将满载的时刻。系统需要判断哪些内容值得保留、哪些可以丢弃。保留的标准通常是:这条信息在未来的任务中是否可能被用到?这需要基于当前任务上下文进行预测,具有一定的不确定性。Claude Code的做法是将即将离开上下文的对话内容压缩为摘要,写入长期记忆文件,使得未来在类似场景下可以回溯。

从长期到短期的流动发生在新任务开始时。系统需要从长期记忆中检索与当前任务相关的背景信息,包括用户偏好、项目上下文、相关经验等。一个好的记忆系统应该能够快速、准确地完成这个”加载”过程,既不能遗漏重要信息,也不能引入过多噪音。

这两种流动方向共同决定了记忆系统的”活性”:如果长期记忆中的信息很少被抽取到短期中使用,说明记忆的利用率低,记忆系统没有真正发挥作用;如果短期记忆的内容频繁需要更新到长期中,说明短期窗口可能过小,或者记忆的重要性判断有偏差。

记忆系统与其他概念的一些关联和区别

在阅读本文的过程中,你可能会遇到一些与”记忆”相关的术语——RAG、LLM Memory、Context Engineering等。这些概念之间既有重叠又有区别,在文献和工程实践中常常被混用,容易造成困惑。这一章我们专门来梳理这些概念之间的边界和关联,帮助读者建立一个更清晰的全局图景。

Agent Memory vs RAG

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将外部知识检索与语言模型生成相结合的技术架构。标准的RAG pipeline包含:文档切分(chunking)、向量化(embedding)、向量存储(vector store)、检索(retrieval)、注入(injection)几个环节,用户的问题通过检索从外部文档库中获取相关片段,注入到模型上下文中,辅助生成答案。

粗看起来,RAG和Agent Memory非常相似——两者都涉及从外部存储中检索信息并注入上下文。但两者的侧重点和目标场景有所不同。

RAG的核心目标是弥补模型知识的不足,即模型在预训练时没有见过或已经遗忘的知识。它假设存在一个相对稳定的外部知识库(如企业文档、法律条文、产品手册),检索的目的是从中找到与当前查询相关的”事实”,这些事实通常不会随时间频繁变化。RAG的信息流向主要是单向的:从外部知识库到模型上下文。

Agent Memory则不然,它的记忆内容不仅来自外部文档,更来自智能体与用户、环境之间的交互过程——用户的偏好、对话历史中的关键决策、智能体自身的成功与失败经验等。Agent Memory需要处理的是动态生成的、任务相关的信息,信息的生命周期与用户的项目进程紧密绑定。此外,Agent Memory的信息流向是双向的:不仅要从记忆中读取信息,还要将交互过程中产生的新信息写入记忆,供未来使用。

用一个比喻来说:RAG像是一个图书管理员,在一个固定的图书馆里为你查找相关的书籍章节;Agent Memory则像是一个私人秘书,它不仅帮你查找信息,还会记住你之前交代过的事、你在哪些地方摔过跟头、你习惯用什么方式工作,并根据这些积累的经验主动为你提供帮助。

当然,两者的边界也在逐渐模糊。一些先进的RAG系统已经引入了交互历史的记忆机制,而不少Agent Memory系统也借鉴了RAG的向量检索技术作为其底层基础设施。这种融合是自然的——两者解决的是同一个根本问题(如何让模型利用超出自身参数的信息),只是在实现细节和应用场景上有所侧重。

Agent Memory vs LLM Memory

LLM Memory(或称Model Memory)指的是与语言模型自身机制相关的内存优化技术。最典型的例子是KV-Cache:模型在自回归生成过程中,每次预测下一个token时,前文的Key和Value矩阵会被缓存起来复用,避免重复计算。Attention Sink、Grouped Query Attention、滑动窗口注意力等机制也属于LLM Memory的范畴。这些技术的共同特点是:它们发生在模型层内部,与具体的任务和用户无关。

LLM Memory还可以扩展到模型层面的知识编辑(model editing)和持续预训练(continual pre-training)——即直接修改模型的参数来编码新的知识。我们在第三章讨论参数化存储时已经提到过这个方向。

Agent Memory与LLM Memory的核心区别在于层级和职责。LLM Memory工作在模型推理层,处理的是如何更高效或更充分地利用模型的上下文窗口;Agent Memory工作在任务执行层,处理的是如何获取、利用和管理与当前任务相关的外部信息。两者的关系可以类比为:LLM Memory是模型的”短期工作记忆”的物理实现(缓存、注意力机制),而Agent Memory是智能体的”长期知识库”的管理系统。

用第一章的数学语言来说,Agent Memory解决的问题是抽取算子 $R$ 的设计——如何从外部存储 $M_t$ 中取回有用的 $m_t^i$;而LLM Memory解决的问题是模型本身如何处理它收到的token序列。Agent Memory的输出会成为LLM Memory的输入(因为抽取出的记忆最终还是要放入模型的上下文),但两者的设计考量和优化目标是完全不同的。

本文在引言中已经做了一个提示:本文主要讨论Agent Memory,对LLM Memory只做简要提及,不深入展开。但了解两者的区别有助于读者在阅读相关文献时避免混淆。

Agent Memory vs Context Engineering

Context Engineering是近年来提出的一个概念,指的是在模型上下文层面进行的系统性工程优化。典型工作包括:提示词结构的设计(system prompt engineering)、few-shot示例的选择与排序(in-context learning)、上下文窗口内容的组织策略(context management)、_chain-of-thought等推理技术的引入。

Context Engineering和Agent Memory之间的界限可能是最容易混淆的。两者的本质区别在于:Context Engineering优化的是”上下文中放什么”,而Agent Memory优化的是”上下文中的内容从哪里来”。

具体来说,Context Engineering关心的问题包括:如何设计system prompt使得模型的行为更符合预期?few-shot示例应该如何选择和排列?当上下文过长时,应该优先保留哪些部分?对于这些问题,Agent Memory并不直接回答——它提供的是支持这些决策的基础设施。例如,当Context Engineering决定”需要将用户偏好注入上下文”时,Agent Memory负责决定”用户偏好存储在哪里、如何检索、如何更新”。

换一个角度来说,Context Engineering是一种手工的、由人驱动的上下文优化策略——它依赖于工程师对模型行为的经验和直觉,通过精心设计的提示词模板来引导模型。而Agent Memory是一种自动的、由数据驱动的上下文补充机制——它从交互历史和外部存储中自动抽取相关信息,减少人工干预的负担。

值得注意的是,Context Engineering和Agent Memory也经常被结合使用。一个典型的例子是Claude Code:它的system prompt(Context Engineering的产物)告诉模型”你可以使用MEMORY.md文件来存储和检索记忆”,而MEMORY.md文件的存在本身就是一个Agent Memory系统的体现。

概念之间的关系总结

为了帮助读者建立更直观的认识,我们用一个表格来总结这几个概念的核心差异:

 Agent MemoryRAGLLM MemoryContext Engineering
核心目标管理任务相关的动态记忆弥补模型知识缺陷优化模型推理效率优化上下文的组成质量
信息来源交互历史、用户偏好、经验积累外部文档库模型参数/推理过程人工设计的提示模板
信息流向双向(读写)单向(读为主)模型内部单向(注入)
触发方式自动检索按需检索自动(模型内部)人工设计
典型实现向量数据库、知识图谱、文本文件FAISS、Milvus、PineconeKV-Cache、Attention SinkChain-of-Thought、Few-shot

从这个表格可以看出,这四个概念虽然都围绕”记忆”二字,但它们的侧重点和解决的问题域是不同的。在实际工程中,一个完整的智能体系统通常会同时涉及所有这四个方面:Agent Memory负责管理任务相关的外部记忆,RAG负责从领域文档中检索知识,LLM Memory负责让模型的推理更高效,Context Engineering负责将所有这些信息以最优的方式组织到上下文中。

理解这些概念之间的区别与联系,有助于在实际项目中识别真正需要解决的问题:是需要改进记忆的检索算法?还是需要优化提示词的结构?还是需要引入向量数据库?不同的诊断结论对应着不同的优化方向。

小结

本文从数学模型出发,系统介绍了智能体和记忆系统的基本概念、为什么智能体需要记忆系统、记忆的存储形式、记忆系统的工作流程,以及它与相关概念的区别。这些内容为读者建立了一个理解当前智能体记忆系统的基本框架。

然而,这个领域的发展速度极快——新的记忆架构、新的检索算法、新的记忆-推理协同机制不断涌现。本文的目的是帮助读者入门和建立框架,而非穷尽所有工作。如果你对某个具体方向感兴趣,可以从文中引用的论文和项目入手,进行更深入的学习。

This post is licensed under CC BY 4.0 by the author.

© Yuanjian Liu. Some rights reserved.

Stay passionate about your life because it is awesome!