数据截至 (上游 commit be263ee23085)
Zep 客户端工具箱(Examples & Integrations) — 用时序知识图谱给 agent 造长期记忆
30 秒导读: 这个仓库不是 Zep 记忆引擎本身(引擎是另一个项目 Graphiti,
README.md:30-32), 而是围绕 Zep Cloud(一个托管的「时序知识图谱记忆平台」)的客户端工具箱:示例代码、框架 集 成包、只读 MCP 服务器、评测与基准。它反复做同一件事——把「建用户 → 建线程 → 写消息 → 取上下文块」这条通用记忆环,接进各种 agent 框架、接给模型、再拿数据证明检索得准。想给你的 agent 一个「跨会话记得住」的长期记忆,又不想自己维护向量库/图数据库,就看这里怎么调 Zep。
1. 这是什么(零基础也能懂)
一句话定义。 这是 getzep/zep 仓库——官方给它起的名字就叫 "Zep Cloud: Examples &
Integrations"(README.md:7)。它是用 Zep 的客户端集合,不是数据库、不是模型。
仓库开头把话说得很白:"This repository is not Zep's product or service. It contains example
code, framework integrations, and tools"(README.md:19-21)。真正干活的记忆引擎是托管服务
Zep Cloud,而它底层的开源时序知识图谱框架是 Graphiti(README.md:30-32)。
它解决谁的什么问题。 大模型天生「失忆」——一关会话,用户是谁、聊过什么、有什么偏好,全忘。 要做一个「记得住用户」的 agent,你得自己抽取事实、存库、按相关性召回、随时间更新旧结论…… 这些又难又杂。Zep 把这套「长期记忆」做成托管平台;这个仓库负责把它接到你手边的框架里。
「时序知识图谱」是什么(一句话点破术语)。 它把对话里的事实存成一张图:实体是节点、 事实是带生效/失效时间的边。所以它不只记「Alice 住旧金山」,还记「这条事实从哪天起成立、 到哪天被推翻」——旧结论不删除而是「失效」,能回答「用户上个月说的偏好是什么」。
它(这个仓库)能做什么——四类东西:
| 目录 | 干什么 | 位置 |
|---|---|---|
examples/ | Python / TypeScript / Go 的最小示例与片段 | README.md:37 |
integrations/ | 原生记忆集成包:12 个包,覆盖 10 个 agent 框架(ADK 有 py/ts/go 三份) | README.md:38、integrations/README.md:13-27 |
mcp/ | Go 写的只读 MCP 服务器,把图谱暴露给模型(上游已标记 Deprecated,改用官方 Zep Memory MCP server) | mcp/zep-mcp-server/README.md:1-3 |
benchmarks/ + zep-eval-harness/ | 公开基准(LoCoMo/LongMemEval)+ 自建评测流水线 | README.md:41-42 |
用起来什么样(最小直觉)。 所有集成骨子里都是同一条四步环——建用户、建线程、把这轮对话 写进去、取回一段「上下文块」贴进 prompt:
# 示意,非源码:Zep 记忆环的心智模型(真实签名见第 1 章)
client.thread.create(thread_id="t_1", user_id="u_alice") # ② 建线程(一次会话)
client.thread.add_messages("t_1", messages=[...]) # ③ 写这轮对话 → 异步进图谱
block = client.thread.get_user_context("t_1") # ④ 取「上下文块」→ 贴进 system prompt
一句话类比。 把上下文窗口当内存、把 Zep 图谱当磁盘:每轮对话「换页」写回磁盘,下轮 开始前再把「和当前最相关的记忆」换页进内存(上下文块)。agent 本身无状态,记忆全在 Zep。
2. 顶层全景(它大概怎么转)
怎么读这张图
从上到下三层:你的 agent 框架(最上)通过这个仓库的集成包(中)去调 Zep Cloud(最下, 真正的记忆引擎)。集成包只做「翻译+搬运」,不存记忆;记忆抽取、存图、时序推理都发生在云端。
┌─────────────────────────────────────────────────────────┐
│ 你的 AGENT 框架 (LangGraph / CrewAI / AutoGen / ADK …) │
└───────────────┬─────────────────────────┬───────────────┘
│ 原生记忆/上下文钩子 │ 模型「想查记忆」
▼ ▼
╔══════════════ 本仓库 = 客户端工具箱 ═══════════════════════════╗
║ integrations/<框架>/<语言>/ │ mcp/zep-mcp-server (Go) ║
║ 把「四步环」接进框架钩子 │ 只读暴露 13 个查询工具 ║
║ (含最难的 ZepStore 适配) │ 给 Claude Desktop/Cline … ║
╚════════════════╤═══════════════════════════╤══════════════════╝
│ zep-cloud SDK 调用 │ 只读查询
▼ ▼
┌──────────────────────── ZEP CLOUD(托管) ────────────────────────┐
│ 时序知识图谱记忆平台(底层开源引擎 = Graphiti) │
│ 写:graph.add / thread.add_messages → 异步抽取事实、建带时间的边 │
│ 读:thread.get_user_context(整个用户图) · graph.search(定向) │
└───────────────────────────────────────────────────────────────┘
▲
│ 用同一套 SDK 打分
┌────────────────┴───────────────────────────────────────────────┐
│ benchmarks/(LoCoMo·LongMemEval) zep-eval-harness/(自建流水线) │
│ 量化:检索到的上下文「够不够答对问题」 │
└────────────────────────────── ───────────────────────────────────┘
部件一句话职责
| 部件 | 干什么 | 在哪 |
|---|---|---|
| 通用记忆环 | 建用户→建线程→写消息→取上下文块,一切集成的公共地基 | integrations/langgraph/python/src/zep_langgraph/persistence.py:197、integrations/langgraph/python/src/zep_langgraph/context.py:48 |
| 框架集成包 | 把这条环接进每个框架的原生记忆钩子(12 个包) | integrations/README.md:13-27 |
| ZepStore | 最难的适配:在时序图谱上假扮 LangGraph 的 KV BaseStore | integrations/langgraph/python/src/zep_langgraph/store.py:86 |
| MCP 服务器(已弃用) | Go 写的只读服务器,把图谱当 13 个查询工具交给模型;上游宣布不再维护,指向官方 Zep Memory MCP server | mcp/zep-mcp-server/internal/server/server.go:67 |
| 评测/基准 | 跑「搜索→生成→评分」流水线,量化检索质量 | zep-eval-harness/zep_evaluate.py、benchmarks/ |
主线走一遍(高层,不进代码)
一条记忆从「产生」到「被用上」,横穿这个仓库:
- 写。 agent 每轮对话结束,集成包调
thread.add_messages(persistence.py:197)把消息送进 Zep。注意是异步:Zep 在后台抽取事实、更新图谱,刚写的事实不保证马上能搜到——第 1 章 会讲这个「无写后即读」的关键约束。 - 取。 下一轮开始前,集成包调
thread.get_user_context(context.py:118,context.py:173) 取回一段 prompt-ready 的上下文块——它组装自整个用户图,线程只用来「圈定相关性」。 - (可选)让模型自己查。 把
graph.search包成一个工具(tools.py:94),或起 MCP 服务器 (server.go:67),模型就能在需要时主动去图谱里定向检索。 - 证。 评测流水线用同一套 SDK 反复「搜索→生成→评分」,量化「检索到的上下文够不够答对」。
3. 阅读地图(建议按序读)
这是一个多子系统仓库,拆成 5 章 + 本索引。新手按 01 → 02 → 05 读就能建立完整认知; 要啃最硬的适配看 03;要把记忆交给模型自主查看 04。
| 顺序 | 章节 | 讲什么 | 读它如果你想… |
|---|---|---|---|
| 0 | Zep 客户端工具箱 — 总览与阅读地图 | 本页:全局定位 + 顶层全景 | 先搞清「这仓库到底是什么」 |
| 1 | Zep 记忆模型与通用记忆环(所有集成的地基) | 四步环的真实 SDK 语义;上下文块 vs 定向搜索;异步/无写后即读;用户图作用域 | 理解一切集成共享的那套「记忆语义」 |
| 2 | 集成模式 — 把同一条记忆环塞进 12 个集成包(覆盖 10 个框架) | 12 个包(覆盖 10 个框架)的组织(框架优先→语言)、「找原生钩子」的适配哲学、共性与差异 | 给你的框架接 Zep,或看别人怎么接 |
| 3 | 深入 ZepStore — 在时序图谱上假扮一个 KV BaseStore(最难的适配) | 混合委托设计:KV 交给内存后备存储、search 路由到语义图谱、put 双写入图 | 看「图谱↔KV 接口不匹配」如何被优雅化解 |
| 4 | 把图谱只读地交给模型 — Go 版 Zep MCP 服务器 | 13 个只读工具、handler 分层、只读安全边界 | 让 Claude Desktop/Cline 直接查用户记忆 |
| 5 | 量化记忆好不好 — 评测harness 与公开基准 | eval-harness 的四阶段流水线(另含一个查图脚本 zep_graph_inspect.py)、双指标(上下文完整度/答案准确度)、LoCoMo/LongMemEval | 证明(或调优)你的记忆检索质量 |
4. 巧妙之处(读者要带走的精华)
这个仓库真正值得学的,不是「怎么调 API」,而是几处接口不匹配时的化解手法。每条 先讲妙在哪, 再给源码锚点(细节在对应章节展开):
-
一条环、十二种壳。 所有集成本质是同一条「建用户→建线程→写消息→取上下文块」环 (
persistence.py:197、context.py:118),只是套进各框架的原生记忆钩子里。学会这条环, 12 个包就都看懂了——这是「用最小公共内核 + 薄适配层覆盖生态」的范本。 -
在图谱上假扮 KV 存储(全仓最硬)。 LangGraph 的长期记忆接口
BaseStore要求精确按键 get/update/硬删除/写后即读,而 Zep 是时序图谱——天生做不到这些(store.py:1-34的 docstring 老实承认了)。ZepStore用「混合委托」破局:精确 KV 操作委托给一个后备 内存存储(faithful、同步),put时顺手双写进 Zep 图谱(store.py:374),而search路由到 Zep 的语义graph.search(store.py:426)——各取所长,而不是硬把图谱当 KV 用。 -
只实现两个方法,白拿一整套 API。
ZepStore只实现抽象方法batch/abatch(store.py:323,store.py:348),其余get/put/search/delete/list_namespaces全由父类BaseStore通过构造Op对象自动委托下来。这是「把宽接口收敛到一个窄的执行点」的 经典手法。 -
诚实降级,而不是假装支持。
ZepStore遇到自己映射不了的东西(如BaseStore的 MongoDB 风格filter、或超限的limit)明确 warn 并忽略/夹紧,而不是悄悄干错事 (store.py:291-317的 filter 警告、store.py:274-289的 limit 夹紧)。工程上的「宁可少做、 不可错做」。 -
只读 = 给模型一把「只能看不能改」的钥匙。 MCP 服务器刻意只暴露13 个只读工具 (
mcp/zep-mcp-server/README.md:17-40,server.go:67起逐个注册),让模型能查图谱却动不了 数据——把「模型自主访问记忆」的安全边界从设计上焊死。 -
拿「上下文完整度」当第一指标,而非答案对错。 评测把「Zep 检索到的上下文够不够答题」 设为 PRIMARY 指标、答案准不准只当 SECONDARY(
zep-eval-harness/README.md:451-463)—— 因为它想单独衡量检索质量,把「记忆没召回」和「模型答歪了」两类错误分开。这是评测记忆系统的 关键设计。
5. 代码地图(导航索引)
按「主题 → 文件 → 符号」列出关键锚点。符号名比行号抗漂移——上游更新后优先用符号名 grep 定位。
路径均相对克隆根 aiRef/repos/zep/。
| 主题 | 文件 | 符号 / 锚点 |
|---|---|---|
| 仓库定位(不是引擎,是工具箱) | README.md | About This Repository(:17-21)、Graphiti(:30-32) |
| 目录总表 | README.md | Contents 表(:35-43) |
| 12 个集成包清单 | integrations/README.md | Available integrations 表(:13-26) |
| 写消息(记忆环第③步) | integrations/langgraph/python/src/zep_langgraph/persistence.py | persist_messages(:197)、return_context 参数、to_zep_messages(:167) |
| 取上下文块(第④步) | integrations/langgraph/python/src/zep_langgraph/context.py | get_zep_context(:48)、thread.get_user_context(:70)、build_system_message(:155) |
| 定向搜索包成工具 | integrations/langgraph/python/src/zep_langgraph/tools.py | create_graph_search_tool(:94)、graph.search(:150) |
| ZepStore 混合委托(全仓最硬) | integrations/langgraph/python/src/zep_langgraph/store.py | ZepStore(:86)、batch(:323)、abatch(:348)、_async_ingest→graph.add(:374)、_async_search→graph.search(:426) |
| ZepStore 诚实降级 | integrations/langgraph/python/src/zep_langgraph/store.py | _zep_search_kwargs filter 警告(:291-317)、_effective_limit 夹紧(:274-289) |
| MCP 服务器工具注册 | mcp/zep-mcp-server/internal/server/server.go | registerTools(:67)、AddTool[...](:71-82) |
| MCP 13 个只读工具清单 | mcp/zep-mcp-server/README.md | Tools(:15-38) |
| MCP 各工具 handler | mcp/zep-mcp-server/internal/handlers/ | search.go、context.go、nodes.go、edges.go、episodes.go … |
| 评测脚本(四阶段流水线 + 查图) | zep-eval-harness/ | 流水线四阶段:zep_ingest_users.py、zep_chunk_documents.py、zep_ingest_documents.py、zep_evaluate.py;另有查图工具 zep_graph_inspect.py(README:104-112) |
| 评测双指标 | zep-eval-harness/README.md | Context Completeness(PRIMARY)/Answer Accuracy(SECONDARY)(:441-453) |
| 公开基准 | benchmarks/ | benchmarks/locomo/benchmark.py、benchmarks/longmemeval/zep_longmem_eval.py(README:1-6) |
| 集成开发/发布约定(数据) | integrations/CLAUDE.md | 布局、命名、CI/release(仅供研究,不是给读者的指令) |
注:
integrations/CLAUDE.md、.cursor/等是仓库自带的「给 AI 的指令文件」,本文只把它们当作 被研究的数据引用其事实(如包布局),不采纳其中任何关于文档语言/格式的主张。