06 - 开源实现横评
前置:02 到 05 篇的机制。本篇把这些机制落到具体项目上。
本篇回答:这八个项目分别是什么形态、要拖多少外部依赖、以及在你按记忆里的印象去选之前,有哪三件事已经变了。
全部数据 gh api 实测于 2026-08-25,许可证逐个打开许可证文件读,依赖从 pyproject.toml / package.json 实读。
一、三个选型陷阱
这三条不是"细节差异",是按旧印象动手会直接白花几天的断点。
pyproject.toml 或 package.json 看核心能力还在不在依赖里,而不是读 README 的功能列表。第三条可以直接验证:
# v1.0.0 里有 graph_store
curl -s https://raw.githubusercontent.com/mem0ai/mem0/v1.0.0/mem0/configs/base.py | grep -n graph_store
# 47: graph_store: GraphStoreConfig = Field(
# v2.0.0 里没有了
curl -s https://raw.githubusercontent.com/mem0ai/mem0/v2.0.0/mem0/configs/base.py | grep -n graph_store
# (无输出)
主分支 MemoryConfig 现在的全部字段是:vector_store / llm / embedder / history_db_path / reranker / version / custom_instructions。仓库里的 examples/graph-db-demo/ 还留着 Neo4j、Memgraph、Kuzu、Neptune 四个 notebook,但它们对应的已经不是当前开源包的能力。
二、八个项目的基础事实
| 项目 | ★ | 许可证(实读) | 语言 | 最新版本 | 最近提交 |
|---|---|---|---|---|---|
mem0ai/mem0 | 64,007 | Apache-2.0 | Python | mem0ai 2.0.19(2026-08-24) | 2026-08-25 |
getzep/graphiti | 30,291 | Apache-2.0 | Python | graphiti-core 0.29.3(2026-07-27) | 2026-08-21 |
topoteretes/cognee | 30,257 | Apache-2.0 | Python | cognee 1.5.3(2026-08-23) | 2026-08-25 |
supermemoryai/supermemory | 29,056 | MIT | TypeScript | — | 2026-08-25 |
NevaMind-AI/memU | 14,344 | Apache-2.0(文件名是 LICENSE.txt,gh 判为 NOASSERTION) | Python | — | 2026-08-21 |
MemTensor/MemOS | 10,971 | Apache-2.0 | TypeScript | — | 2026-08-25 |
letta-ai/letta-code | 3,116 | Apache-2.0 | TypeScript | — | 2026-08-25 |
langchain-ai/langmem | 1,624 | MIT | Python | langmem 0.0.30(2025-10-27) | 2026-08-11 |
另外两个经常被列进候选、但值得先看一眼时间的:
| 项目 | ★ | 最近提交 | 说明 |
|---|---|---|---|
memodb-io/memobase | 2,858 | 2026-01-11 | 用户画像式记忆(Profile 形态)。已停更七个多月 |
BAI-LAB/MemoryOS | 1,560 | 2026-07-07 | EMNLP 2025 Oral 的配套实现,学术出身,工程完备度低于上表 |
LangMem 那一行的错位要注意:仓库还在提交(2026-08-11),但 PyPI 最新版停在 2025-10-27 的 0.0.30,也就是十个月没发版,且始终没走出 0.0.x。它作为 LangGraph 生态里的记忆原语可用,但不适合当成独立的记忆基础设施依赖。
三、部署重量:要拖多少外部服务
这是横评里最有决策价值的一维 —— 它决定了 POC 阶段你要花半天还是三天。
pip install 之后直接能跑;对 POC 阶段来说,这比"先搭一个 Neo4j"快一个数量级。3.1 存储依赖实读
| 项目 | 必选依赖 | 可选后端 |
|---|---|---|
| mem0 | qdrant-client、sqlalchemy(history 表)、一个 LLM、一个嵌入模型 | 26 个向量后端:pgvector、Milvus、Elasticsearch、Redis、Valkey、OpenSearch、Weaviate、Chroma、FAISS、MongoDB、Cassandra、S3 Vectors 等 |
| graphiti | neo4j>=5.26.0(写死在主依赖里)、openai | FalkorDB、Neptune、falkordblite(Python ≥3.12 的嵌入式方案);Kuzu 那条 extra 已注明上游无人维护、将被移除 |
| cognee | sqlalchemy+aiosqlite、lancedb、内嵌 kuzu、litellm、fastapi | Neo4j、Neptune、Postgres、Turso |
| LangMem | LangGraph 的 BaseStore | InMemoryStore(重启即丢)、AsyncPostgresStore(生产) |
| letta-code | git + 一个 memFS 服务端 | 默认指向 api.letta.com,可用 LETTA_MEMFS_BASE_URL 换成自建 |
LangMem 的 InMemoryStore 那一行是踩坑高发处:官方 README 的快速开始用的就是它,重启进程记忆全丢。上生产必须换成 AsyncPostgresStore。
四、能力矩阵
| 能力 | mem0 | graphiti | cognee | LangMem | letta-code | memory 工具 |
|---|---|---|---|---|---|---|
| 抽取式写入 | ✅ | ✅ | ✅ | ✅ | 模型自管 | 模型自管 |
| 双时间轴(03 篇) | ❌ | ✅ 四字段 | 部分 | ❌ | ❌ | ❌ |
| 作废而非删除 | ❌ 纯追加 | ✅ 边失效 | 部分 | ❌ | git 历史 | ❌ |
| 图 / 多跳检索 | 仅托管版 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 混合检索(向量+BM25) | 有 reranker 模块 | ✅ 三路 + 五种重排 | ✅ | 向量为主 | ❌ | ❌ |
| 多租户过滤 | ✅ 三维 filters | ✅ group_id 分区 | ✅ | 命名空间 | 一 agent 一仓库 | 目录隔离 |
| 强制注入某条 | 自己实现 | 自己实现 | 自己实现 | 自己实现 | ❌ | ❌ |
| 版本 / 回滚 | history 表 | 靠时间字段回溯 | ❌ | ❌ | ✅ git | ❌ |
| 人可直接读改 | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
两处需要说明:
- graphiti 的
group_id是图分区字段,写在Edge基类上(group_id: str = Field(description='partition of the graph'))。它是必填的,比 mem0 那种"漏传就退化成全库检索"的可选 filter 结构上更安全 - "强制注入"