Zep
Paper · arXiv 2025 · 2501.13956

Zep:给 Agent 一张会「过期」的时间知识图谱

静态 RAG 把记忆当成不变的文本块,但用户的地址、职位、偏好都会变。Zep 用 Graphiti 把对话拆成实体与事实,给每条边记两套时间——世界何时为真、系统何时知道。冲突时旧事实只失效、不删除。代价是构图阶段大量 LLM 调用。

Preston Rasmussen 等 · Zep / Graphiti arXiv 2501.13956 ↗ Graphiti 代码 ↗
TL;DR · 30 秒抓住核心

普通 RAG 隐含三个假设:语料基本不变、相关性等于语义相似、事实一旦写入就长期有效。Agent 记忆三条都撞上——对话在持续发生,业务数据在更新,用户会搬家、换工作、改偏好。

Zep 的做法是把记忆做成时序知识图谱:底层 episode 存原始消息,中间层存实体和事实边,顶层存社区摘要。每条事实边带四个时间戳,分属两条轴:T 是世界时间,T′ 是系统摄入时间。

新事实与旧事实矛盾时,旧边不删除:只把 t_invalid 写成新边的 t_valid,把 t′_expired 写成新边的 t′_created。历史可查,当前状态也清楚。

检索不是单纯向量相似:cosine + BM25 + 图上的 BFS,再重排,最后把事实与时间范围拼成上下文。代价也很明确:单会话助理类问题反而下降 17.7%,结构化业务数据的联合推理没有基准验证。

94.8%
DMR 准确率(gpt-4-turbo)
MemGPT 93.4% / 全上下文 94.4%
71.2%
LongMemEval 准确率(gpt-4o)
全上下文 60.2%,论文称 +18.5%
1.6k
平均上下文 token
全上下文 115k;延迟 28.9s → 2.58s
01

静态 RAG 假设事实不会变,Agent 的记忆恰好一直在变

先建立一个共同认知:记忆的难点不是「找不到」,而是「不知道哪条现在还算数」。

普通 RAG 把文档切成块、向量化、按相似度取回。这套流程隐含三个假设:语料基本不变;相关性等于语义相似;一条事实一旦写入就长期有效。企业 Agent 三条都撞上——对话在持续发生,业务数据在更新,用户的地址、职位、偏好会变。

一个具体场景

用户说「我搬到 NYC 了」

向量库里同时躺着「User 住在 Boston」和「User 住在 NYC」。两句话语义高度相似,都会被召回;但只有一条是当前事实。没有有效区间,模型只能靠上下文顺序猜,或者把两条都写进 prompt,让 LLM 自己判断。对话越长,这种冲突越多。

另一条路是把全部历史塞进上下文。LongMemEval 的平均对话长度约 115,000 token;论文的 full-context 基线在 gpt-4o 上延迟 28.9 秒。成本之外,长上下文还会稀释关键信息。于是问题变成:如何在不丢历史的前提下,让每条事实带上「何时为真」和「系统何时知道」。

这两个时间不必重合。用户可能 6 月就搬了家,Zep 7 月才从对话里得知;这段时间里,世界时间已经翻页,系统时间还停在上一页。如果系统只存一个「当前值」,它既说不清自己当时知道什么,也无法在事后审计「为什么当时答错了」。

02

MemGPT 会分页,GraphRAG 会聚类,但都没把「失效」写进边

两套方案各解决了一半:一个管上下文,一个管结构;时间维度都缺席。

MemGPT

把记忆做成操作系统的分页

主上下文之外再开一层 archival storage,靠函数调用在两层之间换页。优点是能在有限窗口里维持长期对话,DMR 上用 gpt-4-turbo 达到 93.4%。

卡在哪:记忆单元仍是文本,检索靠相似度或摘要。事实没有显式的有效区间;新信息与旧信息冲突时,也没有一条边级的失效规则。

GraphRAG

把语料做成实体图

从语料抽实体和关系,做社区检测,再用 map-reduce 生成社区摘要。优点是能回答「这批文档整体在讲什么」这类全局问题。

卡在哪:它为静态语料设计:图构建一次,社区用 Leiden 划分,事实边不带双时态,也不处理「新事实让旧事实失效」。语料一变,图谱就要重建。

普通向量 RAG 更直接:块 + 余弦相似度。它连实体都没有,更谈不上时间。三者共同的缺口是:事实的生命周期没有被建模。Zep 的切入点不是「再加一个检索器」,而是把「失效」变成图上一次显式的写操作。

03

给每条边记两套时间:世界何时为真,系统何时知道

Zep 的核心不是「用了知识图谱」,而是把「失效」变成一次写操作,而不是删除。

论文把时间拆成两条轴。T 是事件在现实世界发生的顺序;T′ 是 Zep 摄入数据的顺序,也就是数据库的审计轨迹。每条事实边同时带四个时间戳:

T · 世界时间

事实在现实中何时成立

t_valid:事实开始为真的时刻。

t_invalid:事实不再为真的时刻。

回答「用户现在住哪」用它。

T′ · 系统时间

Zep 何时写入、何时标记失效

t′_created:这条边写入 Zep 的时刻。

t′_expired:这条边在 Zep 里被标记失效的时刻。

回答「系统当时知道什么」用它。

两者不必重合。用户可能 6 月就搬了家,Zep 7 月才从对话里得知;这段时间里,世界时间已经翻页,系统时间还停在上一页。论文的边失效规则只做两件事:

t_invalid(旧边) ← t_valid(新边)
t′_expired(旧边) ← t′_created(新边)
论文明确给出第一行;第二行是 T′ 审计轴的记录方式——旧边在新边写入时被标记失效

具体做法是:LLM 把新边与语义相关的旧边逐条比对,找出时间上重叠且互相矛盾的对;确认矛盾后,旧边的 t_invalid 被设为新边的 t_valid。在系统时间轴 T′ 上,旧边的 t′_expired 也在新边写入时被填上。结果是一条边从「无终点」变成「有终点」,历史仍然可查。

这也解释了为什么 Zep 要保留原始 episode:语义边会失效,但原始消息不该被改写。查询时既可以看当前有效的事实,也可以沿双向索引回到当时的原话。

自己动手:拖动同一条时间轴,看两条时间线何时分叉

下面用一组示意事实演示这套规则。切换 T 与 T′,拖动时间轴;再点「注入新事实」,观察旧边如何被写上终点。虚线表示这条边还没有进入图谱。

2023-012023-072024-012024-072025-01
当前视图下有效 不在当前区间 尚未写入图谱
当前视图

建议按这个顺序试:

这组日期是论文里的吗?点开看示意数据与真实规则的边界

不是。Boston → NYC、Coffee → Tea 的具体月份是为演示构造的,论文只给出规则,没有给出这组例子。规则本身取自论文:新边与语义相关的旧边比对,时间重叠且矛盾时,旧边的 t_invalid 被设为新边的 t_valid;系统时间轴上,旧边的 t′_expired 在新边写入时被填上;旧边保留。

模拟把「系统收到新事实」简化成一个按钮,省略了实体消解、事实抽取和 LLM 矛盾判断。真实系统里,这些步骤都可能出错:实体没对齐、关系抽错、日期解析错,都会让失效规则作用在错误的边上。

04

构图不在 GPU 上训,而是在摄入时反复调用 LLM

Zep 没有训练阶段;它的成本主要花在把每条消息变成实体、事实和失效判断。

一条消息进入 Zep 后,构图按固定流水线走:

工程上几个刻意的选择:写图用预定义 Cypher 查询,而不是让 LLM 生成查询,保证 schema 一致;社区用 label propagation 是为了支持增量更新,代价是社区会逐渐偏离完整重算的结果,所以仍需要周期性全量刷新;构图模型用 gpt-4o-mini,嵌入和重排用 BGE-m3。

成本在哪

没有反向传播,只有推理账单

实体抽取、反思、消解、事实抽取、矛盾判断、社区摘要,每一步都是 LLM 调用。论文没有给出每条消息的调用次数或 token 成本,也没有做消融;因此无法从论文数字里拆出「双时态」单独贡献了多少。能确认的是:这是一套推理时的构图系统,不是训练出来的记忆模型。

这也决定了它的扩展性讨论方式不同于训练模型:瓶颈不在 GPU 显存,而在摄入吞吐、LLM 调用成本和图数据库写入。论文把延迟作为一等指标报告,但没有给出千万级用户下的成本曲线。

05

三层图负责存,三步检索负责取

架构解决「记忆放哪」,检索解决「这一次该拿什么」。

社区子图 Gc · 高层摘要 工作 / 生活 / 偏好;社区名做向量索引 语义实体子图 Gs · 实体 + 事实边 User Boston NYC Coffee lives_in lives_in likes 2023-01 → 2024-06 t_invalid = 2024-06 2024-06 → 2024-09 失效 实体消解:余弦 + 全文检索 → LLM 判重;写图用预定义 Cypher 抽取 / 溯源 情节子图 Ge · 原始消息 + t_ref 消息 2024-01-10 消息 2024-06-20 消息 2024-09-15 无损存储;双向索引可从事实回到原话 同一条边的两套时间 User lives_in NYC T · 世界时间 t_valid 2024-06-01 t_invalid ∅ T′ · 系统时间 t′_created 2024-07-01 t′_expired ∅ 新事实到达时,旧边不删除: t_invalid(旧) ← t_valid(新) t′_expired(旧) ← t′_created(新)
图:Graphiti 的三层子图与一条事实边上的四个时间戳。原图未直接复制,按论文第 2 节文字重绘;图中日期为示意。

三层各司其职:episode 存原始消息,保证可溯源;semantic 存实体和事实边,边上带四个时间戳;community 存强连通实体的摘要,负责全局性问题。三者不是三份互相独立的存储,而是同一张图 G = (N, E, φ) 的三个子图。

检索是三个函数的复合

f(α) = χ(ρ(φ(α))) = β
输入查询 α,输出一段可直接塞进 LLM 的上下文 β;φ 搜索、ρ 重排、χ 组装
φ Search

余弦相似度 + Okapi BM25 全文检索 + n 跳 BFS。三者分别抓语义相似、词面匹配、图上的上下文接近;返回事实边、实体、社区三类候选。

ρ Rerank

支持 RRF、MMR、episode-mentions(按提及频率加权)、node-distance(按到中心节点的距离)、cross-encoder(最贵)。

χ Constructor

边输出事实 + t_valid/t_invalid;实体输出名称 + 摘要;社区输出摘要。时间范围会一起进入上下文。

实验里只取了 top 20 条边和实体(DMR 用 top 10)。这也是论文承认的边界:episode 与实体之间的双向索引没有被评估,检索系统的完整能力只验证了一部分。

06

长对话上提升明显,但有一类问题反而变差

DMR 已经饱和,真正有信息量的是 LongMemEval 的分题型结果。

DMR:只赢一点点,而且基准本身太短

记忆方案模型准确率
Recursive Summarization†gpt-4-turbo35.3%
Conversation Summariesgpt-4-turbo78.6%
MemGPT†gpt-4-turbo93.4%
Full-conversationgpt-4-turbo94.4%
Zepgpt-4-turbo94.8%
Conversation Summariesgpt-4o-mini88.0%
Full-conversationgpt-4o-mini98.0%
Zepgpt-4o-mini98.2%

† 为 MemGPT 论文报告的结果。Zep 在 gpt-4-turbo 上 94.8%,比 MemGPT 的 93.4% 高 1.4 个百分点,也只比 full-conversation 的 94.4% 高 0.4 个百分点。每段对话只有 60 条消息,塞得进上下文窗口;作者自己说这个基准区分度不足。

LongMemEval:准确率、延迟、上下文长度同时改善

记忆方案模型准确率延迟延迟 IQR平均上下文
Full-contextgpt-4o-mini55.4%31.3 s8.76 s115k
Zepgpt-4o-mini63.8%3.20 s1.31 s1.6k
Full-contextgpt-4o60.2%28.9 s6.01 s115k
Zepgpt-4o71.2%2.58 s0.684 s1.6k

gpt-4o 上 60.2% → 71.2%,论文称 18.5% 提升;gpt-4o-mini 上 55.4% → 63.8%,论文称 15.2%。延迟从 28.9 s 降到 2.58 s(约 90%),平均上下文从 115k 降到 1.6k。注意口径:18.5% 是论文的相对提升;按表中数字,绝对差是 11.0 个百分点。

分题型:时序推理涨得最多,单会话助理跌得最多

问题类型 gpt-4o-mini gpt-4o
Full-contextZep Full-contextZep
single-session-preference30.0%53.3%20.0%56.7%
single-session-assistant81.8%75.0%94.6%80.4%
temporal-reasoning36.5%54.1%45.1%62.4%
multi-session40.6%47.4%44.3%57.9%
knowledge-update76.9%74.4%78.2%83.3%
single-session-user81.4%92.9%81.4%92.9%

几个值得注意的点:

还有一个测量细节:Zep 的延迟是在波士顿的消费级笔记本上、连接 AWS us-west-2 测的,网络往返被算进了 Zep 的延迟;基线没有这段网络开销。因此 90% 的延迟降幅对 Zep 是偏保守的估计。

07

它解决的是「事实会变」,不是「记忆无限大」

论文自己列出的边界,比宣传语更有信息量。

边界一

单会话助理类问题会回退

single-session-assistant 是唯一在两个模型上都下降的类别:gpt-4o −17.7%,mini −9.06%。当答案就在最近一段对话里,图检索反而可能漏掉局部上下文。论文把这条列为「otherwise consistent improvements」的例外,并说需要更多工程工作。

边界二

弱模型用不好时间数据

knowledge-update 在 gpt-4o-mini 上不升反降(76.9% → 74.4%),在 gpt-4o 上升 6.52%。时间范围被写进上下文,不等于模型会用它;能力较弱的模型可能被多出来的时间字段干扰。

边界三

社区会漂移,必须周期性重算

增量 label propagation 只做一步递归,新节点按邻居多数票归入社区。这样省 LLM 调用,但社区会逐渐偏离完整重算的结果。论文明确说,周期性全量刷新仍然必要。

边界四

结构化业务数据没有被验证

论文的动机是「对话历史 + 结构化业务数据」的联合记忆,但实验只测了对话。作者承认,现有基准无法评估 Zep 把对话与业务数据放在一起推理的能力。这是动机与实验之间最大的一道缝。

边界五

没有消融,归因只能靠机制推断

论文没有拆开双时态、社区层、混合检索各自的贡献,也没有报告构图成本。DMR 又太短:60 条消息的对话,full-context 已经能到 94.4%。因此「涨了多少是因为时间建模」这个问题,论文没有直接回答。

一句话总结:Zep 解决的是「同样的历史里,怎么知道哪条现在还算数」,而不是「把记忆容量做大」。它适合事实会更新、需要审计「当时知道什么」的场景;如果任务只是从固定文档里找答案,普通 RAG 或长上下文可能更简单。