Back to the tools

Memory and knowledge base

Graphiti

Graphiti is an open source framework for temporal knowledge graphs: it derives entities and facts from ingested episodes and stores a validity window on every fact.

3 min read

Graphiti is Zep’s open source framework for building and querying temporal knowledge graphs, which the project calls context graphs. It does not index document chunks. It keeps entities, the facts that hold between them, and the validity window of each fact: when it became true, and whether a later episode superseded it. A superseded fact is invalidated rather than deleted, so an earlier state of the world can still be queried.

The graph has three layers. Entities are nodes whose summaries evolve as new data arrives. Facts are edges: two entities and the relationship between them, with a validity window. Episodes are the raw inputs. Every derived fact traces back to one of them, and that provenance separates it from plain vector retrieval.

How it differs from classic RAG

  • Temporal facts. Validity windows on every edge; contradicting input invalidates the old fact instead of overwriting it.
  • Provenance. Nodes and edges trace back to the episode that produced them.
  • Incremental construction. New data integrates immediately, without recomputing the whole graph.
  • Ontology. Entity and edge types can be prescribed with Pydantic models, or learned from the data.
  • Hybrid retrieval. Semantic similarity, BM25 keyword search and graph traversal in one ranked result set, with no LLM in the reranking loop.

This pays off when data changes often: continuous updates instead of batch processing.

How memory is ingested

The unit of input is the episode, which is itself a node; entities extracted from it are linked by MENTIONS edges. The ingestion API supports three episode types:

  • text: unstructured text,
  • message: a conversation in speaker: message form,
  • json: structured data, processed on a separate path.

An add_episode call takes a name, the body, the source type and a reference time that pins the event in time. For larger imports add_episode_bulk loads many episodes in one pass, but it performs no edge invalidation, so the docs reserve it for empty graphs.

Storage and runtime

Graphiti does not store the graph itself: it runs on a graph database you provide, and calls an LLM and an embedder for extraction.

  • Graph backend. Neo4j 5.26, FalkorDB 1.1.2 or Amazon Neptune, where a Neptune Analytics graph uses an OpenSearch Serverless collection as the full text backend. Kuzu support is deprecated.
  • LLM and embeddings. OpenAI by default; Azure OpenAI, Anthropic, Gemini, Groq and local servers work through OpenAI-compatible endpoints.
  • Requirements. Python 3.10 or higher, a running graph database and an API key. We run the database in Docker.
  • Throughput. Ingestion concurrency is governed by SEMAPHORE_LIMIT; the default is 10 to stay clear of provider rate limits, so ingestion looks slow at first.

The MCP server exposes the same functionality as tools: add an episode, search facts and nodes, delete episodes, clear the graph. A group_id separates several graphs inside one deployment. The server is documented as experimental, so measure it on your own load.

What to watch

  • Extraction quality depends on the model. Providers with structured output support work best; small models tend to fail ingestion.
  • An episode has to fit the LLM context window, so keep JSON bodies compact.
  • The MCP server is experimental and its API can change between releases.
  • You operate the graph database and the scaling; the managed counterpart is Zep.
  • Anonymous telemetry is on by default; GRAPHITI_TELEMETRY_ENABLED=false disables it.

Further reading

We use Graphiti as one layer of cross-session memory: decisions and fixed bugs go in as episodes, queried from Hermes Agent through our MCPHub server.

Tags
  • knowledge graph
  • memory
  • MCP
  • retrieval