一:短期记忆:大模型上下文
就是大模型的上下文
二:中期记忆:执行任务记忆
-
对上一阶段的对话进行阶段性摘要。根据任务精心设计prompt,目标明确。摘要序列存储。
-
即将Agent过程中的Action单独存储,维护一个”Action栈“,对历史执行任务进行管理。
比如,对话助手,每20轮就需要
三: 长期记忆:借助外部存储
letta(原MemGPT):
Main Context:
MemGPT可以看做一个Agent,每次输入的Main Context主要包含三部分:
- System Instructions:静态的系统prompt,不可修改,用来定义Agent的基本设定、工作流、所有tools的定义描述等。如:
The following is information about myself. My task is to completely immerse myself in this role (I should never say that I am an AI, and should reply as if I am playing this role).If the user asks me a question, I should reply with a best guess using the information in core memory and conversation search.
- Working Context:是一个固定长度的、可以修改的、非结构化文本描述,只能通过Agent的function calls来修改。用来存储Agent所接受的关键信息、个人偏好以及其他重要信息。在默认模式下,这个模块包含两个block,一个是human(保存用户基本信息),一个是persona(保存agent自身角色设定)。随着对话的进行,agent根据上下文信息,通过function calls自动地、持续地修改和补充block中的内容。
- FIFO Queue: 存储队列,存储历史对话记录、agent系统输出信息(比如memory用量提醒等)、function call的输入和输出。由于LLM的context窗口长度限制,agent会定期把一部分message记录从Context中删除,保存到Recall Storage中,这时agent会将删除的message记录以及结合当前的Summary,生成一个Recursive Memory,构建新的记忆,因此,在Context中,这部分内容的调整最频繁。
下图是letta框架实际方案中Context的组成:
- Queue Manager(QM):
队列管理模块管理在Recall Storage和FIFO Queue中的message。
当新的用户message进来,QM把新的message先加入到FIFO队列中,与prompt拼接到一起送给大模型,得到输出。QM将输入和输出同时写入到Recall Storage数据库中。在后面的对话中,如果agent通过function call从RS中检索出来特定的message,QM会把他们加入到队列的后面,并拼接到LLM的输入prompt中。
QM还负责实现队列移除策略,用来控制对话溢出,当prompt的token长度超过70%,QM回想队列中插入一句“system提醒”,触发agent使用functions来总结FIFO队里中的重要信息,然后存储到数据库(Archival storage)中。
当prompt的token长度超过了100%,QM将释放空间(比如50%),用当前的Summary和释放的message重新生成一个新的Summary。当队列空间被被释放,弹出的message就不会出现在输入contaxt中,只会储存在Recall Storage中了,只能被agent通过funcitons来访问,参考上面的流程。
- Function executor
MemGPT精心设计了在context和外部存储单元之间进行信息移动的策略,这些策略都是通过function call来实现。记忆的编辑和检索是完全自我驱动的:MemGPT根据当前的语境和从记忆库中搜索来自动更新记忆,比如,当对话太长的时候,会选择移除一些信息。实现方式就是在system prompt中直接说明(instructions)来实现,这些instructions主要包好两个部分:1.详细描述说明记忆模块的层次结构以及他们的具体功能,2.funciton列表和描述,agent用来使用他们修改意义内容。
了解context的限制是MemGPT正确运行的关键因素。
参考:
Agent Workflow Memory
本文提出的Agent workflow Memory(AWM)框架,是通过Agent来持续地归纳出工作流(workflow),再整合使用工作流(workflow)来提升系统表现。工作流(workflow)的定义是为了解决一个特定问题的子步骤拆解,可以有效地帮助agent解决后续越来越复杂的任务,如下图中,显示了AWM在WebArena 地图导航数据集上导出的workflows:
AWM可以通过agent轨迹持续地归纳出工作流(workflow),也就是抽取可以重复使用的路径,然后把这些workflow整合到agent的记忆模块来指导解决下面的任务。
AWM的实现方式:
-
一个workflow包含两个部分:1.关于此workflow的文本描述d,2.完成此workflow的一系列行动,如下图所示。
- Workflow描述:需要使用一个特定的格式,可以让agent正确的获取信息,如何从更高维度描述这一系列行动的目标是至关重要的。本质上就是对workflow功能的描述,具体实现就是启发性的经验提取或者直接使用LLM从总结出来的。
- Workflow轨迹:也就是完成此workflow的一系列行动轨迹,每一个行动p包含三个部分,分别是[env des],[reason]和[action]。具体的,如下图中Step3所示:1.[env des]是对当前环境状态的文字描述,比如:“Order {id} is shown”。2.[reason]是基于当前的观察,说明Agent详细的推理过程,决定接下来需要执行什么action,比如:“Order {id} is found, I will now terminate the task.” 。3.[action]即具体可以代码执行的函数,比如:stop() 函数,即终止workflow。
LM-based Workflow Induction:
AWM的核心就是workflow的归纳模块,主要作用就是agent根据过去的所有经验,归纳出一系列的workflows。每一个经验包含两部分,1.定义某个任务q的文本描述,2.行动轨迹,即解决任务q的一系列行动(观察和action)。
不同于任务描述,我们故意的让LLM尽可能抽取出来最细粒度的workflows,比如“search for a product on Amazon”,这个子任务会重复出现在各个任务中。同时,我们会用槽位标识来代替具体的值,使得workflow更加通用性,比如:用“{product-name}”代替“dry cat food”来表示。
LLM输出这些workflows的通过prompt来约定格式,比如通过json格式或者用双空格分隔。在具体使用的时候分开存储在Agent的记忆模块中。在workflows W被归纳出来之后,直接加入到agent当前的记忆M中,生成强化的记忆。当处理指示q时,agent推理出一系列action通过function call方式执行,过程可以表示成:
AWM有下面两种工作模式,“离线模式”和“在线模式”。
-
“离线模式”分成两个独立的阶段,下方左图:
- induce workflows:首选使用人工标注的训练数据或者模型合成的数据来,即把所有训练数据拼接成一个prompt,然后输入到LLM中抽取出一系列workflows,这个可以看做“训练”阶段。
- 把“训练”阶段得到的所有workflows作为agent的记忆,来解决每个待测试指令(instructions)。
-
“在线模式”,下方右图:
- 很多时候获得训练数据是很困难的,因此AWM还支持“无监督”模式,只需要测试query即可。AWM在“推理”的时候循环执行“推导”、“整合”和 “使用workflow”几个环节,并持续更新记忆的内容。
- 具体的,解决第t个测试query 的时候,首先agent通过LLM推理得到行动轨迹,他们共同组成经验。然后,我们采用基于LM的评估模型每个是不是能成功解决 ,如果判断是可以,就把这个经验转换成特定的workflow ,然后更新到agent的记忆中 ,然后继续解决后续的query。
评估指标:agent对每个测试query推理action轨迹的平均成功率。
AWM推导出的一些workflow例子:
WebArena数据集:
参考:
A-MEM(Agentic Memory)
这个memory的设计主要包含4个模块:便条构建、构建链接、记忆进化和记忆检索
1.构建便条Note
当Agent每次与环境交互时候,使用一个特定结构的便条来提取记忆内容,所有时刻的记忆汇总就构成了整个系统的记忆链。的具体结构是 ,其中,
-
表示原始的交互内容(也就是输入query)
-
表示交互的时间戳(格式为“YYYYMMDDHHMM”)
-
表示LLM生成的关键词,是使用大模型从当前语境用提炼出来的突出的关键词,通常是名词、动词或者通用概念。
-
表示当前记忆Note的标签,是LLM生成的,用来对记忆Note分组。
-
表示对当前语境的文本描述,用来提供更加丰富的语义理解,是LLM生成。
-
维护一组关联的记忆Note,他们具有相同语义。
-
是当前记忆Note的向量表示,用BERT来编码,用于快速检索和构建关联关系。
- 构建、和
其中,、和是通过精心设计的prompt 模板使用LLM生成: ,具体的prompt如下:
prompt = """Generate a structured analysis of the following content by:
1. Identifying the most salient keywords (focus on nouns, verbs, and key concepts)
2. Extracting core themes and contextual elements
3. Creating relevant categorical tags
Format the response as a JSON object:
{
"keywords": [
// several specific, distinct keywords that capture key concepts and terminology
// Order from most to least important
// Don't include keywords that are the name of the speaker or time
// At least three keywords, but don't be too redundant.
],
"context":
// one sentence summarizing:
// - Main topic/domain
// - Key arguments/points
// - Intended audience/purpose
,
"tags": [
// several broad categories/themes for classification
// Include domain, format, and type tags
// At least three tags, but don't be too redundant.
]
}
Content for analysis:
""" + content
- 构建
直接使用BERT类型编码器对记忆Note进行编码,直接将Note 中的、、和拼接起来:
2.构建链接(Link Generation)
本文的方案可以自动构建Note之间的关联关系,当新构建了一个记忆Note,可以自动找到现有Note哪些是有关联的,构建起边的关系。具体的,
第一步,当引入新的记忆便条,使用上面的方法得到向量表示,然后与所有记忆Note 的向量计算cos相似度,,再计算得到topk最相似的候选记忆Note 。
第二步,对于所有的候选记忆Note,我们再用采用精心设计的prompt通过大模型来分析两个Note之间是否有关联关系。
最终得到了的所有关联Note,用数组来存储起来:
这种方法,首先借助文本相似度筛选出来候选Note,不用穷举计算所有Note,更加高效。第二步借助LLM的能力,能够更精细化的分析两个Note之间是否有关系,弥补了只使用文本相似度的不足。
因为大模型能够分析出更多关系,比如隐晦的模式、因果关系和概念上的关联等,这些关系通过文本相似度都无法实现。
具体的prompt:
3.记忆进化(Memory Evolution)
经过上面的步骤,我们构建了所有记忆Note的“边”,A-MEM基于他们的文本描述和检索到的关联Note来决定是否更新每个Note的内容。即对于每一个记忆Note,以及他们的邻近节点列表,通过精心设计的prompt用大模型来决定是不是更新的上下文、关键词和标签,得到新的记忆Note ,替换掉原本的Note ;
这个过程是在后台持续进行的,并有可能产生新的连接。随着系统持续运行,整个记忆Note 的网络持续更新,能够产生更高维度的关联关系,并能带来更丰富的知识。
具体的promtp:
4.检索关联记忆(Retrieve Relative Memory)
检索过程就是简单的计算k近邻,我们采用相同的文本编码器,对用户的query进行编码,然后与所有以及Note 的向量表示计算文本相似度,取topk。然后将检索到的记忆Note 的内容拼接到当前的promot中,回答用户问题。具体prompt为:
参考: