MEMORY ENGINE · 记忆工程原理

mem0 记忆工程原理详解

从源码视角拆解 mem0(mem0ai/mem0)这套「AI 智能体的通用记忆层」是如何把一段对话,抽取成可检索、可演进、带实体关联的长期记忆的。覆盖整体架构、写入管线(V3 批量流水线)、事实抽取与合并提示词、多信号检索、内置图记忆与数据模型。
源码:mem0/memory/main.py · base.py 提示词:mem0/configs/prompts.py 默认 LLM:OpenAI gpt-5-mini 默认向量库:本地 Qdrant

1mem0 是什么

mem0 的定位是 「AI Agents 的通用记忆层(Universal Memory Layer)」——它为 LLM 应用提供一套可插拔的记忆系统,让对话之外的事实、偏好、关系被持久化,并在后续交互中被精准召回。

它不是简单的向量库封装,而是一条「抽取 → 嵌入 → 存储 → 合并 → 检索 → 重排」的完整管道。mem0 以三种形态交付:

📦Library 库

pip install mem0ai / npm install mem0ai。几行代码接入 Memory(),适合原型与测试。

🖥️Self-Hosted Server

docker compose up 自建基础设施,带鉴权、Dashboard 与审计日志,数据完全自控。

☁️Cloud Platform

零运维托管全功能版,平台侧有专有检索与合并优化。

记忆的本质在 mem0 里是「以事实(fact)为最小单元」的结构化记录,而不是整段对话的堆砌。这让记忆可被去重、可被演进、可被带权召回。

2整体架构:分层与工厂装配

mem0 的内核是一个 Memory 编排类,它通过一组工厂(Factory)动态装配底层组件,再对接存储层。这种「横向基础库 + 纵向领域层」的分层,是它可扩展性的根基。

应用 / Agent Memory 引擎(Memory / AsyncMemory) add · search · get · update · delete · history V3 Phased Batch Pipeline · 多信号检索 · 实体链接 LLM 事实抽取 / 合并决策 结构化 JSON 输出 Embedder 文本 → 向量 默认 text-embedding-3 VectorStore 向量 + 元数据 Qdrant / pgvector … Reranker 候选重排(可选) Cohere / HF / LLM HistoryStore 对话原文 (SQLite) ~/.mem0/history.db 装配方式(工厂模式) LlmFactory EmbedderFactory VectorStoreFactory RerankerFactory SQLiteManager 存储后端:本地 Qdrant / Postgres+pgvector / Milvus / Chroma / Pinecone / Redis / 等 30+ 向量库 + SQLite 历史库 + {collection}_entities 实体集合
图 1 · mem0 分层架构:应用 → Memory 引擎 → 可插拔组件(工厂装配)→ 存储后端
Memory.__init__ 中的工厂装配(来自 main.py)
# 按 config 中的 provider 动态创建组件——典型工厂模式
self.embedding_model = EmbedderFactory.create(config.embedder.provider, config.embedder.config, ...)
self.vector_store    = VectorStoreFactory.create(config.vector_store.provider, config.vector_store.config)
self.llm             = LlmFactory.create(config.llm.provider, config.llm.config)
self.db              = SQLiteManager(config.history_db_path)   # 历史库
self.reranker        = RerankerFactory.create(...) if config.reranker else None
self._entity_store   = None  # 实体集合懒加载(首次 add 时创建)
设计要点:所有组件都面向接口。换向量库、换 Embedder、换 LLM 都不改引擎逻辑,只改配置。这正是 mem0 能同时支持 30+ 向量库、十余种 LLM 的原因。

3六大核心组件

每条记忆从诞生到被召回,都要经过这些组件的协作。理解各自的职责边界,是理解整条管线的前提。

🧠LLM

记忆的「大脑」。负责两件事:① 从对话中抽取事实(结构化 JSON);② 在旧版管线中决定 ADD/UPDATE/DELETE/NONE。默认 OpenAI gpt-5-mini,要求支持 response_format=json_object

🔢Embedder

语义的「翻译器」。把记忆文本变成向量。默认 text-embedding-3-small;官方建议本地 Qwen GTE 系列(600M+)以启用混合检索

🗄️VectorStore

记忆的「主仓库」。存向量 + 元数据(user_id/agent_id/run_id/标签)。检索时做 ANN 相似度 + 元数据过滤。支持 Qdrant、pgvector、Milvus、Chroma、Pinecone、Redis 等。

📐Reranker

精度的「守门员」。可选组件。对初筛候选做二次精排(Cohere / HuggingFace / LLM / Sentence-Transformers),提升 top-k 准确率。默认关闭,需显式配置。

📜HistoryStore

原始对话的「档案室」。SQLite(~/.mem0/history.db),存每条记忆对应的原始消息。支撑 history() 变更追溯,也便于重新抽取。

🔗EntityStore

图关系的「隐式层」。向量库中的并行集合 {collection}_entities,存从每条记忆抽取的实体。检索时用于实体 boost,把共享实体的记忆关联起来。

关键认知:mem0 的「图记忆」不再是独立图数据库(见第 8 节)。实体链接被内建进向量库的同实例并行集合,用检索期打分提升来承载「关联」,而非返回可遍历的图谱。

4写入管线:V3 批量流水线(ADD-only)

2026 年 4 月的新记忆算法把写入重构为一条「单遍、批量、只追加」的流水线。源码中以 # === V3 PHASED BATCH PIPELINE === 标注,分 9 个阶段。

① 收集上下文messages + 过滤键 ② 检索已有拉取相关记忆 ③ 单次 LLM 抽取ADDITIVE 提示词 ④ 批量嵌入文本 → 向量 ⑤ Hash 去重防重复写入 ⑥ 批量入库向量库 INSERT ⑦ 历史写 SQLite ⑧ 实体链接(extract_entities_batch → 写入 {collection}_entities) ⑨ 完成
图 2 · 写入管线(V3):单次 LLM 调用抽取全部事实,之后批量嵌入/去重/入库/链接

九个阶段逐一看

0
收集上下文

把传入的 messages 与过滤标识(user_id / agent_id / run_id / metadata)组装成一次写入请求。

1
检索已有记忆

先按过滤键拉取该主体已有的记忆,作为后续抽取/链接的上下文依据。

2
单次 LLM 抽取(核心)

ADDITIVE_EXTRACTION_PROMPT 一次调用同时处理 user 与 assistant 消息,产出结构化 {"memory":[{id,text,attributed_to,linked_memory_ids}]}只 ADD,不 UPDATE/DELETE。

3
批量嵌入

把所有新事实文本批量送进 Embedder 得到向量,减少往返次数。

4
Hash 去重

对文本做哈希,避免完全相同的事实重复入库。配合实体链接实现「消歧」而非「覆盖」。

5
批量入库

一次性 insert 进 VectorStore(含向量 + 元数据 + 过滤键),写入高效。

6
批量写历史

原始消息落 SQLite(HistoryStore),供 history() 追溯与重抽。

7
实体链接

extract_entities_batch 从每条记忆抽取实体(专有名词 / 引用文本 / 复合名词短语),写入 {collection}_entities 并行集合,并用 uuid_mapping 防幻觉、建立跨记忆链接。

8
完成

返回本次新增的记忆列表(含 id、text、categories、metadata 等)。

add() 调用(来自 README 示例)
from mem0 import Memory
m = Memory()

# 写入:把一段对话交给记忆引擎
m.add(messages, user_id="default_user")

# 若 infer=False:不做 LLM 抽取,每条消息原样 ADD(最简单的 ADD-only)
m.add(messages, user_id=u, infer=False)
为什么 ADD-only?旧版在 add 时就要把新事实与旧记忆逐条比对、决定 UPDATE/DELETE,逻辑脆弱且易丢信息。新算法改为「只累积 + 实体链接消歧 + 检索期融合」:记忆只增不减,演进靠「关联」与「检索排序」实现,更稳、更可解释。

5事实抽取原理:提示词即算法

mem0 的「智能」几乎全部藏在提示词里。抽取阶段把非结构对话压缩成自包含的事实语句,是整条管道质量的上限。

5.1 基础抽取:FACT_RETRIEVAL_PROMPT

通用抽取提示词,明确告诉 LLM「只从 user/assistant 消息提取、不要碰 system、语言跟随用户、空则返空列表」。输出固定 schema:

期望输出格式(JSON)
{
  "facts": [
    "Name is John",
    "Is a Software engineer",
    "Looking for a restaurant in San Francisco"
  ]
}

它定义了 7 类应记住的信息:个人偏好、重要个人信息(姓名/关系/日期)、计划意图、服务偏好、健康养生、职业信息、杂项。few-shot 示例直接教导模型「无关内容(如『树上有树枝』)返回空列表」。

5.2 分角色抽取:USER / AGENT 两套提示词

为支持用户记忆智能体状态两类记忆,mem0 提供两套抽取提示词:

👤USER_MEMORY_EXTRACTION_PROMPT

只从用户消息生成事实。提示词用大写强调:[IMPORTANT] GENERATE FACTS SOLELY BASED ON THE USER'S MESSAGES,且「包含 assistant/system 内容会被惩罚」。

🤖AGENT_MEMORY_EXTRACTION_PROMPT

只从助手消息生成事实,沉淀智能体自身的状态、能力与配置。两条流水线并行,互不污染。

5.3 V3 增量抽取:ADDITIVE_EXTRACTION_PROMPT

新算法的核心提示词。角色定位为「Memory Extractor」——只 ADD,不修改,且每条记忆必须「自包含、上下文丰富」,并显式标注来源与关联。

ADDITIVE_EXTRACTION_PROMPT 输出格式
{
  "memory": [
    {"id": "0", "text": "First extracted memory",
     "attributed_to": "user",
     "linked_memory_ids": ["uuid-of-related-existing-memory"]},
    {"id": "1", "text": "Second extracted memory",
     "attributed_to": "assistant"}
  ]
}
抽取质量的三条铁律:① 自包含(脱离上下文仍可理解)、② 只取 user/assistant(屏蔽 system 注入)、③ 语言跟随用户。这三条直接决定了后续检索能否命中。

6记忆的更新与合并:从「决策」到「追加」

记忆要随对话演进——今天说「喜欢芝士披萨」,明天说「讨厌芝士披萨」。mem0 在旧版用一段决策提示词处理这种演进,新版则改为追加式。

6.1 旧版:DEFAULT_UPDATE_MEMORY_PROMPT(四分类决策)

旧版把「新抽取事实」与「已有记忆」交给 LLM,强制输出四选一事件:

ADD 新信息→新增元素(生成新 id)

UPDATE 信息冲突/更丰富→更新旧记忆(保留原 id,附带 old_memory

DELETE 与已有记忆矛盾→删除(保留原 id)

NONE 已存在/无关→不变
UPDATE 决策输出 JSON schema
{
  "memory": [
    {"id": "0", "text": "Loves cheese and chicken pizza",
     "event": "UPDATE", "old_memory": "I really like cheese pizza"},
    {"id": "1", "text": "User is a software engineer", "event": "NONE"}
  ]
}

决策规则非常具体,例如:「Loves to play cricket with friends」应 UPDATE「User likes to play cricket」;但「Loves cheese pizza」与「Likes cheese pizza」含义相同则 NONE。 这种 LLM 驱动的合并,是 mem0 早期「记忆会自己纠错」的来源。

6.2 新版:ADD-only 如何「演进」

新算法在 add()不再做 UPDATE/DELETE,而是:

对比小结:旧版=抽取后逐条比对、就地改库(脆弱、易丢历史);新版=只追加 + 链接 + 检索期排序(稳、可解释、保留全部演进轨迹)。平台版另有专有合并优化,但 OSS 默认走 ADD-only。

7检索管线:多信号融合检索

记忆的价值在「被召回的精准度」。mem0 的检索不是单纯向量最近邻,而是语义 + BM25 关键词 + 实体匹配三条信号并行打分、再融合。

Query 查询 + 过滤键 预处理 词形还原+实体抽取 ① 语义搜索向量 ANN 相似度 ② BM25 关键词提升信号(非召回扩展) ③ 实体匹配_entities 集合 boost 分数融合 加权 → 综合 score Reranker 可选精排 Top-K 返回结果
图 3 · 检索管线:语义 / BM25 / 实体三路并行打分,融合后可选重排取 Top-K

7.1 三路信号如何协作

7.2 过滤器:把记忆「框」对主体

search() 支持按 user_id / agent_id / run_id 以及任意 metadata 过滤,并支持丰富的比较算子:

过滤器算子示例
m.search(query, filters={
    "user_id": "alice",            # 精确匹配
    "metadata": {
        "category": {"==": "preference"},
        "tags":      {"in": ["work","health"]},
        "score":     {"gte": 0.7},
        "created_at":{"lte": "2026-07-01"},
        "label":     {"contains": "trip"}
    }
}, top_k=5)

支持的算子:== · != · in · nin · gte · lte · gt · lt · contains · or · and。过滤器在向量召回之后、返回之前生效。

7.3 时间推理(Temporal Reasoning)

reference_date 参数让检索具备时间感:「当前/过去/未来」的查询能正确排序实例。例如问「我下周的会议」与「我上周的会议」会落到不同的时间窗口,避免把旧记忆错当新记忆。

返回结构:结果以 {"results":[{id, memory, score, categories, metadata, created_at, ...}]} 返回。新版不再返回旧版的 relations 字段——实体关联已折叠进 score 的 boost 中。

8图记忆:从 Neo4j 到内置实体链接

这是新算法最大的架构变化之一。理解它,才能避免用旧心智模型去接 mem0。

🕓旧版:外置图存储

通过 enable_graph + graph_store 配置外挂 Neo4j / Memgraph / Kuzu / Apache AGE / Neptune。节点=实体,边=关系,search 返回 relations 供应用遍历。约 4000 行专用代码。

新版:内置实体链接

外部图库支持已整体移除。mem0 自己在 add 时抽取实体,存入向量库并行集合 {collection}_entities。共享实体的记忆被链接,检索时做 boost。

为什么这样改

迁移提示:若旧代码读取或遍历 search 结果里的 relations 数组,需针对新 API 重写——实体连接现在只通过检索排序体现。内置实体集合要求向量库有「建集合」权限(托管库权限受限时需手动预建同维度集合)。

9数据模型与记忆类型

一条记忆在向量库里长这样——它由「文本 + 向量 + 过滤键 + 元数据」四件套组成。

字段含义作用
id记忆唯一标识(uuid)get / update / delete / history 的句柄
memory / text自包含的事实语句召回后回填给 LLM 的内容
vectorEmbedder 产出的嵌入语义检索的相似度计算
user_id用户级归属用户记忆过滤键
agent_id智能体级归属智能体状态过滤键
run_id会话/运行级归属会话记忆过滤键
categories记忆类别标签语义分类(如 preference / event)
metadata任意业务键值支持 == / in / gte / contains 等算子过滤
created_at / updated_at时间戳时间推理、过期(expiration_date)
linked_memory_ids关联记忆 id 列表实体链接 / 图关系载体

三类记忆(按归属维度)

👤User Memory

关于用户的偏好、身份、计划。由 USER_MEMORY_EXTRACTION_PROMPT 从用户消息抽取。个性化推荐的核心。

💬Session Memory

run_id 隔离的会话级状态,适合多轮任务上下文隔离。

🤖Agent State

关于智能体自身的能力、配置、行为。由 AGENT_MEMORY_EXTRACTION_PROMPT 从助手消息抽取。

此外还有 PROCEDURAL_MEMORY_SYSTEM_PROMPT 支撑的过程记忆——把 Agent 过去 N 步的执行历史逐字摘要,供其无歧义续做任务。这是「会干活的记忆」,与上述「关于事实的记忆」互补。

10配置与可扩展性

mem0 的「通用」来自组件可插拔。 Library 模式默认组件如下,全部可用 Memory.from_config(...) 覆盖。

组件Library 默认Self-Hosted Server 默认
LLMOpenAI gpt-5-miniOpenAI gpt-5-mini
EmbedderOpenAI text-embedding-3-smallOpenAI text-embedding-3-small
VectorStore本地 Qdrant(/tmp/qdrant)Postgres + pgvector
HistoryStoreSQLite(~/.mem0/history.db)同左(服务内)
Reranker关闭(需配置)关闭(需配置)

可替换的 Provider 生态

用 from_config 覆盖默认组件
m = Memory.from_config({
  "llm": {"provider": "anthropic", "config": {"model": "claude-..."}},
  "embedder": {"provider": "huggingface", "config": {"model": "Qwen/Qwen3-Embedding-..."}},
  "vector_store": {"provider": "milvus", "config": {"collection_name": "mem0"}},
  "reranker": {"provider": "cohere"}
})

11一句话总结与启示

mem0 把「记忆」拆成一条可工程化的管道:用 LLM 把对话压缩成自包含事实 → 嵌入进向量库 → 实体链接织成隐式图 → 检索时语义/关键词/实体三路融合打分 → 可选重排取 Top-K。新算法用「ADD-only + 链接 + 检索期排序」替代了旧版脆弱的就地 UPDATE/DELETE。

对做情感陪伴 / 长期关系类产品的启示:记忆的「演进」不必靠覆盖,而可靠「追加 + 关联 + 时间加权召回」实现——这恰好契合你正在做的「陌生人→熟人→知己」关系递进与跨会话记忆。mem0 的实体链接与三类记忆(user/session/agent)可直接映射到你的用户画像、会话上下文与 AI 自身人格状态。

📍最小可运行闭环

add(messages, user_id)search(query, filters, top_k) → 把结果拼进 system prompt → 生成 → 再 add。几行即成记忆循环。

⚙️工程要点

事实自包含、屏蔽 system、语言跟随;检索三信号融合且 BM25 只做 boost;实体链接内建、不返 relations;历史落 SQLite 可溯源。