跳到主要内容
ReMe 深度解析:面向 AI 智能体的模块化记忆管理工具包设计与实现 | 极客日志
Python AI 算法
ReMe 深度解析:面向 AI 智能体的模块化记忆管理工具包设计与实现 综述由AI生成 ReMe 是 AgentScope 团队开源的模块化记忆管理工具包,将记忆管理视为智能体任务。它借鉴认知科学分层模型,区分长期与短期记忆。核心创新包括 MemoryNode 数据模型中的 when_to_use 字段,实现检索意图与存储内容解耦;四种记忆类型(个人、程序性、工具、工作)的精细化设计;基于 ReAct Agent 的执行引擎及 Flow 编排能力。相比传统 RAG,ReMe 通过 LLM 驱动的智能提取、语义去重及上下文压缩机制,显著提升了智能体的跨会话学习与任务执行效率。
灵魂伴侣 发布于 2026/4/6 更新于 2026/5/21 27 浏览
在大语言模型驱动的 AI 智能体中,"记忆"(Memory)是决定智能体能否跨会话学习、长期适应用户需求的关键能力。ReMe(Remember Me, Refine Me)是由 AgentScope 团队开源的一款面向智能体的模块化记忆管理工具包,其核心理念是将记忆管理本身视为一项智能体任务 ,而非简单的数据存取操作。本文将从架构设计、记忆分类体系、核心数据模型、执行引擎及工程实现等多个维度,对 ReMe 的记忆体设计进行深度剖析。
一、设计背景与核心理念
在传统的 RAG(Retrieval-Augmented Generation)系统中,"记忆"通常等价于"向量检索"——将文本切块、生成嵌入向量、存入向量数据库。然而,对于一个真正具备持续学习能力的 AI 智能体而言,记忆问题远比简单的文本检索复杂得多。
ReMe 的设计者借鉴了认知科学中人类记忆的分层模型 ,将智能体的记忆体系形式化为:
Agent Memory = Long-Term Memory + Short-Term Memory = (Personal + Procedural + Tool) Memory + Working Memory
其中:
长期记忆 持久化存储在向量数据库中,跨会话保留——类似于人类的"显式记忆";
**短期记忆(工作记忆)**管理当前会话上下文,通过压缩与卸载机制防止 token 溢出——类似于人类的"工作记忆容量"。
这种分层模型并非概念上的简单对齐,而是深入到代码层面的系统性设计,指导着整个工具包的架构组织。
二、整体架构概览
ReMe 的系统架构可以划分为四个清晰的层次:
┌──────────────────────────────────────────────────────────────┐
│ 用户入口层 │
│ ReMe / ReMeApp(Python API & CLI) │
├──────────────────────────────────────────────────────────────┤
│ 应用编排层 │
│ Application → ServiceContext → Flow 编排引擎 │
├──────────────────────────────────────────────────────────────┤
│ 记忆代理层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ ReMeSummarizer│ │ ReMeRetriever│ │ 统一调度器 │ │
│ └──────┬───────┘ └──────┬───────┘ │ DelegateTask │ │
│ │ │ │ └──────────────┘ │
│ ┌──────┴──────────────────┴──────┐ │
│ │ PersonalSummarizer/Retriever │ │
│ │ ProceduralSummarizer/Retriever│ │
│ │ ToolSummarizer/Retriever │ │
│ └────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ BaseVectorStore │ BaseEmbeddingModel │ BaseLLM │ FileStore │
│ (Local/ChromaDB/Elasticsearch) │
└──────────────────────────────────────────────────────────────┘
这一分层设计有几个值得关注的特点:
记忆代理层 是整个系统的核心创新——记忆的提取与检索不是硬编码的规则管线(pipeline),而是由 LLM 驱动的 ReAct Agent 自主完成的智能流程;
基础设施层 采用抽象接口模式(BaseVectorStore、BaseLLM 等),支持多种后端实现,保证了系统的可插拔性;
Flow 编排引擎 通过操作符组合语法(>> 顺序执行、| 并行执行),支持灵活的工作流定义。
三、核心数据模型:MemoryNode
MemoryNode 是 ReMe 整个记忆体系的基础数据结构,其字段设计反映了团队对"一条记忆应该包含什么信息"的深入思考:
( ):
memory_id:
memory_type: MemoryType
memory_target:
when_to_use:
content:
message_time:
ref_memory_id:
time_created:
time_modified:
author:
score:
vector: [ ]
metadata:
class
MemoryNode
BaseModel
str
str
str
str
str
str
str
str
str
float
list
float
dict
3.1 when_to_use —— 检索意图与存储内容的解耦 when_to_use 是 MemoryNode 中最具设计巧思的字段。要理解它解决了什么问题,需要先看清传统向量检索的一个固有缺陷。
传统向量检索的困境 在常规 RAG 系统中,一条知识被存进向量库时,系统直接把知识内容本身 转成向量嵌入。检索时,拿用户的查询和这些向量做相似度匹配。
然而,用户提问的方式和知识本身的表述方式,往往存在巨大的词汇和语义鸿沟 。
记忆内容(content) :"在 AppWorld 中执行多步任务时,应先通过 list_apis 获取接口列表,再逐个用 check_params 验证约束,最后用 chain_call 构造调用链。成功率可提升约 15%。"
这条记忆非常有价值。但用户实际的提问可能是这样的:
"我要在 AppWorld 里完成一个需要多个 API 配合的任务,怎么规划?"
对比来看——用户的查询说的是"怎么规划"、"API 配合";而记忆内容说的是"list_apis"、"check_params"、"chain_call"、"成功率 15%"。一个是提问语气 ,一个是技术操作步骤 。虽然语义上相关,但向量相似度可能并不高,检索很容易漏掉。
when_to_use 的解决思路when_to_use 的核心思路可以概括为:给每条记忆额外贴一张"使用场景标签" 。这张标签描述的不是记忆的内容,而是"这条记忆适合在什么场景下被使用?"
对于前面的例子,加上 when_to_use 后就变成了:
字段 内容 when_to_use(场景标签)"当需要在 AppWorld 中规划多 API 协作的任务执行策略时" content(实际内容)"应先通过 list_apis 获取接口列表,再用 check_params 验证…"
现在检索时,系统是拿用户的查询和 when_to_use 做向量匹配 ,而不是和 content 匹配。when_to_use 的措辞天然更接近"用户会怎么问这个问题",匹配度会高得多。匹配上之后,系统再把 content(具体操作步骤)返回给用户。
图书馆索引卡的比喻 ┌──────────────────────────────────────────────┐
│ 索引卡(when_to_use) │
│ ────────────────────────────── │
│ "当读者想了解二战期间太平洋战场的 │
│ 转折点时,推荐查阅此书" │
│ │
│ 实际书籍(content) │
│ ────────────────────────────── │
│ "1942 年 6 月,中途岛海战爆发。美军凭借 │
│ 情报优势,成功伏击日军四艘航母... │
│ 此战被视为太平洋战争的转折点..." │
└──────────────────────────────────────────────┘
读者(用户)走进图书馆问"我想了解太平洋战争的关键节点"
图书管理员翻的是索引卡 (when_to_use),不是逐页搜索书的正文
找到匹配的索引卡后,再把对应的书 (content)递给读者
更多实际场景示例 when_to_use: "当需要搜索最新新闻,且关键词包含中文时"
content: "使用 search_news 工具,设置 lang=zh-CN,max_results=10。避免使用 web_search,因为它对中文关键词的召回率只有 40%。"
如果没有 when_to_use,系统用 content 做检索——但 content 里全是参数名(lang=zh-CN)和技术细节,跟用户"帮我搜下关于 xxx 的中文新闻"的措辞完全不同,很可能检索不到。
when_to_use: "当遇到 API 调用超时错误时"
content: "采用指数退避重试策略:初始等待 1s,每次翻倍,最多重试 3 次。如果 3 次都失败,检查网络连通性后切换到备用 endpoint。"
用户的查询可能是"API 超时了怎么办"——跟 when_to_use ("当遇到 API 调用超时错误时") 高度匹配,但跟 content("指数退避"、"翻倍"、"备用 endpoint")的相似度就低得多。
代码层面的实现 在底层实现中,to_vector_node() 方法根据 when_to_use 是否为空,决定向量数据库实际存储哪段文本做检索:
def to_vector_node (self ) -> VectorNode:
if self .when_to_use:
vector_content = self .when_to_use
metadata["content" ] = self .content
else :
vector_content = self .content
return VectorNode(
vector_id=self .memory_id,
content=vector_content,
vector=self .vector,
metadata=metadata,
)
模式 向量数据库拿什么做检索 检索命中后返回什么 有 when_to_use when_to_use 的向量嵌入metadata["content"](真正的记忆内容)无 when_to_use content 的向量嵌入content(内容即检索锚点,传统 RAG 模式)
一句话总结:when_to_use 让"怎么找到这条记忆"和"这条记忆的实际内容"成为两段独立的文本。检索用前者,返回用后者。 这就是"检索意图与存储内容解耦"的含义。
3.2 自动化的 ID 生成与变更追踪
基于内容的 ID 生成 :memory_id 通过 SHA-256(content) 的前 16 位自动生成,确保相同内容的记忆具有稳定且唯一的标识;
变更时间的自动追踪 :当 content 或 when_to_use 字段被修改时,__setattr__ 拦截器自动更新 time_modified 并重新计算 memory_id。
这些细节虽小,但在大规模记忆管理中,它们有效避免了内容重复存储和手动维护时间戳的负担。
四、四种记忆类型详解
4.1 个人记忆(Personal Memory) 个人记忆用于捕获用户的偏好、习惯与个性化上下文,是实现"千人千面"交互的基础。
ReMe 在个人记忆的处理上采用了独特的两阶段设计(Two-Phase) :
阶段一(S1 — Memory Phase) :细粒度记忆片段的提取与去重。
对话轨迹 → 创建记忆草稿 → 向量检索历史相似记忆 → 对比去重 → 添加新记忆
这一阶段的核心工具是 add_draft_and_retrieve_similar_memory,它在一个原子操作中完成"草拟 + 检索"两件事——先为每条新记忆创建草稿,然后立即检索向量库中的相似历史记忆。LLM Agent 随后对比草稿与历史记忆,仅将不冗余的新记忆持久化。
在提示词工程上,ReMe 明确要求使用真实名称(如"Bob 喜欢喝咖啡")而非泛指(如"用户喜欢喝咖啡"),以保持记忆的具体性和可区分度。
阶段二(S2 — Profile Phase) :结构化用户画像的更新。
读取现有用户画像 → 分析最新对话 → 更新/添加 Profile 键值对
与细粒度记忆片段不同,用户画像采用结构化的 key-value 形式(如 name: Bob、occupation: engineer、preference: dark mode),提供更加稳定、全局性的用户特征描述。
这种"片段记忆 + 结构化画像"的双轨管理,使得系统既能在语义层面进行模糊匹配(通过向量检索),也能在结构层面进行精确查询(通过画像键值)。
4.2 程序性记忆(Procedural / Task Memory) 程序性记忆的目标是从任务执行轨迹中提取可复用的"How-To"知识。这在认知科学中对应"程序性记忆"——即"知道怎么做"的知识。
ReMe 的 ProceduralSummarizer 通过提示词工程,引导 LLM 从执行轨迹中聚焦于五类知识的提取:
知识类型 提取模板 示例 成功策略 "When doing X, approach Y works well because…" 在导航设置页面时,先获取 session token 效果更好 失败模式 "Avoid doing X when Y because it leads to…" 避免在未验证权限时直接调用写入 API 最佳实践 "Always check X before doing Y to ensure…" 执行删除操作前务必确认备份存在 工作流模式 "The optimal sequence for X is: step1 → step2 → step3" 任务规划的最优顺序是:分析→分解→验证→执行 问题 - 解决方案对 "When encountering X issue, the solution is Y" 遇到 API 超时时,采用指数退避重试
提示词中有一个值得注意的设计原则:明确区分"事实"与"程序" 。系统要求跳过纯事实描述(如"任务 X 的成功率是 72%"),只保留可操作的程序性知识(如"当成功率低于预期时,增加验证步骤可提升 6%")。
在实验验证方面,ReMe 在 Appworld 环境上使用 Qwen3-8B 模型进行了评测。引入任务记忆后,Pass@4 指标从 0.3285 提升至 0.3631(+3.46%);在 BFCL-V3 工具调用任务中,Pass@4 从 0.5955 提升至 0.6577(+6.22%)。
4.3 工具记忆(Tool Memory) 工具记忆是 ReMe 的一个差异化特性,旨在解决一个被广泛忽视的问题:智能体的工具使用效率是否可以通过历史经验持续优化?
ToolSummarizer 不仅记录工具调用的成功/失败结果,还综合考量多个维度:
成功率统计 :该工具的历史成功比例;
调用耗时 :平均响应时间;
Token 成本 :每次调用的 token 开销;
LLM-as-Judge 评估 :由 LLM 对工具调用的成功/失败进行定性分析;
参数优化模式 :从历史成功调用中学习最优参数配置。
工具记忆的产出是一份持续更新的"工具使用指南"——它不是静态的 API 文档,而是基于真实调用数据不断演化的活文档 。
在工具记忆基准测试中,引入记忆后工具选择的成功率提升了约 14.88%(从 0.672 到 0.772),这一改进完全来自数据驱动的参数优化和工具选择策略。
4.4 工作记忆(Working Memory) 工作记忆解决的是长运行智能体面临的实际问题:当对话或任务执行链超出 LLM 的上下文窗口时,如何在保留关键信息的前提下控制 token 消耗?
ReMe 提出了 消息卸载与重载(Message Offload & Reload) 机制,由三个核心组件协作实现:
(1)FbContextChecker — 上下文检查器
该组件持续监控消息序列的 token 总量。当总量超过 context_window_tokens - reserve_tokens 的阈值时,触发压缩流程。
其切割算法具备分裂轮次感知能力(Split Turn Detection) 。在典型的对话中,一个完整"轮次"由 User → Assistant 组成。当切割点恰好落在轮次中间(如 User → Assistant → [CUT] → Assistant → User)时,系统不会简单地截断,而是将该轮次分为两部分分别生成摘要,以避免信息丢失。
接收需要压缩的消息,通过 LLM 生成结构化的摘要。当存在分裂轮次时,它会生成两部分摘要:
History Summary :历史对话的整体摘要;
Turn Context :被分裂轮次的前缀部分的摘要。
当智能体需要回顾已卸载的内容时,可通过 grep_working_memory(全文搜索)和 read_working_memory(精确读取)按需重新载入相关信息。
这一设计的灵感来源于 OpenClaw 项目,在 ReMe 的终端 AI 聊天助手 ReMeCli 中得到了端到端的落地验证。
五、执行引擎:ReAct Agent 与任务委派
5.1 ReAct 循环 ReMe 的记忆代理构建在 ReAct(Reasoning + Acting) 模式之上。BaseReact 类实现了经典的推理 - 行动交替循环:
async def react (self, messages, tools ):
for step in range (max_steps):
assistant_message, should_act = await self ._reasoning_step(messages, tools)
if not should_act:
break
tool_results = await self ._acting_step(assistant_message, tools)
messages.extend(tool_results)
类层次结构为 BaseOp → BaseReact → BaseMemoryAgent → 具体 Summarizer/Retriever。每一层添加特定的记忆上下文(如 memory_type、memory_target、retrieved_nodes 等),形成了一个从通用到特化的继承链。
5.2 DelegateTask — 多记忆类型的统一调度 在实际场景中,一次对话可能同时涉及多个用户、多个任务类型的记忆操作。DelegateTask 工具实现了一次分析、多路分发、并行执行 的调度模式:
LLM 分析输入 → 确定需要处理的 memory_target 列表
┌───────┼───────┐
▼ ▼ ▼
Personal Procedural Tool
Agent Agent Agent
│ │ │
└───────┼───────┘
▼
汇总各 Agent 结果
DelegateTask 内部维护了一个 MemoryType → BaseMemoryAgent 的映射字典。当接收到包含多个 memory_target 的任务列表时,它并行启动对应的 Agent 实例,待所有 Agent 执行完成后汇总结果。
上游的 ReMeSummarizer 和 ReMeRetriever 通过提示词工程引导 LLM 判断"当前上下文应该分派给哪些 memory_target",从而实现了一个由 LLM 驱动的动态路由机制 。
六、记忆工具层的工程实现
6.1 Draft → Retrieve → Deduplicate 模式 记忆写入遵循"先草拟、后确认"的策略,由 AddAndRetrieveSimilarMemory 工具实现:
Draft 阶段 :LLM 从对话轨迹提取候选记忆片段,每条包含 message_time 和 memory_content;
Retrieve 阶段 :以每条草稿的内容为查询,批量检索向量库中的相似历史记忆;
Deduplicate 阶段 :LLM 对比草稿与历史记忆,仅将真正新颖的内容持久化。
这种模式有效避免了传统 RAG 系统中常见的信息冗余问题;通过让 LLM 而非固定规则来判断"是否冗余",系统具备了更精细的语义去重能力。
6.2 MemoryHandler 的批量搜索与混合检索 MemoryHandler 封装了向量数据库的 CRUD 操作,并在此基础上实现了混合检索模式 。当设置 hybrid_threshold 参数时,系统执行以下流程:
对所有查询文本获取向量嵌入;
分别执行多路向量搜索并去重;
计算每条结果与所有查询的平均余弦相似度 ;
按阈值过滤,按分数降序排列。
这确保了检索结果不偏向某一个查询,而是与查询集的整体语义保持较高的一致性。
6.3 更新策略:Delete + Insert MemoryHandler 的记忆更新采用 Delete + Insert 策略而非原地修改。当需要更新一条记忆时,系统先通过 vector_store.get() 获取原始 VectorNode,转换为 MemoryNode 修改字段,再删除旧节点、插入新节点。
这一策略的原因在于:更新 content 后 memory_id 会变化(因其基于内容哈希),同时向量嵌入也需要重新生成。直接替换比原地修改在语义一致性上更可靠。
七、提示词工程的设计哲学 ReMe 的每个 Memory Agent 都配备了独立的 YAML 提示词文件,这些文件的设计遵循几个原则:
原则一:角色定义明确化。 每个 Agent 被赋予清晰的角色身份。例如,ReMeSummarizer 的系统提示为"You are a Memory Orchestrator responsible for routing memory summarization tasks to specialized agents",强调其"调度者"而非"执行者"的定位。
原则二:工具使用约束严格化。 在 DelegateTask 的提示词中,系统通过大量加粗文本和 CRITICAL 标记,反复强调 memory_target 必须精确匹配预定义列表中的值,不得从上下文内容中"发明"新的 target 名称。
原则三:决策流程步骤化。 个人记忆的提示词将写入流程拆分为显式的 Step 1(创建草稿 + 检索相似记忆)和 Step 2(对比后添加新记忆),每一步的输入、输出和判断条件都有明确说明。
原则四:可选的思维链注入。 BaseMemoryTool 支持 enable_thinking_params 参数。当启用时,工具调用的 JSON Schema 中会自动注入一个 thinking 字段,要求 LLM 在填写参数之前先输出其推理过程。
八、Flow 编排与操作符组合 ReMe 的 BaseFlow 类提供了工作流编排能力,而 BaseOp 类支持操作符重载语法:
pipeline = step1 >> step2 >> step3
parallel = branch_a | branch_b | branch_c
workflow = (preprocess >> (analyze | summarize)) >> postprocess
这种设计使得复杂的记忆处理管线可以通过声明式语法灵活组合,同时保持了代码的可读性。
九、与传统 RAG 方案的对比 维度 ReMe 传统 RAG 记忆类型 四种细分类型(个人 / 程序性 / 工具 / 工作) 通常仅支持文档检索 写入方式 LLM Agent 自主提取 + 语义去重 直接文本分块存储 检索锚点 when_to_use(检索意图与内容解耦)内容本身 用户画像 结构化 Profile + 细粒度片段 通常不涉及 上下文管理 Offload/Reload + Split Turn 检测 简单截断或滑动窗口 工具选择优化 基于历史表现的数据驱动策略 通常不涉及 冗余控制 Draft → Retrieve → Deduplicate 流程 通常不涉及 执行模式 ReAct Agent(推理 + 行动交替) 固定管线(Pipeline)
十、总结 ReMe 的核心创新在于将记忆管理从传统的"被动存取"升级为由 LLM 驱动的**"主动理解、智能提取、语义去重、分类存储"**的智能化流程。其设计中几个值得深入学习的技术亮点包括:
when_to_use 解耦设计 ——将检索意图与实际内容分离,解决了"内容语义 ≠ 检索意图"的经典问题;
Two-Phase 个人记忆 ——将细粒度记忆片段与结构化用户画像双轨管理,兼顾语义灵活性与结构精确性;
Agent-as-Memory-Manager ——用 ReAct Agent 替代硬编码规则执行记忆操作,天然具备泛化能力;
Draft-Retrieve-Deduplicate ——"先草拟后确认"的写入策略,以 LLM 的语义理解能力解决冗余控制问题;
Split Turn 感知压缩 ——工作记忆的上下文压缩不仅考虑 token 预算,还尊重对话的逻辑边界。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online