last update
Jun 24, 2026
license
MITv1.0.0
format
SKILL.md
- Install
// Downloads SKILL.md into ~/.claude/skills/graphiti-temporal-memory/
$ curl -fsSL --create-dirs -o ~/.claude/skills/graphiti-temporal-memory/SKILL.md https://claudeskil.com/skills/graphiti-temporal-memory/SKILL.md - Invoke
// Inside Claude Code, type the skill name as a slash command
> /graphiti-temporal-memory fine-tune on this CSV - Or copy this from the README
// extracted python block
$ from graphiti_core import Graphiti g = Graphiti("bolt://localhost:7687", "neo4j", "password") await g.build_indices_and_constraints() await g.add_episode(
- name:
- Graphiti Temporal Memory
- slug:
- graphiti-temporal-memory
- version:
- v1.0.0
- license:
- MIT
- author:
- @chiragthummar16
- categories:
- tags:
- #graphiti#zep#knowledge-graph#agent-memory#temporal
- description:
Build bi-temporal knowledge-graph agent memory with Graphiti and Zep — facts with validity windows, not flat vector recall.
README.md
Graphiti Temporal Memory
Most agent memory collapses to a vector store: you embed past turns, retrieve the nearest neighbors, and hope the model sorts out what's still true. Graphiti Temporal Memory takes a different approach, building a bi-temporal knowledge graph where facts are edges with explicit validity windows. When new information contradicts old, the prior edge is invalidated rather than overwritten — so your agent can answer "what did the user prefer last March" as easily as "what do they prefer now." It's aimed at developers building long-running assistants, support agents, or anything where state changes over time and provenance matters.
When to use it
- A user's facts mutate over a session or across sessions (job title, address, current project, preferences) and stale recall causes wrong answers.
- You need to reconstruct what was known at a point in time — audits, debugging agent decisions, "as of" queries.
- Flat RAG keeps surfacing outdated or conflicting chunks with no way to reconcile them.
- You want graph-aware retrieval (entities and their relationships), not just semantic similarity.
How it works
The skill wraps the Graphiti library and the Zep service. Core flow:
- Ingestion —
graphiti.add_episode(...)takes raw text or structured messages. An LLM extracts entities (nodes) and relationships (edges), deduplicates against existing nodes, and writes them to a graph backend (Neo4j or FalkorDB). - Bi-temporal tracking — every edge carries two timelines: event time (
valid_at/invalid_at, when the fact was true in the world) and system time (created_at, when the graph learned it). Contradicting an existing edge sets itsinvalid_atinstead of deleting it. - Hybrid retrieval —
graphiti.search(...)combines semantic (embedding) search, BM25 full-text, and graph-distance traversal, fused with reciprocal rank fusion (RRF) and optional reranking.
Usage
curl -fsSL --create-dirs -o ~/.claude/skills/graphiti-temporal-memory/SKILL.md https://claudeskil.com/skills/graphiti-temporal-memory/SKILL.md
from graphiti_core import Graphiti
g = Graphiti("bolt://localhost:7687", "neo4j", "password")
await g.build_indices_and_constraints()
await g.add_episode(
name="onboarding",
episode_body="Priya moved from the Data team to the Platform team.",
reference_time=datetime.now(timezone.utc),
)
results = await g.search("which team is Priya on?")
for edge in results:
print(edge.fact, edge.valid_at, edge.invalid_at)
Tips & gotchas
reference_timeis what populatesvalid_at— pass the real event timestamp when backfilling history, notnow(), or your timelines will be wrong.- Call
build_indices_and_constraints()once per database; skipping it makes search fall back to slow scans. - Ingestion is LLM-bound and not cheap. Batch episodes and choose a smaller extraction model where you can.
- Deduplication is name- and embedding-based — inconsistent entity naming spawns duplicate nodes.
FAQ
Graphiti library or Zep service? Graphiti is the open-source engine you self-host against Neo4j/FalkorDB. Zep is the managed product built on it. This skill covers both.
Does old data disappear on contradiction? No. The superseded edge stays with invalid_at set, so point-in-time queries still work.
Can I run without an LLM? No — entity/edge extraction requires one. The backend graph DB is separate.
$ cat reviews/