MIRIX - Multi Agent Memory System · essay
07. MIRIX:多模块记忆系统
论文:MIRIX: Multi-Agent Memory System for LLM-Based Agents
链接:https://arxiv.org/abs/2507.07957
本地原文:
![[papers/07-MIRIX-2507.07957.pdf]]
论文定位与阅读路径
核心定位
MIRIX 把记忆系统拆成多个专门组件,并用类似 Multi-Agent 的方式协作管理记忆。
原文结构导读
| 原文部分 | 主要任务 | 阅读时抓什么 |
|---|---|---|
| Motivation | 说明单一记忆模块难以覆盖复杂 Agent | 看多类型记忆为什么必须分工 |
| System Overview | 给出 Chat Agent 与 Meta Memory Manager 的关系 | 抓住“谁接用户输入,谁决定调用哪类记忆” |
| Memory Managers | 展开 profile、episodic、semantic、procedural、resource | 每个 manager 的输入、输出、更新策略要分开看 |
| Coordination | 说明多记忆结果如何汇总 | 重点看冲突、冗余和优先级如何处理 |
| Evaluation | 比较多组件记忆对任务的帮助 | 注意它证明的是整体系统收益,还是某个子模块收益 |
证据链阅读
| 证据点 | 读什么 | 工程判断 |
|---|---|---|
| Manager 分工 | profile/episodic/semantic/procedural/resource 各自负责什么 | 分工清楚才不会变成一个大杂烩 store |
| Meta Memory Manager | 如何选择和协调子记忆模块 | 这是多记忆系统的路由核心 |
| 冲突处理 | 多模块返回矛盾结果怎么办 | 长期 Agent 必须有优先级和证据来源 |
| Evaluation | 多模块是否比单模块更好 | 判断复杂架构是否真的买来收益 |
研究背景与问题定义
它要解决什么
一个长期 Agent 需要记住的东西很多:
- 用户画像。
- 任务历史。
- 事实知识。
- 对话上下文。
- 计划。
- 经验教训。
- 工具使用结果。
如果全部塞进一个 memory store,会越来越乱。MIRIX 的思路是:不同记忆交给不同模块管理。
方法框架与核心机制
核心思想
具体组件名称可以随实现变化,但思想是“分工协作”。
为什么要多模块
不同记忆的写入和检索方式不同:
| 记忆 | 写入方式 | 检索方式 |
|---|---|---|
| 用户偏好 | 从对话抽取 | 用户画像匹配 |
| 事件经历 | 保存时间线 | 时间 + 语义检索 |
| 事实知识 | 抽实体关系 | 关键词/图检索 |
| 技能经验 | 总结成功策略 | 任务类型匹配 |
| 工具结果 | 结构化日志 | trace/任务关联 |
统一一个表也能做,但会很难优化。
概念校准
学校里不会让一个老师负责所有课。数学、英语、体育各有老师。MIRIX 的思路也一样:不同记忆让不同“记忆专家”处理,最后由总协调者整合。
工程映射与实践启发
工程落地方案
Java 后端可以设计成策略模式:
代码块收起展开
MemoryModule interface
- shouldHandle(event)
- write(event)
- retrieve(query)模块:
| 模块 | 作用 |
|---|---|
ProfileMemoryModule | 用户长期偏好 |
EpisodicMemoryModule | 事件和时间线 |
SemanticMemoryModule | 知识和事实 |
ProceduralMemoryModule | 技能和工作流 |
TraceMemoryModule | 工具调用和执行历史 |
Meta 管理器:
代码块收起展开
query -> classify -> route to modules -> merge -> rerank -> context相关工作与方法对比
和 MemOS 的区别
| 维度 | MemOS | MIRIX |
|---|---|---|
| 重点 | 系统资源治理 | 多模块协作 |
| 核心问题 | 如何统一管理记忆生命周期 | 如何把不同记忆交给不同专家 |
| 工程类比 | 操作系统 | 微服务/策略路由 |
局限、对比与阅读检查
局限与边界
- 多模块意味着更多复杂度。
- 模块间可能返回冲突结果。
- Meta 管理器质量很关键。
- 需要评测每个模块是否真的有贡献。
阅读重点
- 它把记忆分成哪些组件。
- Meta Memory Manager 如何路由。
- Chat Agent 什么时候触发记忆搜索。
- 多模块结果如何合并。
- 它相比单一 memory store 提升在哪里。
实践启发
如果你做 Personal Knowledge Agent,初版不必多 Agent,但可以先分表/分模块:
- 用户偏好。
- 笔记知识。
- 对话事件。
- 工具执行记录。
- 学习计划历史。
这会比一个 memory_text 表更可维护。
原文精读补充
1. MIRIX 的核心不是“多个 Agent 更酷”
MIRIX 的重点是:不同记忆类型需要不同管理器,不应该由一个大而全的 memory store 处理所有事。
你可以把它理解成医院分诊:
代码块收起展开
不是所有病人都去同一个窗口。
先由分诊台判断,再送到内科/外科/检查室。Meta Memory Manager 就是分诊台。
2. 多组件记忆
MIRIX 强调将记忆拆成多个组件。不同版本描述可能略有差异,但核心思想是把事实、事件、语义、程序、资源等分开管理。
工程上你可以先拆成:
| 组件 | 存什么 |
|---|---|
| Profile Memory | 用户稳定画像 |
| Episodic Memory | 历史事件和对话 |
| Semantic Memory | 概念、事实、知识 |
| Procedural Memory | 技能、流程、成功做法 |
| Resource Memory | 文件、链接、工具结果 |
| Working Memory | 当前任务状态 |
3. 写入路由
一条新输入进来,先判断它属于什么:
flowchart TD
A["新输入"] --> B["Meta Memory Manager"]
B --> Core["用户与事件<br/>Profile / Episodic"]
Core --> Knowledge["知识与技能<br/>Semantic / Procedural / Resource"]
Knowledge --> Result["综合记忆结果"]
这比所有内容都写进一个表更利于维护。
4. 检索也是两阶段
MIRIX 的检索思想可以理解为:
- 先粗略问各组件有没有相关内容。
- 再由 Chat Agent 决定深入查哪个组件。
这和搜索引擎的粗召回/精排很像。
5. 实验怎么看
你读实验时关注:
- 多组件是否真的比单一记忆库更准。
- 路由错误时系统表现如何。
- 组件变多后延迟是否可接受。
- 对 single-hop、multi-hop、temporal 问题提升是否一致。
6. 工程落地提醒
你的个人 Agent 未来很容易变复杂。初版可以只有一个物理表,但逻辑上先留 memory_kind:
代码块收起展开
PROFILE / EPISODIC / SEMANTIC / PROCEDURAL / RESOURCE / WORKING这样后面扩展成多表或多服务时,数据语义不会乱。
深度精读:MIRIX 的关键是“分工”,不是炫技式 Multi-Agent
1. 单一记忆库为什么会失控
如果所有东西都写到一个 memory store:
代码块收起展开
用户偏好、事实知识、历史事件、执行日志、技能、当前任务状态检索时会出现:
- 当前任务状态和长期事实混在一起。
- 一次失败日志被当成稳定知识。
- 用户偏好和项目规则互相干扰。
- 程序性技能被当成普通文本事实。
MIRIX 的思想是把记忆类型分开,让不同管理器负责不同问题。
2. Meta Memory Manager 是路由器
Meta Memory Manager 的职责不是直接回答,而是判断:
代码块收起展开
这条输入和哪些记忆组件有关?
需要写入哪些组件?
检索时先问哪些组件?类比后端网关:
代码块收起展开
HTTP 请求 -> Gateway -> user-service/order-service/search-serviceMIRIX 是:
代码块收起展开
Agent 输入 -> Meta Memory Manager -> semantic/episodic/procedural/... managers3. 组件化记忆的好处
| 组件化收益 | 解释 |
|---|---|
| 存储结构更适合 | 事件按时间,事实按实体,技能按任务类型 |
| 检索更准 | 查询不会在无关记忆里乱找 |
| 更新策略不同 | 偏好可更新,事件应保留,技能需验证 |
| 权限更清楚 | 用户画像和公共知识权限不同 |
| 评测更细 | 可以单独测每类记忆命中率 |
这就是为什么它比“一个向量库 + topK”更像工程系统。
4. 写入时的路由例子
用户说:
代码块收起展开
以后讲论文要更深入,最好结合原文、代码和工程落地。路由应该是:
| 记忆组件 | 是否写入 | 内容 |
|---|---|---|
| Profile | 是 | 用户偏好深度讲解 |
| Episodic | 是 | 本次反馈事件 |
| Procedural | 可能 | 生成论文笔记的流程要求 |
| Semantic | 否/弱 | 不是通用知识 |
| Working | 是 | 当前任务修改标准 |
如果全部塞进同一类 memory,后续很难用对。
5. 检索时的两阶段策略
MIRIX 类系统适合两阶段检索:
代码块收起展开
阶段一:每个组件返回轻量摘要/候选
阶段二:根据任务需要深入查具体组件例子:
代码块收起展开
问题:继续扩论文笔记
先查 Working Memory:当前扩到哪
再查 Profile:用户偏好深度
再查 Semantic/Resource:论文原文和笔记文件
最后查 Procedural:之前成功的写作模板这比无脑 topK 更接近真实 Agent。
6. 组件化后最大风险:路由错
分工不是没有代价。最大的风险是 Meta Memory Manager 判断错:
| 路由错误 | 后果 |
|---|---|
| 应写 Profile 却写 Episodic | 偏好不会长期生效 |
| 应查 Procedural 却只查 Semantic | 知道概念但不会做事 |
| 应查 Working 却查长期库 | 当前任务进度丢失 |
| 查太多组件 | 延迟和成本上升 |
所以路由本身要有 trace:
代码块收起展开
为什么查这些组件?
每个组件返回了什么?
最后用了哪些?7. 工程实现建议
不要一开始真做多个 Agent。可以先做一个服务、多个策略类:
代码块收起展开
interface MemoryManager {
MemoryKind kind();
List<MemoryCandidate> extract(TurnContext ctx);
List<Memory> retrieve(MemoryQuery query);
void update(MemoryUpdate update);
}然后注册:
代码块收起展开
ProfileMemoryManager
EpisodicMemoryManager
SemanticMemoryManager
ProceduralMemoryManager
ResourceMemoryManager
WorkingMemoryManager这就是 MIRIX 思想的轻量落地。
8. 读实验时要看分类问题
MIRIX 如果分数高,你要看它在哪类问题高:
- single-hop 是否只是普通检索就够。
- multi-hop 是否靠组件分工提升。
- temporal 是否靠事件/时间记忆提升。
- open-domain 是否靠 semantic/resource 记忆提升。
如果所有类别都只提升一点,说明可能是整体 prompt/模型影响;如果特定类别显著提升,才说明对应组件有效。
论文精读主线:问题-方法-验证-局限-启发
1. 核心结论
MIRIX 把 Agent 记忆拆成多个专职模块,并由 Meta Memory Manager 负责写入路由和检索协调,避免所有信息挤进一个记忆库。
本篇的阅读重心是:复杂记忆系统需要专职模块和 Meta Memory Manager,而不是一个万能向量库。读完后要能说清它改变的是 runtime、存储、检索、更新还是评测层;否则只是记住了论文名。
2. 问题背景
单一向量记忆库会混淆用户画像、当前任务、历史事件、稳定知识和可复用技能。系统一复杂,写入时不知道放哪里,检索时不知道该信什么,结果就是长期记忆越多越吵。
把问题具体化为失败样例:用户偏好、任务过程、知识事实、技能经验全进同一库,检索时互相污染,更新策略也无法区分。用这个样例反推论文动机,比泛泛说“上下文不够”或“记忆不准”更有判断力。
3. 核心方法
核心是 Meta Memory Manager。写入时它把输入拆成多条原子记忆并路由到 profile、episodic、semantic、skill 等模块;读取时根据任务意图选择相关模块,合并结果后进入上下文。
flowchart TD
I[输入事件] --> M[Meta Memory Manager]
M --> P[Profile Memory]
M --> E[Episodic Memory]
M --> S[Semantic Memory]
M --> K[Skill Memory]
Q[任务查询] --> M
P --> C[上下文融合]
E --> C
S --> C
K --> C
方法部分按数据流读:输入先由 Meta Manager 分类,再路由到不同记忆模块;回答时按任务组合多个模块的检索结果。每一步都要能标出输入、输出、控制点和失败后该记录的日志。
4. 技术细节
这篇的技术关键是模块边界和路由置信度。一条输入可能同时包含偏好、项目状态和知识事实,不能只路由到一个地方。检索也不应每次查所有模块,而要先判断任务意图。
代码块收起展开
final class MetaMemoryManager {
private final MemoryRouter router; // 把输入拆成原子记忆,并判断目标模块、类型和置信度
private final ModuleRegistry registry; // 注册 profile/episodic/semantic/skill 等记忆模块
private final RetrievalCoordinator coordinator; // 按任务意图选择模块并融合证据
private final RouteAuditor auditor; // 记录路由理由,支持后续重分类和纠错
MemoryResult handle(MemoryInput input) {
// 1. 把输入拆成原子记忆,并判断目标模块、类型和置信度
// 2. 注册 profile/episodic/semantic/skill 等记忆模块
// 3. 按任务意图选择模块并融合证据
// 4. 记录路由理由,支持后续重分类和纠错
// 返回结果时必须带 evidence、confidence、traceId,方便以后追查记忆为什么生效。
return MemoryResult.withTrace(input.traceId());
}
}字段检查重点是 memoryKind、routeReason、moduleScore、mergePolicy、conflictResolution 是多模块系统关键。这些字段不是装饰,它们决定后续能否检索、审计、回滚、限权和做离线评测。
5. 实验验证
实验要证明多模块分工优于单库。重点看去掉 Meta Manager、合并成单一记忆库、去掉某个模块后的表现。还要检查检索证据来自哪个模块,否则无法知道提升原因。
实验阅读重点:看路由准确率、模块消融、冲突合并质量;只看端到端回答会掩盖哪个模块真正起作用。如果论文没有直接给出这层证据,复现时就要自己补机制级指标。
6. 局限与启发
最大风险是路由错。临时吐槽进了 profile 会长期污染;稳定偏好进了 episodic 可能检索不到。启发是你的 Agent 至少要区分用户偏好、项目状态、笔记知识、任务 trace、可复用技能。
迁移到你的项目时,结论是:你的初版可以一张表物理存储,但逻辑接口要分 episodic、semantic、profile、skill、reflection。先把边界做对,再追求更复杂的模型或更大的记忆规模。
7. 关键术语表
| 术语 | 在论文里的意思 | 工程落地时要看什么 |
|---|---|---|
| Meta Memory Manager | 记忆路由和协调器 | 写入分类、检索融合、预算分配 |
| Memory module | 专用记忆组件 | profile/episodic/semantic/skill |
| Routing confidence | 路由置信度 | 低置信待确认或多模块写入 |
| Retrieval fusion | 多模块结果合并 | 去重、排序、来源标注 |
8. 复现难点
模块太少会混乱,太多会路由困难。跨模块查询也难,例如“继续优化论文笔记”同时需要项目状态、用户偏好和笔记内容。成本上不能每轮全查,必须先做 query planning。
复现入口应从失败集开始:同一输入分别涉及偏好、事实、任务过程和技能时,检查系统是否路由到正确模块并合并结果。只有先证明旧方案会坏,才知道新机制是否真的解决了问题。
9. 代码框架建议
先用同一数据库不同表实现模块边界:user_profile_memory、project_event_memory、note_semantic_memory、skill_memory。每个模块都有自己的写入策略和检索策略,但统一由 manager 调度。
代码验收门槛:Meta Manager 的每次路由都要写 reason;无法解释为什么进某模块,就不能自动写长期记忆。这条门槛应写进测试或 trace 字段里,避免实现只停留在 demo。
10. 相关论文对比
MIRIX 和 CoALA 都强调记忆类型划分;CoALA 是认知分类,MIRIX 更像工程系统。MemOS 抽象层更高,Mem0 可作为每个模块内部的写入策略。
横向比较时抓这个角度:MIRIX 和 CoALA 都强调分层;MIRIX 更像工程系统,CoALA 更像认知分类框架。比较对象不是谁“更先进”,而是谁负责哪一层失败。
11. 批判性思考
多模块不自动等于更聪明,可能只是更多 prompt、更多维护成本。判断是否成熟要看模块边界是否清晰、路由错误是否可发现、检索结果是否能解释来源和用途。
批判边界:模块越多,调度错误越多;如果没有路由评测和冲突策略,多模块只会增加不确定性。这不是否定论文,而是把论文结论放回真实系统的成本、权限和恢复约束里。