Guide11 min read
Temporal Knowledge GraphHow AI Agents Know What Is True Now
A temporal knowledge graph records relationships with the periods when they hold. A bitemporal model also records when the system learned them. This helps answer current and historical questions when sources and update rules are reliable. It does not decide which source is authoritative or who may read a fact.
The decision check further down tests whether your workflow needs one before you add a graph that ordinary retrieval may make unnecessary.
What is a temporal knowledge graph?
A knowledge graph stores entities as nodes and their relationships as edges. A temporal knowledge graph adds a validity window to every edge, so a fact becomes (subject, relation, object, valid from, valid to) instead of a timeless triple. When a fact stops holding, its window is closed rather than deleted, and the graph can answer three kinds of question from the same data:
- Current state: who owns this customer today?
- Point in time: who owned it on 1 May?
- Change: when did ownership move, and which source said so?
The term has two homes. In machine-learning research it usually means timestamped event data used to predict missing or future facts. In agent memory, which this guide covers, it means a store that tells an agent which fact is current, which one it replaced and where each came from.
The problem: similar is not current
Take a customer whose contact person changed in June. The March email names Jana Keller, the June ticket names Tom Berger. A vector search for “who is the contact at Acme” returns both passages, because both are similar to the question. The model then picks one, usually the one that reads more confident, and nothing in the retrieved text says which is still true.
Documents do not expire. Facts do. Every system that feeds an agent from chat, tickets, wiki and CRM runs into this within weeks, because those sources are full of decisions that were later revised.
How it works: facts with two clocks
A temporal knowledge graph stores three kinds of things:
- Entities are the nodes: a customer, a person, a project, a system.
- Facts are the edges between entities, written in plain language, such as “Tom Berger is Acme’s contact for the rollout”.
- Episodes are the raw inputs the facts were extracted from: a ticket comment, a meeting note, a CRM change. Every fact points back to its episodes.
Each fact carries two time axes. Valid time says when the fact held in the world. Transaction time says when the system recorded it, and when the system stopped treating it as current. A model with both axes is called bi-temporal. In Graphiti, every fact edge carries four timestamps for exactly this: valid_at and invalid_at for the world, created_at and expired_at for the system.
When the June ticket arrives, the graph does not overwrite anything. It adds the new fact and closes the old one:
| Fact | valid_at | invalid_at | Source |
|---|---|---|---|
| Jana Keller is Acme’s contact for the rollout | 2026-03-04 | 2026-06-03 | Email, 4 March |
| Tom Berger is Acme’s contact for the rollout | 2026-06-03 | open | Jira comment, 3 June |
A query for the current state returns the second row. A query as of 1 May returns the first. Both answers carry their source, so a person can open the email or the ticket and check.
Temporal knowledge graph, vector RAG and GraphRAG compared
| Vector RAG | GraphRAG-style knowledge graph | Temporal knowledge graph | |
|---|---|---|---|
| Unit of knowledge | Text chunk | Entities, relations, community summaries | Entities, facts with validity windows, episodes |
| New data | Embed and append | Batch indexing pipeline | Incremental, one episode at a time |
| Contradicting sources | Need metadata and conflict rules | Need explicit temporal modeling | Validity windows support conflict handling |
| “What was true in May?” | Possible with retained versions and date filters | Requires a history model | Supported when the relevant history is retained |
| Provenance | Chunk to document | Summaries to source text | Fact to episode to source system |
| Main cost | Embeddings | Extraction and summaries at index time | Extraction and reconciliation during ingestion |
Microsoft’s GraphRAG builds community summaries over a document collection and suits questions about the collection as a whole. A temporal knowledge graph suits questions about the current state of things that keep changing: customers, projects, systems, decisions.
The table compares common implementations. RAG is an architectural pattern and can include a graph. Azure AI Search, for example, documents metadata filters for vector retrieval.
Options for keeping agents off outdated facts
The question usually arrives as “which platform handles temporal consistency?” The honest answer depends on where your facts already live:
- Retrieval with versions and date filters. Keep superseded documents, store an effective date in the metadata and filter on it. Cheapest, and enough when one document per topic is authoritative.
- A temporal knowledge graph framework. Graphiti, described below, extracts facts from text and closes contradicted ones. Zep and Cognee offer agent-memory products built around the same idea.
- A bitemporal database. When the facts are already structured, a database that keeps valid time and system time, such as XTDB, gives you as-of queries without language-model extraction.
- The system of record itself. A CRM or ERP with field history often answers “who owned it on 5 June” already; the agent needs read access to that history, not a second copy.
Whichever you pick, the decision check below tells you whether it answers your questions before you build on it.
Does your workflow need a temporal knowledge graph?
Start with a decision that has already failed because a fact changed. If the problem is finding a static document, improve retrieval first. A temporal model becomes useful when the answer depends on relationships and dates, and the team needs to explain both the current state and what was known earlier.
Try this replay with two anonymized records from one workflow:
- Name the source authority. For the customer owner, is the CRM record authoritative, or a signed handover? Have the business owner decide before ingestion. A later message is not automatically a better source.
- Ask about now and then. Use an old owner and a dated replacement. Write down the expected answer to “Who owns this customer today?” and “Who owned it before the handover?”, each with a source link.
- Add a late correction. Record a handover effective on 3 June but received on 10 June. Distinguish “Who was the owner on 5 June?” from “What could this system have known on 5 June?” Retaining both dates is necessary for that distinction; test that retrieval actually uses them.
- Compare with the simpler baseline. Run the same questions against your existing search with retained versions and date filters. If it answers them reliably, keep that approach. If it fails, identify the missing history or relationship before choosing a graph.
The result should be a small set of expected answers, source records and an accountable owner. A graph alone does not grant read access or authorize an action. The production context-layer case study shows those controls around the graph. Bring the failed replay to the architecture call when it needs an implementation assessment.
How Graphiti builds it
Graphiti is an open-source framework for temporal knowledge graphs from Zep, under the Apache-2.0 license, at version 0.30.2 in September 2026 with about 30,800 GitHub stars. The parts that matter for an agent:
- Episodes in, facts out. You add an episode (text, a message or JSON) with a reference time. A language model extracts entities and facts, resolves them against what the graph already knows, and closes facts the new episode contradicts. Entity and edge types can be prescribed with Pydantic models or left to emerge from the data.
- Hybrid search without a model on the read path. Retrieval combines embeddings, BM25 keyword search and graph traversal, with optional reranking by graph distance, and returns facts rather than a generated summary.
- Backends. Neo4j 5.26 or newer, FalkorDB 1.1.2 or newer, and Amazon Neptune. The Kuzu driver is deprecated because the upstream project is no longer maintained.
- Models. OpenAI by default, with clients for Azure OpenAI, Anthropic, Google Gemini and Groq, and any OpenAI-compatible endpoint such as Ollama or vLLM. The README is explicit that Graphiti works best with models that support structured output, and that smaller models cause ingestion failures.
- Two defaults to know. Anonymous telemetry is on by default and switches off with
GRAPHITI_TELEMETRY_ENABLED=false. The official MCP server exposes write and delete tools, including one that clears a whole group.
A minimal round trip:
import asyncio
from datetime import datetime, timezone
from graphiti_core import Graphiti
from graphiti_core.nodes import EpisodeType
async def main():
graphiti = Graphiti("bolt://localhost:7687", "neo4j", "password")
await graphiti.build_indices_and_constraints()
await graphiti.add_episode(
name="jira-comment-4711",
episode_body="From today Tom Berger is Acme's contact for the rollout. "
"Jana Keller moved to procurement.",
source=EpisodeType.text,
source_description="Jira comment",
reference_time=datetime(2026, 6, 3, tzinfo=timezone.utc),
)
for edge in await graphiti.search("Who is Acme's contact for the rollout?"):
print(edge.fact, edge.valid_at, edge.invalid_at)
await graphiti.close()
asyncio.run(main())
How Graphiti compares with Mem0 is in Graphiti vs Mem0, and what running it takes is in Graphiti in production. Every add_episode parameter, the index build and the errors I hit on the way are in Graphiti add_episode.
What it costs to run
The read side is cheap. The write side is where the cost sits: every episode means model calls for extraction and for resolving entities and facts against the existing graph, and that context grows with the graph. Graphiti’s own issue tracker has threads on high ingestion cost and on resolution prompts that grow with the number of nodes. Plan for it:
- Batch what can wait. A nightly ingest of a wiki space costs the same as a live one and is easier to watch.
- Keep concurrency low at first. Graphiti defaults to low concurrency to stay under provider rate limits; raise it once you know your quota.
- Pick the extraction model for structured output, not for price alone. A cheap model that returns malformed JSON costs more in retries and dropped facts than a mid-range model that follows the schema.
- Set the embedding width explicitly. A local embedder such as
nomic-embed-textreturns 768 dimensions, while graphiti-core defaults to 1,024 unlessEMBEDDING_DIMsays otherwise, and a mismatch corrupts every vector it writes without an error.
When a temporal knowledge graph is the wrong tool
- Static reference text such as manuals and policies: plain retrieval is simpler and cheaper.
- Memory inside one conversation: the context window already holds it.
- Numbers and aggregates: a warehouse answers “revenue per quarter” better than any graph of facts.
Use one when facts change, when two sources can disagree, and when someone will ask “since when” or “who said so”.
Three rules from running them
I run temporal knowledge graphs in two settings: a company’s operational context layer on its own cloud tenant, and my own working graphs on FalkorDB, with a single-file LadybugDB graph on my laptop. Three rules came out of both:
- The agent proposes, a person approves. A record from a system of record, with its own source id, can land automatically. An interpretation, such as “this customer is at risk”, waits in a queue for a person. Writes go through a separate command, never through the tools the agent reads with.
- Nothing generates on the read path. The agent gets facts with their validity window and their source, and the model only phrases the answer. That keeps answers checkable and reads fast.
- Pin what you read with to what you wrote with. Keep reader and writer on the same graphiti-core version, and take query embeddings from the same embedding model, served the same way, that built the index. In my graphs, a reader one patch version behind the writer returned no results at all, without an error, and the same embedding model served by two different Ollama builds produced vectors with a cosine similarity of only 0.80 to each other, enough to lose matches.
Those rules are built into Graphiti Local, the open-source interface I maintain: six read-only MCP tools, a kg command line, and a write path that waits for a person. In client work they become the context layer for AI agents: the same kind of graph, fed from the systems a company already runs, on its own tenant. If the comparison in front of you is a platform rather than a library, the Palantir Foundry alternative guide sets the two side by side and gives you one workflow to run yourself.
Graphiti Local is an independent community project built on Graphiti. It is not affiliated with or endorsed by Zep. Versions and counts as of 11 September 2026.
Changelog
- 12 October 2026: added a current-versus-historical decision replay and a workflow scoping route. Existing implementation versions retain their stated September reference date.
- 23 October 2026: added a definition section, a research-versus-agent-memory note and an options overview; moved the decision check after the comparison.
Frequently asked questions
What is a temporal knowledge graph?
A knowledge graph in which every fact carries time: when it was true in the world and when the system recorded it. A contradicting fact closes the old one instead of deleting it, so you can ask what is true now and what was true on any earlier date.
How is a temporal knowledge graph different from a static knowledge graph?
A temporal graph explicitly models validity over time. A graph without that model can still retain history using snapshots, events or versioned properties. Incremental updates are an implementation choice, not exclusive to temporal graphs.
What does temporal knowledge graph mean in research papers?
In machine-learning research, a temporal knowledge graph is usually a set of timestamped facts (subject, relation, object, time) used to predict missing or future facts, as in event datasets such as ICEWS. In agent memory, the same structure serves a different job: telling an agent which fact is current and which source said so.
Is a knowledge graph better than RAG for AI agents?
A temporal graph is useful when relationships, validity periods and the history of decisions matter. RAG can also use timestamps, metadata filters, source attribution and reranking. Similarity alone does not establish which conflicting claim is current; neither approach guarantees truth without reliable sources and evaluated update rules. Test both on your actual questions.
Is Graphiti open source?
Yes. Graphiti is Zep's framework for temporal knowledge graphs, released under the Apache-2.0 license and at version 0.30 in September 2026. It runs on Neo4j, FalkorDB or Amazon Neptune. Zep Cloud is the vendor's managed service built on it.
Does a temporal knowledge graph need a language model?
No. Structured facts can be imported with deterministic code. Graphiti uses language models for its unstructured episode extraction and reconciliation pipeline. Retrieval can also call embedding or reranking models, depending on configuration; a generated answer is a separate step.
Can a temporal knowledge graph run inside the EU or fully on premises?
Compute, storage and the graph run in your cloud tenant. Model and embedding endpoints are selected and verified separately. For an EU requirement, the deployment review records the exact model, version, deployment type, processing location and connected services. Self-hosted inference is an option when data must remain inside your network.
Next step
Book a 30-minute architecture callYour agents answer from whatever the retriever finds, and too often that is last quarter's truth. I build the context layer they answer and act from: a temporal knowledge graph that keeps every fact with its source and the time it held, reads with each person's own permissions, and writes nothing without a person's approval. On your own tenant, billed by the hour, step by step.