Graphiti Temporal Memory 源码深潜:双时间、实体消歧与事实失效
Agent Memory Engineering 专栏 · 6/6。 Graphiti 研究的核心不是“用图数据库存聊天”,而是如何让事实同时拥有实体身份、来源 Episode、业务有效时间、摄取时间、冲突失效区间与可组合的混合检索信号。
专栏导航:总览与选型地图 · Codex · Claude Code · Hermes · Mem0 · Letta · Graphiti
0. 研究基线:Temporal Memory 不等于 Graph RAG
本文于 2026-07-15 联网核对 Graphiti 官方 Adding Episodes 文档、Zep 论文与固定版本源码;源码基线为 getzep/graphiti Commit 526dcad7a300f3c5c506ff96a68bcdc7ca9f97ed。[G1][G2][G3]
阅读路径:
graphiti.py:add_episode↓node_operations.py: extract / candidate / resolve↓edge_operations.py: extract / duplicate / contradiction / timestamp↓nodes.py + edges.py: temporal schema↓search/search.py + recipes↓saga summary + dual watermarks0.1 十三个研究问题
- Episode、Entity、Fact Edge 与 Community 分别是什么?
created_at、valid_at、reference_time为什么不能合并?invalid_at与expired_at的业务语义有何不同?- 为什么写入前要召回 Previous Episodes?
- Entity Resolution 如何降低身份碎片和错误合并?
- Duplicate Candidate 与 Contradiction Candidate 为什么是两类集合?
- 新事实如何关闭旧事实的有效区间,而不是物理删除?
- 普通
add_episode为什么要求顺序 Await? - 为什么 Bulk Ingestion 的网页文档与固定源码在 Edge Invalidation 上发生契约漂移?
- Saga 为什么需要 Processing-time 与 Event-time 双 Watermark?
- Search 为什么同时查 Edge、Node、Episode、Community?
- BM25、Cosine、BFS、RRF、MMR、Cross Encoder 如何组合?
- 如何评测时间正确性,而不是只测语义相关性?
1. Graphiti 的数据模型:Event、Identity、Fact 与 Summary 分层
1.1 Episodic Node:原始摄取事件
EpisodicNode 保存:[G4]
uuidnamegroup_idsource / source_descriptioncontentcreated_atvalid_atentity_edgesepisode_metadataEpisode 是一个 Ingestion Event,而不是已经 Canonicalized 的事实。它保留原始文本、消息或 JSON,并通过 MENTIONS 连接到 Entity。
1.2 Entity Node:被消歧后的身份
EntityNode 保存:
namename_embeddingsummarylabels / typesattributes它解决:
“Jupiter”“Jupiter363”“该项目作者”是否指向同一实体的问题。
1.3 Entity Edge:带时间与来源的事实
EntityEdge 连接两个 Entity,并保存:[G5]
name / relationfactfact_embeddingepisodes[]created_atvalid_atinvalid_atexpired_atreference_timeattributes关系边本身就是 Fact Record,而不只是图遍历连接。
1.4 Community:区域摘要
Community Node / Edge 对局部图进行聚类和摘要,适合高层主题召回。它不是原始事实真相源,而是 Derived Projection。
1.5 Saga:有序 Episode 序列
固定版本新增 Saga Node 与 HAS_EPISODE / NEXT_EPISODE,用于把一组连续 Episode 组织成可增量摘要的长叙事。[G6]
flowchart LR E1["Episode 1"] -->|"MENTIONS"| N1["Entity A"] E1 -->|"MENTIONS"| N2["Entity B"] N1 -->|"Fact Edge + temporal interval"| N2 S["Saga"] -->|"HAS_EPISODE"| E1 E1 -->|"NEXT_EPISODE"| E2["Episode 2"] N1 --> C["Community Summary"]2. 双时间:世界发生时间与系统知道时间
2.1 created_at:Transaction / Ingestion Time
Episode created_at 由系统摄取时生成:
系统什么时候把这条 Episode 写入图?2.2 valid_at:Event / Reference Time
调用 add_episode(reference_time=...) 时,Episode valid_at 使用业务事件的参考时间:[G7]
这条 Episode 描述的事情在世界中何时发生?2.3 为什么必须分开
2026-07-15 ingestion:“用户在 2025-01-10 搬到上海”
created_at = 2026-07-15valid_at = 2025-01-10如果只保留 created_at,系统会误以为搬家发生在 2026;如果只按 valid_at 推进摄取 Watermark,迟到数据可能被永久跳过。
2.4 Fact Edge 的五个时间字段
| 字段 | 问题 |
|---|---|
created_at | 系统何时创建这条 Edge? |
valid_at | 事实何时开始成立? |
invalid_at | 事实何时不再成立? |
expired_at | 系统何时将 Edge 标记为已失效/过期? |
reference_time | 生成这条 Edge 的 Episode 参考时间是什么? |
invalid_at 属于业务有效区间;expired_at 更接近系统失效标记。两者混用会让“世界事实变化”和“系统维护状态”无法区分。[G5]
2.5 Bitemporal Query
理想查询可以分别问:
AS OF valid time:2025-06-01 用户住在哪里?
AS OF transaction time:系统在 2025-06-01 当时知道用户住在哪里?固定版本提供了必要字段,但应用是否暴露完整 Bitemporal Query API,需要根据 Search Filter 与业务层自行设计。
3. add_episode:在线写入是一条有序语义流水线
官方文档和源码都建议每个 Episode 顺序加入并 Await 完成,Web 应用可用 Background Queue,但同一序列不能无约束并发。[G3][G7]
固定版本主路径:[G7]
validate types + group→ retrieve previous episodes→ create / load episode→ extract nodes→ resolve entity identities→ extract edges and attributes→ resolve duplicates and contradictions→ invalidate old edges→ persist episode / nodes / edges→ optional community update→ trace counts and latency3.1 为什么先取 Previous Episodes
当前 Episode 可能写:
“她上周从北京搬到了上海。”没有前序上下文,模型不知道“她”是谁,也无法判断旧的北京居住关系是否需要结束。
Previous Episodes 提供局部 Schema 与叙事连续性:
- 指代消解;
- 已出现 Entity;
- 旧关系;
- 时间变化;
- 用户自定义 Type Context。
3.2 previous_episode_uuids
调用方可以显式传 Previous Episode UUID,避免依赖“按最近 created_at 自动选择”。这对外部有严格序列的事件流很重要:
Kafka partition order→ previous UUID from prior committed result→ deterministic local context3.3 Group Partition
group_id 是图分区与查询隔离键。固定实现会校验,并可能 Clone Driver 到对应 Database。[G7]
它必须被当成 Tenant Boundary:Node Resolution、Edge Candidate Search、Search 与 Delete 都不能跨 Group 意外混合。
4. Entity Extraction 与 Resolution:身份规范化是图质量上限
Node Pipeline 包含:[G8]
extract_nodes→ collapse exact duplicates in current extraction→ collect exact / semantic candidates→ LLM resolution when needed→ commit canonical UUID mapping→ extract attributes and summaries4.1 Exact Collapse
同一 Episode 中重复提取的 Entity 先本地折叠,避免后续每个重复都触发数据库候选搜索和 LLM Resolution。
4.2 Candidate Retrieval
Resolution 不是让 LLM 在全图自由猜 UUID,而是先构造有限候选:
exact name candidate∪ semantic name candidate∪ previous-episode entities再让 LLM 判断 Merge 或 New Entity。
4.3 两种错误
False Merge:
Apple companyApple fruit→ incorrectly one node污染会沿所有关系扩散。
False Split:
OpenAIOpen AIthe company→ three nodesRecall 会碎片化,多跳关系断裂。
4.4 Custom Entity Types
entity_types 允许用 Pydantic Model 定义类型与属性;excluded_entity_types 可以禁止某些类型进入图。[G7][G8]
Ontology 越严格:
- Extraction 更一致;
- 但新实体更容易被错误套入旧类型;
- Schema Evolution 更复杂。
需要保存 ontology_version / extractor_version 才能解释历史 Node 为什么拥有某些 Label。
5. Fact Extraction:Duplicate 与 Contradiction 必须分开
Edge Pipeline 包含:
extract_edges→ exact / semantic duplicate filtering→ resolve extracted edge→ extract timestamps→ resolve contradictions→ produce resolved + invalidated + new edges相关函数在固定版本 edge_operations.py 中显式分离。[G9]
5.1 Duplicate Candidate
问题是:
新 Fact 是否已经表达过同一关系?如果是,通常应:
- 复用 Edge;
- 添加当前 Episode 到 Provenance List;
- 避免重复 Fact。
5.2 Contradiction Candidate
问题是:
新 Fact 是否让某条旧 Fact 从某个时间起不再成立?例如:
Old: Alice lives in Beijing, valid_at=2024-01New: Alice moved to Shanghai, valid_at=2025-09正确操作不是删除旧 Fact,而是:
Old.invalid_at = 2025-09New.valid_at = 2025-095.3 为什么不能用一个 Similarity Threshold 同时解决
Duplicate 与 Contradiction 都可能高度语义相似:
“用户住在北京”“用户不再住在北京”仅靠 Embedding 很可能把两者当近重复。需要结合关系类型、否定、时间与 Entity Pair 判断。
5.4 Provenance List
EntityEdge.episodes[] 保存引用该 Fact 的 Episode ID。[G5]
它支持:
- 回到原始证据;
- 统计多次提及;
- 删除 Episode 时判断 Edge 是否仍有其他来源;
- 解释为什么 Fact 存在。
但 Episode List 只提供来源 ID;来源 Trust、Extractor Model 与具体 Text Span 仍需额外 Metadata 才能完成细粒度审计。
6. Temporal Conflict:关闭区间,而不是覆写当前值
Flat KV Memory 常做:
location = ShanghaiGraphiti 路线保存:
Alice --lives_in--> Beijingvalid_at=2024-01invalid_at=2025-09
Alice --lives_in--> Shanghaivalid_at=2025-09invalid_at=null6.1 三种查询
Current state→ invalid_at is null or after now
Historical state at t→ valid_at <= t < invalid_at
Evolution→ order facts by valid_at6.2 迟到数据
2026 年摄取一条 valid_at=2025-02 的 Episode,可能需要插入到已有时间线中间,并重新计算相邻 Fact 的区间。
这比“新消息总是覆盖旧消息”复杂得多:
- 新 Episode 的 Processing Time 最新;
- 但 Event Time 可能更早;
- 它可能不是 Current State;
- 却可能修复一段历史空白。
6.3 Temporal Extraction Error
相对时间“去年春天”“下周一”依赖 Episode Reference Time。Reference Time 错误会让所有 Fact Interval 错位。
生产系统应保留:
raw temporal expressionnormalized timestampreference_timetimezoneextraction confidence7. Sequential 与 Bulk:官方文档和固定源码存在契约漂移
官方 Adding Episodes 文档明确写道:add_episode_bulk 只应用于空图或不要求 Edge Invalidation 的导入,并称 Bulk Pipeline 不执行 Invalidation。[G3]
但本文固定的 526dcad 源码已经不同:add_episode_bulk() 的 Docstring 明确声明 Bulk 同样执行日期提取与 Edge Invalidation;实现也从 _resolve_nodes_and_edges_bulk() 收集 invalidated_edges,并与新 Edge 一起持久化。[G14]
因此不能把“Bulk 不做 Invalidation”写成这个固定 Commit 的源码事实。更准确的判断是:公开文档落后于固定源码,使用者必须按实际安装版本验证 Bulk 契约。
7.1 为什么 Bulk 更快
它可以:
- 批量 Extraction;
- 批量 Embedding;
- 减少每 Episode 前序查询;
- 并行更多 CPU / Network Work。
7.2 为什么仍不能假设它与顺序在线写入等价
在线事实变化依赖顺序:
Episode 1 establishes fact AEpisode 2 contradicts A and opens BEpisode 3 refers to B即使固定版本已经补上 Invalidation,Bulk 内的多个 Episode 仍经过批量抽取、去重和并行 Resolution。调用方需要验证同一 Batch 内的顺序冲突是否与逐条 await add_episode() 完全一致,特别是:
- Episode 2 是否能看到 Episode 1 刚提取但尚未持久化的事实;
- 同一 Batch 内的多个 Contradiction 是否按
valid_at稳定关闭区间; - Previous Episode Context 是否与调用方业务序列一致;
- Retry 整个 Batch 时,部分已持久化对象是否保持幂等。
7.3 导入策略
Historical bootstrap on empty graph→ bulk load→ validate in-batch invalidation + reconciliation
Online updates→ partition by group / saga→ sequential queue per partition→ await commit before next episode跨 Partition 可并行;对严格依赖状态演化的同一 Entity Graph,逐 Episode 顺序路径仍是更容易证明的默认选择。若采用 Bulk,必须固定 Graphiti 版本,并用 Contradiction / Late-arrival Fixture 验证实际语义,而不能只依据当前网页文档或最新源码中的任意一方。
8. Persist 与故障窗口
add_episode 涉及:
- Episodic Node;
- Entity Nodes;
- Entity Edges;
- MENTIONS Edges;
- Invalidated Old Edges;
- Optional Saga Links;
- Optional Communities。
8.1 原子边界依赖 Graph Driver
源码在多个异步步骤中保存不同对象。是否处于同一数据库事务、Driver 是否支持跨查询原子提交,需要按 Provider 验证,不能只因使用 Graph DB 就假设完整 ACID Workflow。
8.2 典型部分成功
Entity nodes savedbut fact edges failed
New edge savedbut old contradictory edge not invalidated
Episode savedbut MENTIONS incomplete
Facts savedbut community update failed8.3 Idempotency
调用方可传 Episode UUID。生产 Ingestion 应用稳定 Event ID 作为幂等键,避免 Queue Retry 生成重复 Episode。
但 Episode 幂等不自动保证 Extracted Node / Edge 全部幂等;需要:
- Deterministic Resolution;
- Unique Constraints;
- Episode Processing Status;
- Reconciliation Job。
8.4 Saga / Outbox 补强
ingestion_event→ PENDING→ episode saved→ entities resolved→ edges committed / invalidated→ projections updated→ COMPLETE失败可从最后 Checkpoint 重放,而不是重新执行全部非确定 LLM Extraction。
9. Saga 双 Watermark:Processing Time 与 Event Time
SagaNode 保存:[G4][G6]
summaryfirst_episode_uuidlast_episode_uuidlast_summarized_atlast_summarized_episode_valid_at9.1 last_summarized_at
这是 Wall-clock Watermark,用于下一次只筛选 created_at > since 的新摄取 Episode。[G6]
迟到 Episode 今天才写入,即使 valid_at 是去年,它的 created_at 仍是今天,因此不会漏掉。
9.2 last_summarized_episode_valid_at
这是 Episode-time Watermark,记录 Summary 已覆盖 Episode 的最大 valid_at,供消费者回答“摘要在业务时间上覆盖到哪里”。[G6]
9.3 为什么一个 Watermark 不够
如果只用 Event-time Watermark 过滤下一批:
last valid_at = 2026-01late event valid_at = 2025-12, ingested today→ incorrectly skipped如果只暴露 Processing-time:
summary updated today却不能说明内容在业务时间上是否只覆盖到去年。

图 1:last_summarized_at 推进摄取过滤;last_summarized_episode_valid_at 表达事件时间覆盖。两个 Watermark 必须保持不同语义,但双 Watermark 本身并不自动解决分页积压与并发摄取竞态。
9.4 Incremental Summary 的边界
固定版本每次最多取 200 个 Episode,并把 Existing Summary 与新 Episode 一起交给 LLM;成功后将 last_summarized_at 直接推进到 utc_now(),而不是本批已处理 Episode 的最大 created_at。[G6]
风险:
- 新 Episode 超过 200 条时,未进入本批的 Episode 可能已经早于新的 Wall-clock Watermark,后续查询不会再选中;
- Episode 在 Fetch 之后、Watermark 保存之前完成写入时,也可能落入同一个跳过窗口;
- 摘要反复重写产生 Drift;
- 迟到旧事件可能改变已有摘要结构;
- LLM 成功但 Watermark 保存失败会重复处理;
- Watermark 成功但 Summary 未持久化会漏内容。
生产实现应在读取前固定 upper_bound,按 (created_at, uuid) 游标分页,只把 Watermark 推进到最后一条已成功纳入摘要的 Episode;再用 Versioned Summary 或事务保证 Summary 与 Watermark 同步提交。
10. Search:Graph Memory 不是 Traversal-only
固定版本 search() 并行执行四个 Scope:[G10]
edge_searchnode_searchepisode_searchcommunity_search配置 Recipe 支持:[G11]
BM25Cosine SimilarityBFSRRFMMRCross EncoderNode DistanceEpisode Mentions10.1 为什么查 Edge
用户问题通常针对事实:
谁负责项目?用户什么时候搬家?系统依赖哪个服务?Fact Text 与时间主要在 Entity Edge。
10.2 为什么查 Node
Node Search 适合 Entity Name、Type、Summary 和属性。
10.3 为什么查 Episode
Episode 保留原始上下文与 Provenance。当 Fact Summary 不足时,需要回到原始事件。
10.4 为什么查 Community
Community 是更高层主题摘要,适合宽泛 Query 和图区域发现。
10.5 BFS 的作用
BM25 / Vector 解决内容相关性,BFS 解决图结构邻近。给定 Center Node 或 Origin Nodes 后,结构信号可以把与任务实体相连但文本不相似的 Fact 带入候选。
10.6 Reranker 选择
| Reranker | 目标 |
|---|---|
| RRF | 融合多个 Rank List,简单稳健 |
| MMR | 相关性与多样性平衡 |
| Cross Encoder | 更精细 Query-Document 判断,成本更高 |
| Node Distance | 偏好图距离近的候选 |
| Episode Mentions | 偏好多来源提及的事实 |
“Hybrid Graph Search”真正含义是内容、结构、来源和重排的组合,不是只跑一次 Cypher Traversal。
11. Search Filter、Group 与时间正确性
11.1 Tenant Isolation
group_ids 在 Search 入口被校验,并传给 Edge / Node / Episode / Community Search。[G10]
任何一个 Scope 忘记 Group Filter 都可能泄漏其他租户的 Entity 或 Fact。
11.2 Temporal Filter
查询 Current Fact 时必须过滤无效区间;查询历史时必须使用目标时间。只按 Final Similarity 排序,可能把语义高度相关但已失效的旧 Fact 放在第一位。
11.3 Conflict Set
当同一 Entity Pair / Relation 存在多条时间相邻 Fact,Context Builder 应整体获取 Conflict Set:
Old fact + valid intervalNew fact + valid intervalSource episodes只把其中一条塞给模型,会丢失变化与不确定性。
12. Deletion、Invalidation 与 Provenance
12.1 Invalidation
业务事实变化时,旧 Edge 保留并设置 invalid_at / expired_at,用于历史查询。
12.2 Episode Removal
固定版本 remove_episode() 的实际边界比一个通用级联删除更窄:它读取 Episode 关联的 Fact Edge,只删除 episodes[0] 等于该 Episode UUID 的 Edge;只删除当前仅被一个 Episode MENTIONS 的 Entity,最后删除 Episode 本身。[G13]
这意味着实现审计还要追问:当被删 Episode 不是 episodes[] 第一项时,数组中的来源引用由谁移除?Community、Saga 与 Summary 由谁重建?源码主函数中没有展示这些派生物的同步更新。因此生产删除工作流必须额外考虑:
- MENTIONS Edge;
- Fact Edge 的
episodes[]; - 该 Fact 是否还有其他 Episode 来源;
- Entity 是否成为孤儿;
- Community Summary 是否需要重建;
- Saga Link 与 Summary 是否需要更新。
12.3 合规删除与历史保留冲突
Temporal System 倾向保留历史,但用户删除请求可能要求物理删除所有派生数据。
这类“可召回的派生记忆无法随源数据删除”的风险也是 Agent Memory 治理必须单独验证的攻击与合规面。[G12]
需要 Tombstone Workflow:
mark subject deletion→ delete / redact episodes→ remove provenance references→ rebuild or delete facts→ rebuild communities / sagas→ purge embeddings and caches→ verify no searchable projection“设置 invalid_at”不能替代隐私删除。
13. Cost Model:图的表达能力不是免费的
一次 Episode 可能触发:
- Node Extraction LLM;
- Entity Resolution LLM;
- Edge Extraction LLM;
- Contradiction / Timestamp LLM;
- Node Attribute / Summary LLM;
- Entity Name / Fact Embedding;
- 多次 Graph Query;
- Optional Community Update。
13.1 写放大
Graphiti 用 max_coroutines 和并行流程降低 Wall-clock,但 Provider Rate Limit、Graph Connection Pool 与 Group Ordering 仍要协调。
13.2 什么时候不该用 Temporal Graph
- 只有少量稳定偏好;
- 没有 Entity / Relation Query;
- 不需要历史状态;
- 写入延迟和成本极敏感;
- 团队无法维护 Ontology 与 Resolution Eval。
这时 Flat Memory + Expiration 可能更务实。
14. Evaluation:相关不等于时间正确
14.1 Entity Resolution
merge precision / recallfragmentation ratefalse merge blast radius14.2 Fact Extraction
relation precision / recallprovenance completenessattribute accuracy14.3 Temporal Correctness
valid_at accuracyinvalid_at accuracycurrent-state accuracyhistorical-state accuracylate-arrival repair accuracy14.4 Invalidation
需要专门构造:
- 明确重复;
- 明确矛盾;
- 偏好增强但非冲突;
- 临时例外;
- 迟到旧事实;
- 同名不同实体。
测量 Duplicate 与 Contradiction 是否被混淆。
14.5 Search
分别测:
Edge Recall@KNode Recall@KEpisode Evidence Recall@KCommunity Topic Recall@KCurrent Fact PrecisionConflict-set Completeness14.6 End-to-end
最终问题是:给定时间点 与系统当时可见的 Episode 集合,Agent 是否基于正确有效事实回答,并引用正确来源。
15. 生产化参考架构
flowchart TB ES["Partitioned Episode Stream"] --> IQ["Idempotent Ingestion Queue"] IQ --> EX["Extraction + Resolution Workers"] EX --> GS["Temporal Graph Store"] EX --> JL["Job / Mutation Log"] GS --> RC["Reconciliation"] RC --> GS GS --> HS["Hybrid Search"] HS --> CB["Temporal Context Builder"] CB --> AG["Agent"] GS --> SG["Saga / Community Projectors"] SG --> GS JL --> DLQ["Retry / Dead-letter"]15.1 Ingestion State
RECEIVED→ EXTRACTING→ RESOLVING→ COMMITTING→ PROJECTING→ COMPLETEor RETRYABLE / QUARANTINED15.2 Reconciliation
周期检测:
episode without mentionsedge references missing episodeinvalid interval overlapsentity fragment candidatesorphan nodessaga watermark behind ingestionsummary version behind episodes15.3 Observability
固定版本已经写入 Tracing Span,包括 Node / Edge / Invalidation / Previous Episode Count 与 Duration。[G7]
生产指标还应包括:
episode_lag_secondsresolution_candidate_countentity_false_merge_rateedge_invalidation_ratelate_episode_ratetemporal_interval_violation_countsearch_latency_ms{scope,method}saga_summary_lagreconciliation_repair_total16. Graphiti 路线的优势与边界
16.1 优势
- Episode 保留原始事件与 Provenance;
- Entity Resolution 建立长期身份;
- Fact Edge 同时保存文本、来源、Embedding 与时间区间;
- Invalidation 保留历史而不是覆盖;
- Previous Episode 提供叙事连续性;
- Saga 用 Processing-time 过滤与 Event-time Coverage 区分迟到事件语义;
- Edge / Node / Episode / Community 多 Scope Search;
- BM25 / Vector / BFS / Reranker 组合灵活;
- Group Partition 支持隔离。
16.2 边界
- LLM 与 Embedding 写放大高;
- Entity Resolution 错误会污染全图;
- Temporal Extraction 与 Ontology Drift 难评测;
- 同 Group 在线写入需要顺序控制;
- Bulk 契约存在文档/源码漂移,Batch 内顺序冲突语义需要版本化验证;
- 多对象 Persist 可能部分成功;
- Community / Saga Summary 会累积摘要漂移;
- 合规删除比 Flat Store 更复杂;
- Graph DB 运维与 Provider 差异不可忽略。
16.3 最准确的架构定义
Graphiti 不是:
Knowledge Graph + Embeddings而是:
Event-sourced Temporal World Model+ Entity Identity Resolution+ Provenance-bearing Fact Edges+ Validity Interval Maintenance+ Sequential Contradiction Processing+ Processing/Event-time Watermarks+ Multi-scope Hybrid Graph Retrieval它最值得学习的结论是:
当 Agent 面对会变化的世界,Memory 的核心不再是“召回相似文本”,而是维护谁、什么关系、在什么时间成立,以及系统为什么相信它。
参考资料与源码
[G1] Graphiti 固定版本
- Repository:getzep/graphiti @
526dcad
[G2] Zep Paper
- Zep: A Temporal Knowledge Graph Architecture for Agent Memory
- 核对内容:Temporal Knowledge Graph 动机、动态事实、检索与 Evaluation 背景。
[G3] Adding Episodes
- Adding Episodes
- Markdown 原文
- 核对内容:Episode 类型、Reference Time、顺序 Await,以及网页文档对 Bulk“不执行 Edge Invalidation”的当前声明。
[G4] Node Schema
nodes.py- 核对内容:Episodic / Entity / Community / Saga Node、Valid Time 与双 Watermark。
[G5] Edge Schema
edges.py- 核对内容:Entity Edge Fact、Episode Provenance、Valid / Invalid / Expired / Reference Time。
[G6] Saga Incremental Summary
[G7] Online Episode Write Path
[G8] Entity Extraction and Resolution
node_operations.py- 核对内容:Exact Collapse、Candidate Collection、Semantic Search、LLM Resolution、Attribute / Summary Extraction。
[G9] Fact Edge Resolution
edge_operations.py- 核对内容:Edge Extraction、Duplicate Filter、Timestamp Extraction、Contradiction 与 Invalidation。
[G10] Multi-scope Search
search/search.py- 核对内容:Edge / Node / Episode / Community 并行 Search、Group Filter 与 Tracing。
[G11] Search Recipes
search_config_recipes.py- 核对内容:BM25、Cosine、BFS、RRF、MMR、Cross Encoder 与其他 Reranker。
[G12] Agent Memory Security
[G13] Episode Removal
Graphiti.remove_episode- 核对内容:Fact Edge 的首来源判定、单 Episode Entity 删除与 Episode 删除边界。
[G14] Bulk Episode Write Path
Graphiti.add_episode_bulk- 核对内容:固定源码中的批量日期提取、Edge Resolution、
invalidated_edges持久化,以及与网页文档的契约漂移。