1 MemGPT: Towards LLMs as Operating Systems

论文地址:MemGPT: Towards LLMs as Operating Systems
代码地址:https://github.com/letta-ai/letta

1.1 MemGPT

  MemGPT(MemoryGPT)借鉴传统操作系统的分层内存管理思想(物理内存与磁盘间的分页机制),通过 “虚拟上下文管理” 技术,让固定上下文窗口的 LLM 具备 “无限上下文” 的使用错觉。其核心逻辑是:将 LLM 的上下文窗口视为 “物理内存”,外部存储视为 “磁盘”,通过函数调用实现信息在两者间的 “分页调入 / 调出”,同时管理控制流以优化上下文利用效率。

  MemGPT 通过多层级内存设计与功能模块协作,实现上下文的智能管理,包括:

  • 主上下文(Main Context):类比RAM。LLM 的Prompt Tokens,可被 LLM 推理直接访问,分为三部分:
    • 系统指令:只读静态内容,包含 MemGPT 控制流、内存层级用途、函数调用规则;
    • 工作上下文:固定大小可读写区块,存储用户关键信息(如偏好、事实)、智能体角色信息;
    • FIFO 队列:滚动存储消息历史(用户 - 智能体对话、系统提示、函数调用记录),头部含已淘汰消息的递归摘要。
  • 外部上下文(External Context):类比磁盘。超出主上下文窗口的信息,需通过函数调用调入主上下文才能使用,包含两类存储:
    • 召回存储(Recall Storage):消息数据库,由队列管理器自动写入对话历史,支持分页搜索与重新调入主上下文;
    • 归档存储(Archival Storage):支持向量搜索的数据库(如 PostgreSQL+pgvector),存储长文档、键值对等大规模数据,需显式函数调用访问。

核心功能模块

  • 队列管理器(Queue Manager)
    • 消息处理:接收新消息并追加到 FIFO 队列,拼接提示词令牌触发 LLM 推理,同时将消息与推理结果写入召回存储;
    • 上下文溢出控制:当主上下文令牌数达到 “警告阈值”(如窗口的 70%),插入 “内存压力” 系统提示,引导 LLM 将关键信息存入工作上下文 / 归档存储;达到 “刷新阈值”(如 100%)时,淘汰部分消息(如 50% 窗口),生成新递归摘要并写入 FIFO 头部,淘汰消息永久保留在召回存储。
  • 函数执行器(Function Executor)
    • 解析 LLM 生成的输出,执行内存管理函数(如搜索外部存储、修改工作上下文、分页调入数据),并将执行结果(含错误信息)反馈给 LLM,形成 “决策 - 执行 - 反馈” 闭环。同时支持分页机制,避免单次检索结果溢出主上下文。
  • 控制流与函数链(Control Flow & Function Chaining)
    • 事件触发推理:用户消息、系统警告、定时任务等事件均会触发 LLM 推理,事件经解析后转为文本追加到主上下文;
    • 多函数顺序执行:通过 “request heartbeat=true” 标志,支持 LLM 在返回用户响应前,连续调用多个函数(如多页文档检索、多跳键值对查询),提升复杂任务处理能力。

1.2 源码分析

1.2.1 内存层次结构 — 主内存 / 归档 / 检索层

  Memory hierarchy(论文里的主内存 / 外部存储分层)是通过 Memory Blocks + Archival Memory 来实现的:

  • 核心上下文(主内存)由 memory blocks 组成,每个 block 都是可编辑、可共享的小单元,在 client.blocks.create() 与 agent 的 block_ids 字段绑定后,会被拼接进 agent 的 in-context prompt 中。
agent_state = client.agents.create(memory_blocks=[{"label": "human","value": "The human's name is Bob the Builder.","limit": 5000},{"label": "persona","value": "My name is Sam, the all-knowing sentient AI.","limit": 5000}],model="openai/gpt-4o-mini",embedding="openai/text-embedding-3-small"
)
  • 外部上下文:超出 context 的长期存储(外部存储层)则通过 filesystem / folders / passages 模块实现,文件内容会被分段、索引、存档,必要时由agent通过工具调用再取回到主内存。这样 Letta 就把 “有限的 prompt context” 和 “无限的外部持久存储” 分层管理。
# create the folder
folder = client.folders.create(name="my_folder",embedding_config=embedding_config
)# upload a file into the folder
job = client.folders.files.upload(folder_id=folder.id,file=open("my_file.txt", "rb")
)

MemoryBlock
  MemGPT中定义了一些系列的Memory,都是基于MemoryBlock来实现的。而外部Memory直接通过FileProcess来实现。

class BasicBlockMemory(Memory):"""BasicBlockMemory is a basic implemention of the Memory class, which takes in a list of blocks and links them to the memory object. These are editable by the agent via the core memory functions.Attributes:memory (Dict[str, Block]): Mapping from memory block section to memory block.Methods:core_memory_append: Append to the contents of core memory.core_memory_replace: Replace the contents of core memory."""def __init__(self, blocks: List[Block] = []):"""Initialize the BasicBlockMemory object with a list of pre-defined blocks.Args:blocks (List[Block]): List of blocks to be linked to the memory object."""super().__init__(blocks=blocks)

调度
  agent 的核心调度器,其中 内存调度(memory hierarchy 的 orchestrator) 主要体现在 “重建上下文窗口” 的逻辑,也就是把 Memory Blocks(主内存)、消息历史 和 归档/摘要 拼接起来,送进 LLM。

# letta/agents/letta_agent.pyclass LettaAgent:...async def step(...):# 每次 agent 前进一轮,都会检查/更新上下文...await self.rebuild_context_window()...async def rebuild_context_window(self):"""这里是核心的内存调度逻辑:1. 从数据库/存储里取出 agent 的 memory blocks(主内存块)2. 加载最近的对话消息(短期记忆)3. 检查上下文 token 使用量- 如果超过阈值,调用 summarizer 做摘要/驱逐4. 把这些拼接成 prompt,交给模型调用"""blocks = await self.get_attached_blocks()messages = await self.load_recent_messages()# 判断 token 是否超限if self.exceeds_context_limit(blocks, messages):summarized = await self.summarizer.summarize(messages)messages = summarized# 构造最终的上下文self.context = self.compose_context(blocks, messages)

摘要
  当上下文压力过大时,会通过LLM对内存进行摘要或驱逐,具体摘要的PE如下:

WORD_LIMIT = 100
SYSTEM = f"""Your job is to summarize a history of previous messages in a conversation between an AI persona and a human.
The conversation you are given is a from a fixed context window and may not be complete.
Messages sent by the AI are marked with the 'assistant' role.
The AI 'assistant' can also make calls to tools, whose outputs can be seen in messages with the 'tool' role.
Things the AI says in the message content are considered inner monologue and are not seen by the user.
The only AI messages seen by the user are from when the AI uses 'send_message'.
Messages the user sends are in the 'user' role.
The 'user' role is also used for important system events, such as login events and heartbeat events (heartbeats run the AI's program without user action, allowing the AI to act without prompting from the user sending them a message).
Summarize what happened in the conversation from the perspective of the AI (use the first person from the perspective of the AI).
Keep your summary less than {WORD_LIMIT} words, do NOT exceed this word limit.
Only output the summary, do NOT include anything else in your output."""

共享内存
  共享内存的实现比较简单就是将内存块的id添加到agent的block_ids中即可。

# create a shared memory block
shared_block = client.blocks.create(label="organization",description="Shared information between all agents within the organization.",value="Nothing here yet, we should update this over time."
)# create a supervisor agent
supervisor_agent = client.agents.create(model="anthropic/claude-3-5-sonnet-20241022",embedding="openai/text-embedding-3-small",# blocks created for this agentmemory_blocks=[{"label": "persona", "value": "I am a supervisor"}],# pre-existing shared block that is "attached" to this agentblock_ids=[shared_block.id],
)# create a worker agent
worker_agent = client.agents.create(model="openai/gpt-4.1-mini",embedding="openai/text-embedding-3-small",# blocks created for this agentmemory_blocks=[{"label": "persona", "value": "I am a worker"}],# pre-existing shared block that is "attached" to this agentblock_ids=[shared_block.id],
)

1.2.2 队列管理器

  MemGPT的队列管理器(queue manager) 对应的就是 对话消息队列 / buffer 的管理逻辑——也就是让 agent 的上下文只保留一部分最近的消息,把溢出的内容清理、归档或摘要。这个机制跟 MemGPT 论文里的 FIFO 队列 + 内存压力控制 是一一对应的。

  1. 消息存储。所有对话消息存到数据库里(Postgres/SQLite,表结构在 messages 表),而 agent 每次运行时不会直接加载全部,而是取最近一段窗口。
  2. 上下文重建时检查队列。从数据库里取最新的 N 条消息(相当于队尾元素)。如果 token 超限,调用 summarizer 对旧消息做摘要,然后替换队首部分(保持队列容量不爆炸)。
async def _rebuild_context_window(self, summarizer: Summarizer, in_context_messages: List[Message], letta_message_db_queue: List[Message]
) -> None:new_letta_messages = await self.message_manager.create_many_messages_async(letta_message_db_queue, actor=self.actor)# TODO: Make this more general and configurable, less brittlenew_in_context_messages, updated = await summarizer.summarize(in_context_messages=in_context_messages, new_letta_messages=new_letta_messages)await self.agent_manager.update_message_ids_async(agent_id=self.agent_id, message_ids=[m.id for m in new_in_context_messages], actor=self.actor)
  1. 驱逐/摘要策略。当消息数量或 token 数超过阈值时,触发 partial evict buffer summarization,把旧消息合并成一条 “总结消息”,再继续放回队首。
async def _partial_evict_buffer_summarization(self,in_context_messages: List[Message],new_letta_messages: List[Message],force: bool = False,clear: bool = False,) -> Tuple[List[Message], bool]:"""Summarization as implemented in the original MemGPT loop, but using message count instead of token count.Evict a partial amount of messages, and replace message[1] with a recursive summary.Note that this can't be made sync, because we're waiting on the summary to inject it into the context window,unlike the version that writes it to a block.Unless force is True, don't summarize.Ignore clear, we don't use it."""all_in_context_messages = in_context_messages + new_letta_messagesif not force:logger.debug("Not forcing summarization, returning in-context messages as is.")return all_in_context_messages, False# First step: determine how many messages to retaintotal_message_count = len(all_in_context_messages)assert self.partial_evict_summarizer_percentage >= 0.0 and self.partial_evict_summarizer_percentage <= 1.0target_message_start = round((1.0 - self.partial_evict_summarizer_percentage) * total_message_count)logger.info(f"Target message count: {total_message_count}->{(total_message_count - target_message_start)}")# The summary message we'll insert is role 'user' (vs 'assistant', 'tool', or 'system')# We are going to put it at index 1 (index 0 is the system message)# That means that index 2 needs to be role 'assistant', so walk up the list starting at# the target_message_count and find the first assistant messagefor i in range(target_message_start, total_message_count):if all_in_context_messages[i].role == MessageRole.assistant:assistant_message_index = ibreakelse:raise ValueError(f"No assistant message found from indices {target_message_start} to {total_message_count}")# The sequence to summarize is index 1 -> assistant_message_indexmessages_to_summarize = all_in_context_messages[1:assistant_message_index]logger.info(f"Eviction indices: {1}->{assistant_message_index}(/{total_message_count})")# Dynamically get the LLMConfig from the summarizer agent# Pretty cringe code here that we need the agent for this but we don't use itagent_state = await self.agent_manager.get_agent_by_id_async(agent_id=self.agent_id, actor=self.actor)# TODO if we do this via the "agent", then we can more easily allow toggling on the memory block versionsummary_message_str = await simple_summary(messages=messages_to_summarize,llm_config=agent_state.llm_config,actor=self.actor,include_ack=True,)

1.2.3 函数执行器

  MemGPT的函数执行器是每个Agent的基础能力,在处理LLM的响应时进行函数调用。函数的具体执行是抛到了不同的Exector里面。

@trace_methodasync def _handle_ai_response()#省略一些检查和参数1.  Execute the tool (or synthesize an error result if disallowed)tool_rule_violated = tool_call_name not in valid_tool_names and not is_approvalif tool_rule_violated:tool_execution_result = _build_rule_violation_result(tool_call_name, valid_tool_names, tool_rules_solver)else:# Track tool execution timetool_start_time = get_utc_timestamp_ns()tool_execution_result = await self._execute_tool(tool_name=tool_call_name,tool_args=tool_args,agent_state=agent_state,agent_step_span=agent_step_span,step_id=step_id,)

1.2.4 控制流与函数链

  MemGPT的控制流与函数链是支撑Agent具备“可编程对话逻辑”的关键。核心由 step() 驱动,每次调用 agent.step() 就是一次事件循环。基本流程为:LLM输出 → 调度器解析 → 执行器执行 → 队列更新 → 下一轮继续。伪代码为:

# letta/agents/letta_agent.pyasync def step(self, user_input=None):# 1. 构建上下文await self.rebuild_context_window()1. 调用模型model_output = await self.model.generate(self.context, user_input)# 3. 根据输出类型决定控制流if model_output.function_call:response = await self.execute_function_call(model_output.function_call)else:response = model_output.text# 4. 更新队列(短期记忆)await self.message_queue.enqueue(response)return response

1.3 要点总结

  • 内存层次(Memory Hierarchy):Main Context Memory,External Memory和Archive / Summarized Memory;
  • 内存调度:高频访问内容留在上下文,低频内容丢到外部存储;
  • 队列管理:管理 输入消息流 与 函数调用结果,确保 LLM 每次看到的上下文是“最有用”的子集。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96539.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96539.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/96539.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MICAPS:气象信息综合分析与处理系统概述

1.概述 说明:Meteorological Information Comprehensive Analysis and Process System 中文意思:气象信息综合分析处理系统。它是中国气象局开发的一套气象数据分析、处理和可视化系统,用于气象资料的收集、整理、分析和发布。 2.MICAPS 的用途 说明: 数据收集:接收来自…

MySQL-day2_02

MySQL-day2&#xff08;四&#xff09;排序&#xff08;五&#xff09;聚合函数一、count 总记录数二、max 最大值三、min 最小值四、sum 求和五、avg 平均值&#xff08;六&#xff09;数据分组一、分组二、分组后的数据筛选&#xff08;七&#xff09;数据分页显示一、获取部…

HarmonyOS应用开发:深入ArkUI声明式开发范式与最佳实践

HarmonyOS应用开发&#xff1a;深入ArkUI声明式开发范式与最佳实践 引言 随着HarmonyOS 4.0的发布及API 12的推出&#xff0c;华为的分布式操作系统进入了全新的发展阶段。ArkUI作为HarmonyOS应用开发的核心框架&#xff0c;其声明式开发范式&#xff08;Declarative Paradigm&…

Claude-Flow AI协同开发:钩子系统与 GitHub 集成

5.1 思维认知框架&#xff1a;从“开发助手”到“DevOps 智能体” 在此之前&#xff0c;我们将 Claude-Flow 视为一个强大的 “开发助手 (Development Assistant)” &#xff0c;它在编码、测试、重构等环节为我们提供支持。现在&#xff0c;我们需要再次进行思维升级&#xff…

DigitalOcean Kubernetes 现已支持 Gateway API 托管服务

在 DigitalOcean Kubernetes 集群中管理流量&#xff0c;一直以来主要依赖 Ingress。虽然能满足基本需求&#xff0c;但在灵活性、角色分离和高级路由方面仍存在局限。今天&#xff0c;我们很高兴迎来新的改变。 我们正式宣布&#xff0c;Kubernetes Gateway API 托管服务现已…

聚铭网络入选数世咨询《中国数字安全价值图谱》“日志审计”推荐企业

近日&#xff0c;国内知名数字安全咨询机构数世咨询正式发布《中国数字安全价值图谱》。聚铭网络凭借领先的技术实力与出色的市场表现&#xff0c;成功入选“日志审计”领域重点推荐企业&#xff0c;彰显了在该赛道的专业认可与品牌影响力。关于《中国数字安全价值图谱》 在当下…

豆包、Kimi、通义千问、DeepSeek、Gamma、墨刀 AI”六款主流大模型(或 AI 平台)生成 PPT 的完整流程

、先厘清 3 个概念&#xff0c;少走弯路大模型 ≠ PPT 软件豆包、Kimi、通义千问、DeepSeek 本身只负责“出大纲/出文案”&#xff0c;真正的“一键配图排版”要靠官方 PPT 助手或第三方平台&#xff08;博思 AiPPT、迅捷 AiPPT、Gamma、墨刀 AI 等&#xff09;。两条主流技术路…

Redis哈希(Hash):适合存储对象的数据结构,优势与坑点解析

Redis哈希&#xff08;Hash&#xff09;&#xff1a;适合存储对象的数据结构&#xff0c;优势与坑点解析 1. Redis哈希概述 1.1 什么是Redis哈希 Redis哈希&#xff08;Hash&#xff09;是一种映射类型&#xff08;Map&#xff09;&#xff0c;由多个字段值对&#xff08;fi…

Python的uv包管理工具使用

一、简介 uv是一个继Python版本管理、Python包管理、项目管理、虚拟环境管理于一体的工具&#xff0c;由于底层是用Rust编写的&#xff0c;uv的执行速度非常快。 安装 pip install uv镜像源设置 uv默认安装包是从pypi上下载的&#xff0c;速度比较慢。我们可以设置镜像源&#…

JavaScript事件机制与性能优化:防抖 / 节流 / 事件委托 / Passive Event Listeners 全解析

目标&#xff1a;把“为什么慢、卡顿从哪来、该怎么写”一次说清。本文先讲事件传播与主线程瓶颈&#xff0c;再给出四件法宝&#xff08;防抖、节流、事件委托、被动监听&#xff09;&#xff0c;最后用一套可复制的工具函数 清单收尾。1&#xff09;先理解“为什么会卡”&am…

【Chrome】chrome 调试工具的network选项卡,如何同时过滤出doc js css

通过类型按钮快速筛选&#xff08;更直观&#xff09;在 Network 选项卡中&#xff0c;找到顶部的 资源类型按钮栏&#xff08;通常在过滤器搜索框下方&#xff09;。按住 Ctrl 键&#xff08;Windows/Linux&#xff09;或 Command 键&#xff08;Mac&#xff09;&#xff0c;同…

Elasticsearch (ES)相关

在ES中&#xff0c;已经有Term Index&#xff0c;那还会走倒排索引吗 你这个问题问得很到位 &#x1f44d;。我们分清楚 Term Index 和 倒排索引 在 Elasticsearch (ES) 里的关系&#xff1a;1. 倒排索引&#xff08;Inverted Index&#xff09; 是 Lucene/ES 检索的核心。文档…

pre-commit run --all-files 报错:http.client.RemoteDisconnected

报错完整信息初步原因是这样 报错是 Python 的 http.client.RemoteDisconnected&#xff0c;意思是 在用 urllib 请求远程 URL 时&#xff0c;远程服务器直接断开了连接&#xff0c;没有返回任何响应。在你的堆栈里&#xff0c;它出现在 pre-commit 尝试安装 Golang 环境的时候…

【C++】STL·List

1. list的介绍及使用 1.1list介绍 List文档介绍 1.2 list的使用 list中的接口比较多&#xff0c;此处类似&#xff0c;只需要掌握如何正确的使用&#xff0c;然后再去深入研究背后的原理&#xff0c;已 达到可扩展的能力。以下为list中一些常见的重要接口。 1.2.1 list的构造…

图论2 图的数据结构表示

目录 一 图的数据结构表示 1 邻接矩阵&#xff08;Adjacency Matrix&#xff09; 2 邻接表&#xff08;Adjacency List&#xff09; 3 边列表&#xff08;Edge List&#xff09; 4 十字链表&#xff08;Orthogonal List / Cross-linked List, 十字链表&#xff09; 5 邻接…

在Excel中删除大量间隔空白行

在 Excel 中删除大量间隔空白行&#xff0c;可使用定位空值功能来快速实现。以下是具体方法&#xff1a;首先&#xff0c;选中包含空白行的数据区域。可以通过点击数据区域的左上角单元格&#xff0c;然后按住鼠标左键拖动到右下角最后一个单元格来实现。接着&#xff0c;按下快…

【C 学习】10-循环结构

“知道做不到就是不知道”一、条件循环1. while只要条件为真&#xff08;true&#xff09;&#xff0c;就会重复执行循环体内的代码。while (条件) {// 循环体&#xff08;要重复执行的代码&#xff09; }//示例 int i 1; while (i < 5) {printf("%d\n", i);i; …

音视频的下一站:协议编排、低时延工程与国标移动化接入的系统实践

一、引言&#xff1a;音视频的基础设施化 过去十年&#xff0c;音视频的两条主线清晰可辨&#xff1a; 娱乐驱动&#xff1a;直播、电商、短视频把“实时观看与互动”变成高频日常。 行业扩展&#xff1a;教育、会议、安防、政务逐步把“可用、可管、可控”引入产业系统。 …

SAM-Med3D:面向三维医疗体数据的通用分割模型(文献精读)

1) 深入剖析:核心方法与图示(Figure)逐一对应 1.1 单点三维提示的任务设定(Figure 1) 论文首先将3D交互式分割的提示形式从“2D逐片(每片1点,共N点)”切换为“体素级单点(1个3D点)”。Figure 1直观对比了 SAM(2D)/SAM-Med2D 与 SAM-Med3D(1点/体) 的差异:前两者…

【Spring】原理解析:Spring Boot 自动配置进阶探索与优化策略

一、引言在上一篇文章中&#xff0c;我们对 Spring Boot 自动配置的基本原理和核心机制进行了详细的分析。本文将进一步深入探索 Spring Boot 自动配置的高级特性&#xff0c;包括如何进行自定义扩展、优化自动配置的性能&#xff0c;以及在实际项目中的应用优化策略。同时&…