在大模型Agent的设计中,Agent所必备的能力被抽象解构成好几个重要的模块,比如planning,tools,memory等。我个人比较喜欢用下面这张经典老图的拆解来表示:
这里将一个智能体拆解成了3个最重要的模块:感知模块、决策模块和行动模块。这篇blog主要想记录对决策模块里memory的理解思考和当前比较主流的memory机制 - mem0的paper work的记录。
前言
类比于人类的记忆系统,大模型Agent的Memory模块是其实现自主决策、长期学习和环境适应的核心组件。我喜欢将memory和knowledge分开,这儿也沿用的我的一些定义。LLM本身就是一个大型信息库+知识库,为了弥补其知识的静态性,实际构建Agent的时候通常会外接知识库,这个可能是补充专业领域知识的知识库,也可能是补充最新动态信息的知识库(当然这个也可以用过搜索引擎在<工具>调用模块提供)。除开这些知识信息外,我倾向于把memory用于是关于用户行为偏好的(或者自身行为偏好,但目前还不具备这一点,咱不做考虑)信息记录。
Memory的分类
当前Agent多作为chatbot或者copilot的形式出现,所以主要是以XX助手的身份来服务于一个或多个用户。所以结合这种情况与当前流行的分类方式,我把memory分成:短期记忆(STM)、长期记忆(LTM)以及用户画像。
- 短期记忆
储存当前Agent和用户沟通的上下文,即conversion中的每一轮对话,但是这个受限于LLM本身的上下文窗口长度(比如8K tokens)。虽然随着LLM训练技术的进步这个window length在不停的增加,但是考虑到注意力可能的分散以及推理latency,将所有的对话记录都塞给LLM肯定不是一个好的选择,也不符合人类的记忆模式(当然这一点不是一个solid的论点,但是当前直觉上我们可以先这么类比。其实不一定符合人类的模式是高效的,特别是对于构建的机器个体,这个可以参见Sutton的bitter lesson)。所以短期记忆我们可以是上文轮数的一个截断,比如近10轮;或者是按交互时间的区分,比如当天的所有对话作为短期记忆。 - 长期记忆
conversion中的除开短期记忆的那部分,一般是更早之前的对话,那部分对话需要被实体化的记录到外部存储中,可以近乎无限制的储存,使用的时候再通过检索机制来调用合适记忆。这儿两个核心点是如何储存与如何检索的设计:- 储存涉及到关键信息的提取、信息的压缩,否则如果只是原始对话信息的储存对于使用的增益很有限(还是参考context window的限制与人类记忆系统)。时间越远的信息越容易忘记、记忆冲突需要解决机制、原始信息需要往上提炼成更精炼的记忆点才会方便后续的会回忆、等等。所以储存的更多的是summary后的历史对话信息。
- 检索的设计更多是依赖与储存来的,传统的基于embedding+rerank的semantic search肯定是首先能想到的高效方式;同时混合的检索方式也极大概率会被考虑,特别是当储存的设计考虑的一些预定义的category或者是关键词的时候(根据具体agent场景)。
- 用户画像
上面的长短期记忆是by conversation的,即在一次对话里、或处理一个任务里需要跟随的。我把跨conversation需要用到的记忆放在了这一类里面,这个更多的是by user的信息(即用户的静态信息、偏好信息等),可以在不同的对话任务里进行使用。比如用户喜欢日光,那么在旅游推荐里可以使用到这一点。比如用户提到过他是一个穆斯林,那么推荐食物的时候就有相应的侧重等等。
Paper Work
1. Cognitive Architectures for Language Agents
这是一篇比较早的系统性的结构Agent的架构,通过感知科学和符号人工智能的发展史,提出了CoALA - 一种Agent架构:一个模块化的记忆组件、一个可与内部记忆与外部环境交互的结构化的行动空间、以及一个通用的用于选择行动的决策制定过程。我们这儿主要关注其中关于memory的构建。
CoALA提出将memory分为4种类型:一种短期记忆(working memory)和三种长期记忆(episodic、semantic、procedural memory)。
- working memory。工作记忆,可以简单的理解成最终进入LLM的prompt所需的元素。即prompt template中的那些动态的需填入的variable。
- episodic memory。情景记忆,储存的agent历史的‘经历’:过往有做了哪些‘决定’,执行了哪些‘动作’。即交互历史,什么场景下做出了哪些反应。这些记忆可以用于指导后续agent遇到相同事件的时候应该如何反应,相关用途:
- 决策时检索相关经验至工作记忆,辅助推理。
- 将工作记忆中的新经验写入情景记忆。
- semantic memory。语义记忆,储存智能体对世界和自身的知识(非时间性事实)。简单理解就是知识库(内部知识库:大模型的weights;外部知识库:向量数据库),RAG本质是从只读语义记忆中检索。语义记忆的进一步特性是需要动态写入新知识(如LLM推理结果),实现渐进式知识积累。
- procedural memory。程序记忆,储存agent的工作步骤,比如大模型weights(关于行为的那部分)以及人类通过代码实现的运行机制(比如workflow)。这是最底层的,一般不会变更。
2. langmem
document链接
langchain的memory工程模块。
3. mem0
paper链接
最近很火的一个开源项目。方法论上不是太复杂,它主要的亮点是工程化的实现和产品化。
方法层面,它主要采用了2个步骤extraction phase和update phase来有机的实现memory的获取和更新,以此实现长时对话和跨时对话的信息一致性。
- extraction phase。通过当前上文检索出合适的memory内容。
- update phase。将ADD, UPDATE, DELETE和NOOP作为4种tool方法,通过function calling让LLM实现自主判断+选择是否更新memory。
基于不同的储存机制,种memory的构建方式:mem0和mem0-g。mem0是通过向量数据库进行memory的储存,mem0-g是通过知识图谱来进行储存的。
mem0的流程:
mem0-g的流程:
4. mirix
paper链接
很新的一篇paper,主要提出了将memory分成6类:
- Core Memory:用户画像、偏好,每次都会用的东西
- Episodic Memory:temporal的信息,类似日志或者日历信息(i.e.某时间做了某事)
- Semantic Memory:静态知识或者事实信息
- Procedural Memory:完整某个任务的步骤,储存解决问题的方法论
- Resource Memory:原始文件信息(pdf,doc,png等)
- Knowledge Vault:用户敏感信息,如密码、地址等