02-Mem0 的 LLM 对话记忆提取提示词设计
Mem0 的 LLM 对话记忆提取提示词设计
学习目标
本章分析 Mem0 如何将精心设计的 LLM 提示词作为记忆提取的”大脑”。你将了解:
- ADDITIVE_EXTRACTION_PROMPT 的结构与设计原则
- 提示词如何防止”First Topic Dominance”等提取陷阱
- 时间锚定、数值精确、禁止泛化等质量约束的实现方式
- 12 个 Few-Shot 示例各自解决的问题
前置知识
本章涉及 LLM 结构化提取的通用原理,建议先阅读:
下文假设你已理解 LLM 提取的基本概念,直接聚焦 Mem0 的提示词设计细节。
项目实践
提示词的层次结构
ADDITIVE_EXTRACTION_PROMPT 位于 mem0/configs/prompts.py,约 900+ 行,分为以下层次:
| 区块 | 行数约 | 内容 |
|---|---|---|
| ROLE | 30 | 角色定义、提取范围(用户+助手消息) |
| INPUTS | 80 | 6 种输入类型的定义(新消息、摘要、已有记忆等) |
| GUIDELINES - 提取范围 | 120 | 从用户/助手消息中提取什么的详细规则 |
| GUIDELINES - 质量标准 | 200 | 上下文丰富、时间锚定、数值精确、禁止泛化等 |
| GUIDELINES - 完整性规则 | 100 | 禁止捏造、禁止隐式推断、禁止回显提取等 |
| GUIDELINES - 记忆链接 | 30 | linked_memory_ids 的链接条件 |
| EXAMPLES | 350 | 12 个 Few-Shot 示例 |
| CHECKLIST | 30 | 输出前的完整性检查清单 |
| OUTPUT FORMAT | 30 | 输出 JSON 格式定义 |
关键设计原则
1. 角色定义:“Memory Extractor”
# ROLEYou are a Memory Extractor — a precise, evidence-bound processorresponsible for extracting rich, contextual memories from conversations.Your sole operation is ADD.“Memory Extractor” 定位明确:不是对话助手,不是总结器,是精确的证据绑定处理器。“Sole operation is ADD” 强调只做添加,不做更新/删除。
2. 提取范围:从两种角色提取
- User messages: Personal facts, preferences, plans, experiences- Assistant messages: Specific recommendations, plans created, information researched, solutions providedMem0 明确允许从助手消息中提取信息——这与传统”只从用户消息提取”不同。助手提供的推荐、创建的方案、研究的信息同样值得记忆。
但有限制条件:
- 不回显:助手重复用户已说的话,不提取
- 不提取元评论:助手对自己能力的描述,不提取
3. 禁止泛化:具体细节必须保留
这是提示词中最强调的规则之一:
"promoted to assistant manager" → KEEP "assistant manager", NOT "manager""drove a Ferrari 488 GTB" → KEEP "Ferrari 488 GTB", NOT "sports car""scored 3 goals in the semifinal" → KEEP "3 goals in the semifinal", NOT "several goals"Mem0 认为”用模糊类别替代具体细节”是最严重的提取错误——因为具体细节正是用户搜索时用的关键词。
4. 时间锚定:Observation Date vs Current Date
Observation Date: 2022-01-16 # 对话实际发生的日期Current Date: 2026-02-18 # 今天的系统日期
"recently" → 基于 Observation Date 解析为 "early January 2022"NOT "early February 2026"这是一个微妙但关键的设计:如果用户在 2022 年说”我最近读了 X”,而系统在 2026 年检索,“recently” 必须解析为 2022 年 1 月,而非 2026 年 2 月。
5. “First Topic Dominance” 防护
# CRITICAL: Exhaustive Extraction Checklist1. Have you extracted at least one memory from EVERY distinct topic?2. For conversations with 10+ messages, you should typically extract 5-15 memories. If you have fewer than 3, re-read the conversation.3. Re-read each user message individually.在输出前强制 LLM 做完整性检查:每个话题是否都提取了?10+ 条消息的对话如果只提取了 2-3 条记忆,几乎肯定遗漏了信息。
12 个 Few-Shot 示例解决的问题
| 示例 | 解决的问题 |
|---|---|
| 1. 多话题提取 | 一条消息包含 3 个话题(职业、餐厅、怀孕),分别提取 |
| 2. 助手推荐提取 | 从助手回复中提取推荐内容 |
| 3. 空结果 | 纯问候对话,无信息可提取 |
| 5. 去重 | 用户重复说同一件事,跳过 |
| 6. 多维度提取 | 职业 + 娱乐偏好 + 学习资源,分别提取 |
| 7. 历史 Observation Date | ”recently” 基于历史日期解析 |
| 8. 文档内容提取 | 用户分享案例,提取内容而非”用户分享了文档” |
| 9. 结构化数据 | D&D 怪物属性,保留所有数值 |
| 10. 记忆链接 | 新记忆关联已有记忆 UUID |
| 11. 长对话多话题 | 5 条消息 5 个话题,每个都提取 |
| 12. 多说话者 | 从”assistant”角色中提取真实人名分享的事实 |
动态提示词构建器
generate_additive_extraction_prompt() 函数将静态模板与动态输入组合:
# 伪代码prompt = "\n\n".join([ f"## Summary\n{_format_summary(summary)}", f"## Last k Messages\n{_format_conversation_history(last_k_messages)}", f"## Recently Extracted Memories\n{_serialize_memories(recently_extracted)}", f"## Existing Memories\n{_serialize_memories(existing_memories)}", f"## New Messages\n{_format_new_messages(new_messages)}", f"## Observation Date\n{observation_date}", f"## Current Date\n{current_date}", f"## Custom Instructions\n{custom_instructions}", # 可选 "# Output:",])过去消息内容超过 300 字符时自动截断(PAST_MESSAGE_TRUNCATION_LIMIT = 300),防止 prompt 过长。
问题与规避
| 问题 | 对策 |
|---|---|
| 提示词过长消耗大量 Token | 对历史消息做 300 字符截断;Existing Memories 只传 top-10 |
| LLM 忽略”禁止泛化”指令 | Few-Shot 示例中反复强调具体→泛化的错误案例 |
| LLM 回显提取 | 提示词中明确”No Echo Extraction”规则 + Few-Shot 示例 |
| 输出 JSON 格式错误 | response_format={"type": "json_object"} + 代码块解析回退 |
设计取舍
为什么提示词 900+ 行而非精简?
优势:
- 12 个 Few-Shot 示例覆盖了几乎所有常见提取场景
- 完整性检查清单显著降低”first topic dominance”问题
- Mem0 基准测试提升(LoCoMo +20 分)证明效果显著
代价:
- 提示词本身消耗大量 Token
- 每次
add()调用都携带完整提示词,成本较高 - 提示词修改需要重新验证所有 Few-Shot 示例
替代方案:小型提取模型
可以使用微调的小型模型(如 BERT-based NER)替代 LLM 提取。Mem0 选择了 LLM 方案,原因是:
- 提取规则灵活变化,微调模型难以快速适应
- LLM 理解上下文和歧义的能力远超 NER 模型
- 提示词可迭代,模型需要重新训练
参考来源
- Mem0 论文:arXiv:2504.19413
- Mem0 提示词源码:
mem0/configs/prompts.py