跳转到内容

06-Mem0 的程序性记忆实现

Mem0 的程序性记忆实现

学习目标

本章分析 Mem0 如何通过 LLM 摘要 Agent 执行历史,构建结构化的程序性记忆。你将了解:

  • _create_procedural_memory() 的触发条件与实现
  • PROCEDURAL_MEMORY_SYSTEM_PROMPT 的摘要格式设计
  • 程序性记忆与普通记忆在存储和检索上的差异
  • 程序性记忆在 Agent 恢复上下文场景中的实际应用

前置知识

本章涉及程序性记忆的通用原理,建议先阅读:

下文假设你已理解程序性记忆的基本概念,直接聚焦 Mem0 的具体实现。

项目实践

触发条件

程序性记忆在 Memory.add() 方法中被触发:

# 伪代码
if agent_id is not None and memory_type == MemoryType.PROCEDURAL.value:
results = self._create_procedural_memory(messages, metadata=processed_metadata)

触发条件:

  • agent_id 存在(Agent 场景)
  • memory_type 设置为 "procedural_memory"

MemoryType 枚举定义了三种类型:

class MemoryType(Enum):
SEMANTIC = "semantic_memory" # 语义记忆
EPISODIC = "episodic_memory" # 情景记忆
PROCEDURAL = "procedural_memory" # 程序性记忆

摘要流程

_create_procedural_memory() 的实现:

# 伪代码
parsed_messages = [
{"role": "system", "content": prompt or PROCEDURAL_MEMORY_SYSTEM_PROMPT},
*messages, # Agent 的执行历史消息
{"role": "user", "content": "Create procedural memory of the above conversation."},
]
procedural_memory = self.llm.generate_response(messages=parsed_messages)
memory_id = self._create_memory(procedural_memory, {...}, metadata=metadata)

流程简洁:

  1. 将 Agent 执行历史 + 摘要提示词组合为对话
  2. LLM 生成结构化摘要
  3. 将摘要作为普通记忆存储(标记 memory_type: "procedural_memory"

摘要提示词设计

PROCEDURAL_MEMORY_SYSTEM_PROMPT 定义了严格的摘要格式:

## Summary of the agent's execution history
**Task Objective**: <总体目标>
**Progress Status**: <完成百分比和里程碑>
1. **Agent Action**: <精确描述做了什么>
**Action Result**: <原文输出,不改写>
**Key Findings**: <关键发现>
**Navigation History**: <访问页面历史>
**Current Context**: <操作后状态>

关键约束

  • 每个步骤的 Action Result 必须原文保留(HTML 片段、JSON 响应、错误消息)
  • 步骤按执行顺序编号
  • 包含错误信息(完整错误消息和堆栈跟踪)
  • 输出只有摘要,不包含额外评论

存储差异

程序性记忆在存储时与普通记忆的区别仅在元数据中:

metadata = {**metadata, "memory_type": MemoryType.PROCEDURAL.value}

检索时可通过 memory_type 字段过滤:

m.search("Agent 做了什么", filters={"user_id": "alice", "memory_type": "procedural_memory"})

问题与规避

问题对策
LLM 摘要时丢失关键输出原文提示词中反复强调”Preserve Every Output”
错误信息被截断要求包含完整错误消息和堆栈跟踪
摘要过长超出上下文窗口对过长的动作结果进行适度截断
程序性记忆与普通记忆混淆memory_type 元数据区分,可单独过滤

设计取舍

为什么程序性记忆独立存储而非附加到普通记忆?

优势

  • 可单独过滤和检索:Agent 恢复上下文时只加载程序性记忆
  • 存储格式不同:程序性记忆是长文本摘要,普通记忆是简短事实
  • 生命周期不同:程序性记忆随任务结束而固化,普通记忆持续更新

代价

  • 需要额外的 memory_type 参数控制
  • 普通用户可能不理解程序性记忆的概念

为什么摘要格式是纯文本而非 JSON?

程序性记忆的摘要是自然语言文本(而非结构化 JSON),原因是:

  • 摘要需要保留 Agent 输出的原文(HTML、JSON、错误消息),嵌入在文本中更自然
  • 检索时通过向量相似度匹配,文本格式更适合
  • 结构化的步骤编号和元数据标题提供足够的可解析性

参考来源

  • Mem0 论文:arXiv:2504.19413
  • Mem0 源码:mem0/memory/main.pymem0/configs/prompts.py