用「擷取 + 整併 + 檢索」三步把多輪對話壓成精煉記憶,讓 LLM agent 在跨 session 對話裡保持一致,且把延遲砍掉 91%。
就算 GPT-4o 給 128K、o1 給 200K、Gemini 1.5 給 10M context window,LLM agent 在跨日、跨週的對話裡仍會「忘記」使用者偏好。Mem0 主張這不是 context 不夠長的問題,而是缺少一套像人類那樣可以選擇性儲存、整併、回憶的記憶機制。
論文用 Figure 1 的素食使用者為例:第一次對話提到「我是素食、不吃乳製品」;隔了一段時間再問「晚餐推薦?」,沒有記憶的系統直接回 chicken,完全推翻先前偏好。這類失敗會直接破壞使用者信任,在醫療、教育、企業客服等高風險場景尤其致命。
幾週/幾月的對話累積起來,動輒上百 K tokens,連 10M context 都會用盡。Full-context 只是延後問題,不是解決。
研究顯示 attention 在距離拉長後會退化(Guo 2024、Nelson 2024),關鍵資訊埋在幾千個 token 的程式碼討論裡時,模型常常根本沒注意到。
使用者可能先聊飲食,然後談幾個小時程式,再回頭問晚餐 — full-context 必須在每次查詢時都重讀全部歷史,代價極高。
論文後續實驗會證明:full-context p95 延遲 ~17 秒、每次 query 都消耗 26K tokens,根本不可能上 production。
Mem0 的核心主張:不要把所有對話原文塞進 prompt,而是用一個專門的記憶層在背景擷取重要事實 → 整併冗餘 → 在 query 時只 retrieval 最相關片段。這是一個「結構化、持久、可演化」的記憶模組,讓 agent 跨 session 也能保有一致個性。
兩階段流程(extraction + update),用 LLM 透過 tool-call 在 ADD / UPDATE / DELETE / NOOP 之中選擇正確的記憶操作。
把記憶結構化成 directed labeled graph,以實體為節點、關係為邊,擅長 temporal 與 open-domain reasoning。
對 6 大類 baseline (5 memory 系統 + RAG + full-context + OpenAI memory + LangMem + Zep) 全面評估。
相對 full-context: J 只差 4-6 分,但 p95 latency 砍 91%、token 省 90% 以上。
Mem0 採「增量處理」設計:每來一對新訊息就跑一次 pipeline,擷取候選事實,再決定要對既有記憶做哪種操作。整個流程靠 LLM 的 tool-call 機制做分類,不需要額外的 classifier。
對話新加進來一對訊息 (mt-1, mt)(通常是 user + assistant 一輪),系統用兩個來源建立 context:
{mt-m, ..., mt-2},提供 fine-grained 的時序 context;實驗中 m = 10。對每個候選事實 ωi,先用 vector embeddings 從 DB 抓 top-s = 10 條語意相近的記憶,然後把「候選事實 + 相似記憶」一起餵給 LLM,透過 function-call 的 tool-call 介面選一個動作:
沒有語意等價的既有記憶 → 建立新記憶。
既有記憶可被補強 → 把更豐富的資訊覆蓋進去。
新事實與既有記憶矛盾 → 刪掉舊的。
不需任何變動(已存在或不相關)。
為什麼不用獨立 classifier?論文明確指出:他們刻意「直接讓 LLM 透過 reasoning + tool-call 來決定」,而不是訓練一個獨立的分類器。理由是 LLM 已經能根據候選事實與既有記憶的語意關係做出正確判斷,加一層 classifier 反而增加 latency 與訓練成本,且無法 generalize。
# Mem0 default configuration (論文 Section 2.1 末段)
m = 10 # 最近訊息視窗
s = 10 # 比對相似記憶數
LLM = "gpt-4o-mini" # 所有 LLM 操作(extraction + update)
vector_db = "dense embeddings" # 用於 update phase 的 similarity search
Mem0g 把對話事實改用 directed labeled graph 表示:實體為節點、關係為邊。這個結構在跨多輪、需要 relational reasoning 的任務(尤其 temporal、open-domain)上特別有利。底層用 Neo4j 當 graph DB。
每個節點 v ∈ V 帶三個欄位:① entity type、② 語意 embedding ev、③ metadata(含 creation timestamp tv)。關係以三元組 (vs, r, vd) 表達。
LLM 從對話文字中辨識出 entities + types。論文舉例:旅遊對話會抓出 destinations(城市/國家)、transportation modes、dates、activities、participant preferences — 任何「未來可能會被引用」的離散資訊。
LLM 對每組可能的 entity pair 判斷有沒有有意義的關係,若有就標上 label (lives_in、prefers、owns、happened_on...),產出三元組構成圖的邊。
每加入新三元組時,先對 source 與 destination 兩端各算 embedding,在圖中找 similarity 高於 threshold t 的既有節點;依「兩端都有 / 一端有 / 兩端都沒有」分支處理。關鍵設計:衝突的舊關係不會被物理刪除,而是被標記為 invalid,這樣才能保留 temporal reasoning 的歷史軌跡。
從 query 抓出關鍵實體 → 在圖中找對應節點 → 系統性遍歷 incoming + outgoing 邊 → 拼出相關子圖。適合「精準找某人的某項屬性」這類查詢。
把整個 query 編碼成 dense embedding → 對所有 triplet 的文字編碼算相似度 → 取超過 threshold 的、依降序排序回傳。適合較概念性、不容易定位 anchor 實體的查詢。
實作棧:Graph DB = Neo4j;extractor / update module 用 GPT-4o-mini + function calling 做結構化抽取。
這個演算法描述 update 階段「對每個候選事實如何決定操作」的完整流程。Mem0 與 Mem0g 都用同一套邏輯,只是 storage 結構不同。
# Algorithm 1 · Memory Management System: Update Operations
# Input : retrieved facts F, existing memory store M = {m1, ..., mn}
# Output: updated memory store M'
procedure UpdateMemory(F, M):
for each fact f in F:
operation = ClassifyOperation(f, M)
if operation == "ADD":
id = GenerateUniqueID()
M = M ∪ {(id, f, "ADD")} # 加入新事實
elif operation == "UPDATE":
mi = FindRelatedMemory(f, M)
if InformationContent(f) > InformationContent(mi):
M = (M \ {mi}) ∪ {(id_i, f, "UPDATE")} # 用更豐富的資訊覆蓋
elif operation == "DELETE":
mi = FindContradictedMemory(f, M)
M = M \ {mi} # 刪掉被推翻的記憶
elif operation == "NOOP":
pass # 不變動
return M
function ClassifyOperation(f, M):
if not SemanticallySimilar(f, M):
return "ADD" # 全新資訊
elif Contradicts(f, M):
return "DELETE" # 與既有記憶衝突
elif Augments(f, M):
return "UPDATE" # 強化既有資訊
else:
return "NOOP" # 無需變動
實作上的關鍵細節:ClassifyOperation 並不是另一個 model,而是「把 f 與 M 中相似的記憶塞進 prompt,讓主 LLM 直接透過 tool-call 回傳要呼叫哪個動作」。InformationContent、Contradicts、Augments 等判斷也都是同一次 LLM call 裡內隱完成,而非分開的 utility function。
LOCOMO 是專為 long-term conversational memory 設計的 benchmark,涵蓋多 session、跨日的對話與大量問答,是目前最完整的 memory 評估資料集之一。
10
每段 multi-session
600
每段對話
26K
每段對話
200
每段對話對應
答案在單一 dialogue turn 裡,直接 retrieval 即可。
需要跨多個 session、整合分散資訊才能回答。
仰賴事件順序、相對時間推理(「上個月」、「兩週前」)。
需要結合對話內知識與外部 world knowledge。
原始 LOCOMO 還有 adversarial 類別(測 agent 能不能拒絕不可回答的問題),作者排除掉,因為這類問題沒有 ground truth 答案。
傳統 lexical overlap 指標。論文明指其缺陷:「Alice was born in March」vs「Alice is born in July」這種事實錯誤,F1/B1 還是會給高分。
主要指標。用更強的 LLM 從事實正確性、相關性、完整性、context 合適度多維評分。為了控制隨機性,每個方法跑 10 次取平均 ± 1σ。
Token consumption(cl100k_base 編碼)+ search latency + total latency(p50/p95)。直接反映 production 成本。
為什麼 J 是主指標?因為對話場景的「正確答案」常有多種等價說法。F1/B1 抓不到語意正確性,J 則是讓 LLM 像人類評審那樣做整體判斷,跟人類標註一致性更高。
LoCoMo、ReadAgent、MemoryBank、MemGPT、A-Mem
LangMem (Hot Path)
chunk 128–8192 × k ∈ {1, 2}
整段 26K tokens 直接塞 prompt
OpenAI ChatGPT memory(gpt-4o-mini)
Zep — 為 agent 設計的 memory 平台
所有對照組統一用 gpt-4o-mini、text-embedding-small-3、temperature = 0 以求可重現。
下表為 LOCOMO 上每個方法在四種 question 類型下的 F1 / B1 / J。粗體 = 該欄最佳;橘色 = 本文方法。J 為 10 次 run 平均 ± 1σ。
| Method | Single-Hop | Multi-Hop | Open-Domain | Temporal | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| F1 ↑ | B1 ↑ | J ↑ | F1 ↑ | B1 ↑ | J ↑ | F1 ↑ | B1 ↑ | J ↑ | F1 ↑ | B1 ↑ | J ↑ | |
| LoCoMo | 25.02 | 19.75 | – | 12.04 | 11.16 | – | 40.36 | 29.05 | – | 18.41 | 14.77 | – |
| ReadAgent | 9.15 | 6.48 | – | 5.31 | 5.12 | – | 9.67 | 7.66 | – | 12.60 | 8.87 | – |
| MemoryBank | 5.00 | 4.77 | – | 5.56 | 5.94 | – | 6.61 | 5.16 | – | 9.68 | 6.99 | – |
| MemGPT | 26.65 | 17.72 | – | 9.15 | 7.44 | – | 41.04 | 34.34 | – | 25.52 | 19.44 | – |
| A-Mem | 27.02 | 20.09 | – | 12.14 | 12.00 | – | 44.65 | 37.06 | – | 45.85 | 36.67 | – |
| A-Mem* | 20.76 | 14.90 | 39.79 ± 0.38 | 9.22 | 8.81 | 18.85 ± 0.31 | 33.34 | 27.58 | 54.05 ± 0.22 | 35.40 | 31.08 | 49.91 ± 0.31 |
| LangMem | 35.51 | 26.86 | 62.23 ± 0.75 | 26.04 | 22.32 | 47.92 ± 0.47 | 40.91 | 33.63 | 71.12 ± 0.20 | 30.75 | 25.84 | 23.43 ± 0.39 |
| Zep | 35.74 | 23.30 | 61.70 ± 0.32 | 19.37 | 14.82 | 41.35 ± 0.48 | 49.56 | 38.92 | 76.60 ± 0.13 | 42.00 | 34.53 | 49.31 ± 0.50 |
| OpenAI | 34.30 | 23.72 | 63.79 ± 0.46 | 20.09 | 15.42 | 42.92 ± 0.63 | 39.31 | 31.16 | 62.29 ± 0.12 | 14.04 | 11.25 | 21.71 ± 0.20 |
| Mem0 (本文) | 38.72 | 27.13 | 67.13 ± 0.65 | 28.64 | 21.58 | 51.15 ± 0.31 | 47.65 | 38.72 | 72.93 ± 0.11 | 48.93 | 40.51 | 55.51 ± 0.34 |
| Mem0g (本文) | 38.09 | 26.03 | 65.71 ± 0.45 | 24.32 | 18.82 | 47.19 ± 0.67 | 49.27 | 40.30 | 75.71 ± 0.21 | 51.55 | 40.28 | 58.13 ± 0.44 |
A-Mem* 表示作者重跑 A-Mem (temperature=0) 並產生 J 分數,原 paper 沒有提供。
Mem0 以 J = 67.13 拿下最佳,比第二名 OpenAI(63.79)高約 5%、比 LangMem / Zep 都高約 8%。Mem0g 在這欄略輸 Mem0,顯示「資訊只在單一 turn」時,relational 結構帶來的好處有限。A-Mem* 落後 25 分以上,印證 fine-grained、結構化 indexing 的必要性。
Mem0 J = 51.15、F1 = 28.64,顯著贏過所有 baseline。值得注意的是 Mem0g(47.19)在這欄並沒贏 Mem0,作者解讀為「圖結構在跨 session 整合複雜資訊時可能反而引入冗餘 / overhead」,密集自然語言記憶在這類整合任務上更直接。
Zep 以 J = 76.60 排第一,Mem0g 緊追在後(75.71,僅差 0.89)、Mem0 = 72.93。作者認為 Zep 在整合對話記憶與外部知識上有一致(但微小)的優勢。
Mem0g 在 temporal 上同時拿下 F1 (51.55) 與 J (58.13) 兩個最佳值,Mem0 也有 55.51。OpenAI 在這欄災難性地只有 21.71,原因是 ChatGPT 即使被 prompt 要求帶 timestamp,實際生出的 memories 大多沒有時間戳。結論:結構化 relational graph + 顯式時間戳,是 temporal reasoning 的關鍵。
容易誤讀的點:不要被「Zep 在 open-domain 贏」誤導為「Zep 整體更好」。Zep 在 single-hop(61.70 vs Mem0 67.13)、multi-hop(41.35 vs 51.15)、temporal(49.31 vs 58.13)都顯著輸,而且 token 成本是 Mem0 的 86 倍(下節展開)。
論文真正想說服讀者的是「Mem0 不只精確,還可上 production」。這節整理 search/total p50/p95 latency 與整體 J,並附 token store 大小比較。
| Method | K / chunk | Memory tokens | Search p50 | Search p95 | Total p50 | Total p95 | Overall J |
|---|---|---|---|---|---|---|---|
| RAG (k=1) | 128 | – | 0.281 | 0.823 | 0.774 | 1.825 | 47.77 ± 0.23 |
| RAG (k=1) | 256 | – | 0.251 | 0.710 | 0.745 | 1.628 | 50.15 ± 0.16 |
| RAG (k=1) | 512 | – | 0.240 | 0.639 | 0.772 | 1.710 | 46.05 ± 0.14 |
| RAG (k=1) | 1024 | – | 0.240 | 0.723 | 0.821 | 1.957 | 40.74 ± 0.17 |
| RAG (k=1) | 2048 | – | 0.255 | 0.752 | 0.996 | 2.182 | 37.93 ± 0.12 |
| RAG (k=1) | 4096 | – | 0.254 | 0.719 | 1.093 | 2.711 | 36.84 ± 0.17 |
| RAG (k=1) | 8192 | – | 0.279 | 0.838 | 1.396 | 4.416 | 44.53 ± 0.13 |
| RAG (k=2) | 128 | – | 0.267 | 0.624 | 0.766 | 1.829 | 59.56 ± 0.19 |
| RAG (k=2) | 256 | – | 0.255 | 0.699 | 0.802 | 1.907 | 60.97 ± 0.20 |
| RAG (k=2) | 512 | – | 0.247 | 0.746 | 0.829 | 1.729 | 58.19 ± 0.18 |
| RAG (k=2) | 1024 | – | 0.238 | 0.702 | 0.860 | 1.850 | 50.68 ± 0.13 |
| RAG (k=2) | 2048 | – | 0.261 | 0.829 | 1.101 | 2.791 | 48.57 ± 0.22 |
| RAG (k=2) | 4096 | – | 0.266 | 0.944 | 1.451 | 4.822 | 51.79 ± 0.15 |
| RAG (k=2) | 8192 | – | 0.288 | 1.124 | 2.312 | 9.942 | 60.53 ± 0.16 |
| Full-context | – | 26031 | – | – | 9.870 | 17.117 | 72.90 ± 0.19 |
| A-Mem | – | 2520 | 0.668 | 1.485 | 1.410 | 4.374 | 48.38 ± 0.15 |
| LangMem | – | 127 | 17.99 | 59.82 | 18.53 | 60.40 | 58.10 ± 0.21 |
| Zep | – | 3911 | 0.513 | 0.778 | 1.292 | 2.926 | 65.99 ± 0.16 |
| OpenAI | – | 4437 | – | – | 0.466 | 0.889 | 52.90 ± 0.14 |
| Mem0 (本文) | – | 1764 | 0.148 | 0.200 | 0.708 | 1.440 | 66.88 ± 0.15 |
| Mem0g (本文) | – | 3616 | 0.476 | 0.657 | 1.091 | 2.590 | 68.44 ± 0.17 |
取 Table 2 中 Total p95 與 Overall J 排序:
| Method | Overall J | Total p95 (s) | 每分 J 的 latency 成本 |
|---|---|---|---|
| Full-context | 72.90 | 17.117 | 0.235 |
| Mem0g (本文) | 68.44 | 2.590 | 0.038 |
| Mem0 (本文) | 66.88 | 1.440 | 0.022 |
| Zep | 65.99 | 2.926 | 0.044 |
| RAG (k=2, 256) | 60.97 | 1.907 | 0.031 |
| LangMem | 58.10 | 60.400 | 1.040 |
| OpenAI | 52.90 | 0.889 | 0.017 |
「每分 J 的 latency 成本」= Total p95 ÷ Overall J,越小越好(由本文導讀計算,非論文原始指標)。
核心 trade-off 一句話:Full-context 還是 J 最高(72.90),但 p95 要 17 秒。Mem0 用 1.44 秒(快 11.9 倍)拿到 66.88(只低 6 分),Mem0g 用 2.59 秒拿到 68.44(只低 4.5 分)。換算下來:Mem0 的 p95 latency 比 full-context 砍 91%。
7k
tokens / 對話
14k
tokens(含節點 + 邊)
26k
raw 對話 token
600k+
Mem0 的 86 倍
Zep 的爆量來自其設計:每個 node 都 cache 一份 abstractive summary,邊上又另存 facts,造成嚴重 redundancy。論文還 calls out:Zep 加完記憶後立刻查詢常常答錯,要等幾小時 background processing 才能拿到好結果 — 對 real-time application 不可用。相對地,Mem0 圖建構最差情況也在 1 分鐘內完成。
論文的主要 selling point:Mem0 / Mem0g 提供「accuracy ≈ full-context,但 token 與 latency 砍掉一個數量級以上」的 production-ready 平衡 — 這是把 LLM agent 從 demo 推到真實 deployment 的關鍵。
論文 Appendix A 完整列出 LLM-as-a-Judge、Mem0 / Mem0g 答案生成、以及 OpenAI ChatGPT memory baseline 的 prompt。下面摘錄結構,完整內容請參照論文 pp.18-20。
為了讓評估更公平,作者強調 J 在「答案語意相同但表述不同」時應該寬鬆給分。例如時間格式不同(May 7th vs 7 May)或相對 vs 絕對時間(last Tuesday vs 2023-05-02)都算 CORRECT。
Your task is to label an answer to a question as "CORRECT" or "WRONG".
You will be given:
(1) a question (posed by one user to another user)
(2) a 'gold' (ground truth) answer
(3) a generated answer which you will score as CORRECT/WRONG
# Example
Question: Do you remember what I got the last time I went to Hawaii?
Gold answer: A shell necklace
# Generated answer can be much longer; be generous if it touches the same topic.
# Time-related questions: format / relative vs absolute time can both be CORRECT
# if they refer to the same date or period.
Question: {question}
Gold answer: {gold_answer}
Generated answer: {generated_answer}
First, provide a short (one-sentence) explanation of your reasoning,
then finish with CORRECT or WRONG. Do NOT include both labels.
Return the label in json format with the key "label".
You are an intelligent memory assistant tasked with retrieving accurate
information from conversation memories.
# CONTEXT
You have access to memories from two speakers in a conversation.
These memories contain timestamped information that may be relevant to
answering the question.
# INSTRUCTIONS
1. Carefully analyze all provided memories from both speakers
2. Pay special attention to the timestamps to determine the answer
3. If the question asks about a specific event or fact, look for direct evidence
4. If the memories contain contradictory information, prioritize the most recent
5. Convert relative time references ("last year") to specific dates based on
the memory timestamp. e.g. a memory from "4 May 2022" mentioning "went to
India last year" → trip in 2021.
6. Always convert relative time references to specific dates/months/years.
7. Focus only on the content of the memories; do not confuse character names
mentioned inside memories with the actual users who created them.
8. The answer should be less than 5-6 words.
# APPROACH (step by step)
1. Examine all memories related to the question
2. Examine the timestamps and content carefully
3. Look for explicit mentions of dates / times / locations / events
4. If the answer requires calculation, show your work
5. Formulate a precise, concise answer based solely on the evidence
6. Double-check that your answer directly addresses the question
7. Ensure your final answer is specific and avoids vague time references
Memories for user {speaker_1_user_id}:
{speaker_1_memories}
Memories for user {speaker_2_user_id}:
{speaker_2_memories}
Question: {question}
Answer:
# 與 8.2 相同,但 APPROACH 多一步:
5. Analyze the knowledge graph relations to understand the user's knowledge context
# 並且 prompt 末段除了 memories 外,還會附上:
Memories for user {speaker_1_user_id}:
{speaker_1_memories}
Relations for user {speaker_1_user_id}:
{speaker_1_graph_memories}
Memories for user {speaker_2_user_id}:
{speaker_2_memories}
Relations for user {speaker_2_user_id}:
{speaker_2_graph_memories}
Question: {question}
Answer:
觀察:Mem0 與 Mem0g 的 prompt 差異只有「多餵 graph relations」與「多一句指示要分析 relations」。換句話說,Mem0g 的精度提升幾乎全部來自 retrieval 側的結構化 memory,而不是 prompt engineering 的不同。
Can you please extract relevant information from this conversation and
create memory entries for each user mentioned? Please store these memories
in your knowledge base in addition to the timestamp provided for future
reference and personalized interactions.
(1:56 pm on 8 May, 2023) Caroline: Hey Mel! Good to see you! ...
(1:56 pm on 8 May, 2023) Melanie: Hey Caroline! Good to see you! ...
...
# 整段 LOCOMO 對話直接餵進單一 chat session
作者特別說明:這個 baseline 比正常 OpenAI memory 使用情境「更寬鬆」,因為他們是把所有抽出的 memories 都當 context 給後續問答,而不是只用 question-relevant 的部分 — 算是給 OpenAI 一個 fair-or-better 的 setup。即便如此,OpenAI 在 temporal 上仍只有 21.71。
作者把這篇定位成「memory layer for production AI agents」的第一步:已經能在跨 session、跨日的對話裡保持一致,且 token / latency 足以上 production,但還有幾個方向值得繼續做。
+5%
vs 最佳 baseline
+7%
vs 最佳 baseline
+11%
vs 最佳 baseline(Mem0g)
−91%
vs full-context
Mem0g 雖然 J 最高,但 search/total latency 仍是 Mem0 的 3 倍以上。需要更高效的 graph traversal 與 incremental update 策略。
結合 dense natural-language memory(快、適合 single-hop)與 graph memory(精確、適合 temporal / open-domain)的階層化設計。
仿照人類睡眠期的記憶整合,設計更智慧的 memory consolidation pipeline,降低冗餘並強化重要事件。
把 Mem0 的記憶框架推到 procedural reasoning(多步驟任務 agent)與 multimodal interactions(視覺 + 語音 + 文字)。
未在論文討論但讀者應注意:① Mem0 的 LLM 都用 gpt-4o-mini;當底層 model 升級時,所有 baseline 也會跟著進步,Mem0 的相對 gain 是否仍維持需要重 benchmark。② LOCOMO 雖是 long-term conversational memory 最完整 benchmark,但只有 10 段對話 × 平均 200 題,sample size 偏小;不同 random seed 下排名可能微調。③ Open-domain 上 Zep 仍領先,顯示「dense + graph」之外的「對話內知識 + 外部知識」融合仍有改進空間。