|
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-left: none;padding: 1em;border-radius: 8px;color: rgba(0, 0, 0, 0.5);background: rgb(247, 247, 247);margin: 0px 8px 2em;">

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">这两天在看大模型长时记忆的一些实现方法,然后看到了这样一个开源项目:MemGPT,又称 Memory GPT,专门用来管理大模型的记忆。这可能是目前管理大模型记忆的最专业的框架和思路了。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-left: none;padding: 1em;border-radius: 8px;color: rgba(0, 0, 0, 0.5);background: rgb(247, 247, 247);margin: 2em 8px;">GitHub:https://github.com/cpacker/MemGPT ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">今天我们来看下 MemGPT 背后的实现原理,看看大佬是怎么实现大模型记忆管理和长时记忆的。并上手体验一下。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 2em auto 1em;padding-right: 1em;padding-left: 1em;border-bottom: 2px solid rgb(15, 76, 129);color: rgb(63, 63, 63);">0. 实现原理ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-left: none;padding: 1em;border-radius: 8px;color: rgba(0, 0, 0, 0.5);background: rgb(247, 247, 247);margin: 2em 8px;">论文原文:MemGPT: Towards LLMs as Operating Systems ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">从论文的题目:MemGPT: Towards LLMs as Operating Systems,就可以看出大体的实现思路,它借鉴传统操作系统虚拟内存管理的方式,通过对记忆分层,智能管理不同存储层,在LLM的有限上下文窗口内提供扩展的上下文。在文档分析和多会话聊天两个领域中,MemGPT克服了现代LLM的上下文窗口限制,提高了性能。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 4em auto 2em;padding-right: 0.2em;padding-left: 0.2em;background: rgb(15, 76, 129);color: rgb(255, 255, 255);">0.1 记忆分层ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">MemGPT受操作系统启发,实现了一个多级存储架构。在这个架构中,有两种主要的内存类型:主上下文(类似于主内存/物理内存/RAM)和外部上下文(类似于磁盘内存/磁盘存储)。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 4em auto 2em;padding-right: 0.2em;padding-left: 0.2em;background: rgb(15, 76, 129);color: rgb(255, 255, 255);">0.2 数据移动MemGPT 通过 LLM 的 Function Calling 能力来协调主上下文和外部上下文之间的数据移动。Memory的编辑和检索完全是自主的:MemGPT 根据当前上下文自主更新和搜索自己的 Memory。例如,当上下文变得特别长时,会自动将多余的上下文经过整理后保存进持久化地址中。 下面代码是超过限制Token时的判断,返回active_memory_warning,外部根据此标志可以进行相应处理: #Checkthememorypressureandpotentiallyissueamemorypressurewarning current_total_tokens=response.usage.total_tokens active_memory_warning=False #Wecan'tdosummarizelogicproperlyifcontext_windowisundefined ifself.agent_state.llm_config.context_windowisNone: #Fallbackifforsomereasoncontext_windowismissing,justsettothedefault print(f"{CLI_WARNING_PREFIX}couldnotfindcontext_windowinconfig,settingtodefault{LLM_MAX_TOKENS['DEFAULT']}") print(f"{self.agent_state}") self.agent_state.llm_config.context_window=( LLM_MAX_TOKENS[self.model]if(self.modelisnotNoneandself.modelinLLM_MAX_TOKENS)elseLLM_MAX_TOKENS["DEFAULT"] ) ifcurrent_total_tokens>MESSAGE_SUMMARY_WARNING_FRAC*int(self.agent_state.llm_config.context_window): printd( f"{CLI_WARNING_PREFIX}lastresponsetotal_tokens({current_total_tokens})>{MESSAGE_SUMMARY_WARNING_FRAC*int(self.agent_state.llm_config.context_window)}" ) #Onlydeliverthealertifwehaven'talready(thisperiod) ifnotself.agent_alerted_about_memory_pressure: active_memory_warning=True self.agent_alerted_about_memory_pressure=True#it'suptotheouterlooptohandlethis else: printd( f"lastresponsetotal_tokens({current_total_tokens})<{MESSAGE_SUMMARY_WARNING_FRAC*int(self.agent_state.llm_config.context_window)}" )

下图是从Memory处理和移动到组装成完整的Prompt的过程描述,重点看一下: 
MemGPT 将 主上下文 分为三个连续部分:系统指令、工作上下文和FIFO队列。 看它源码中的这部分Prompt,太复杂了...... (如果每次都需要将这个Prompt告诉大模型,让其生成相应的Function Calling,那这成本是不是有点高了?)

图中有个箭头最多的,Function Executor,用来读写各种外部Memory,也就是实现Memory的增删改查,例如将外部上下文转移到主上下文中使用。 部分Function定义如下:包括修改主上下文,检索外部上下文等,都是通过这些Fuction来进行的。而这些Function的调用,是注册到LLM里面,由LLM根据上下文生成的Function Calling调用。

论文先看到这里,里面实现的细节非常多且复杂,需要花时间详细并且反复读才行。 用我自己的话和理解总结一下整体的实现思路: 将上下文分为主上下文和外部上下文,外部上下文存储在磁盘或向量数据库中,需要时进行检索,然后填充到主上下文中去使用。至于什么时候应该用外部上下文,什么时候应该修改主上下文,这由LLM根据当时的主上下文生成Function Calling,通过Function来去调用相应的函数实现上下文的变换。这样,外部上下文都是分散的,检索出来的也都是与当前主上下文相关的,所以就解决了长上下文时比较旧的内容丢失的问题。 1. 快速上手1.1 普通玩法1.1.1 环境安装pipinstall-Upymemgpt 然后 memgptrun 运行界面如下: 
当然你可以输入一些命令来使用高级一点的玩法: /exit:ExittheCLI /attach:Attachaloadeddatasourcetotheagent /save:Saveacheckpointofthecurrentagent/conversationstate /dump:Viewthecurrentmessagelog(seethecontentsofmaincontext) /dump<count>:Viewthelastmessages(allifisomitted) /memory rintthecurrentcontentsofagentmemory /pop:Undothelastmessageintheconversation /pop<count>:Undothelastmessagesintheconversation.Itdefaultsto3,whichusuallyisoneturnaroundintheconversation /retry opsthelastanswerandtriestogetanotherone /rethink<text>:Willreplacetheinnerdialogofthelastassistantmessagewiththe<text>tohelpshapingtheconversation /rewrite:Willreplacethelastassistantanswerwiththegiventexttocorrectorforcetheanswer /heartbeat:Sendaheartbeatsystemmessagetotheagent /memorywarning:Sendamemorywarningsystemmessagetotheagent
这些命令具体怎么实现的,可以看 MemGPT\memgpt\main.py 中的源码: 
这种玩法就不过多介绍了。下面重点介绍进阶玩法,开发的方式。
1.2 进阶玩法1.2.1 源码安装还是老规矩,用源码安装,方便以后断点调试和学习。 gitclonehttps://github.com/cpacker/MemGPT.git cdMemGPT pipinstall-e.
1.2.2 上手代码在运行前,一定记得将OpenAI的Key和代理设置到环境变量中,例如下面的load_dotenv
#加载.env到环境变量 fromdotenvimportload_dotenv,find_dotenv _=load_dotenv(find_dotenv()) frommemgptimportcreate_client
#Connecttotheserverasauser client=create_client()
#Createanagent agent_info=client.create_agent( name="my_agent", persona="Youareafriendlyagent.", human="Bobisafriendlyhuman." )
#Sendamessagetotheagent messages=client.user_message(agent_id=agent_info.id,message="Hello,agent!")
1.2.3 运行效果
无法重复创建相同名字的Agent,可能是一个名字一个存储地址?这样实现的Agent整体的持久化存储? 
|