graphiti-core 0.8.0__tar.gz → 0.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphiti-core might be problematic. Click here for more details.

Files changed (62) hide show
  1. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/PKG-INFO +93 -42
  2. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/README.md +92 -41
  3. graphiti_core-0.8.2/graphiti_core/cross_encoder/__init__.py +20 -0
  4. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/openai_reranker_client.py +16 -8
  5. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/openai.py +14 -3
  6. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/models/nodes/node_db_queries.py +2 -2
  7. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/node_operations.py +3 -0
  8. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/pyproject.toml +1 -1
  9. graphiti_core-0.8.0/graphiti_core/utils/__init__.py +0 -0
  10. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/LICENSE +0 -0
  11. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/__init__.py +0 -0
  12. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
  13. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/client.py +0 -0
  14. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/edges.py +0 -0
  15. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/__init__.py +0 -0
  16. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/client.py +0 -0
  17. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/voyage.py +0 -0
  18. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/errors.py +0 -0
  19. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/graphiti.py +0 -0
  20. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/helpers.py +0 -0
  21. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/__init__.py +0 -0
  22. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/anthropic_client.py +0 -0
  23. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/client.py +0 -0
  24. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/config.py +0 -0
  25. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/errors.py +0 -0
  26. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/groq_client.py +0 -0
  27. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/openai_client.py +0 -0
  28. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/openai_generic_client.py +0 -0
  29. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/utils.py +0 -0
  30. {graphiti_core-0.8.0/graphiti_core/cross_encoder → graphiti_core-0.8.2/graphiti_core/models}/__init__.py +0 -0
  31. {graphiti_core-0.8.0/graphiti_core/models → graphiti_core-0.8.2/graphiti_core/models/edges}/__init__.py +0 -0
  32. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/models/edges/edge_db_queries.py +0 -0
  33. {graphiti_core-0.8.0/graphiti_core/models/edges → graphiti_core-0.8.2/graphiti_core/models/nodes}/__init__.py +0 -0
  34. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/nodes.py +0 -0
  35. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/__init__.py +0 -0
  36. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/dedupe_edges.py +0 -0
  37. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/dedupe_nodes.py +0 -0
  38. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/eval.py +0 -0
  39. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_edge_dates.py +0 -0
  40. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_edges.py +0 -0
  41. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_nodes.py +0 -0
  42. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/invalidate_edges.py +0 -0
  43. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/lib.py +0 -0
  44. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/models.py +0 -0
  45. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/prompt_helpers.py +0 -0
  46. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/summarize_nodes.py +0 -0
  47. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/py.typed +0 -0
  48. {graphiti_core-0.8.0/graphiti_core/models/nodes → graphiti_core-0.8.2/graphiti_core/search}/__init__.py +0 -0
  49. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search.py +0 -0
  50. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_config.py +0 -0
  51. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_config_recipes.py +0 -0
  52. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_filters.py +0 -0
  53. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_utils.py +0 -0
  54. {graphiti_core-0.8.0/graphiti_core/search → graphiti_core-0.8.2/graphiti_core/utils}/__init__.py +0 -0
  55. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/bulk_utils.py +0 -0
  56. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/datetime_utils.py +0 -0
  57. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/__init__.py +0 -0
  58. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/community_operations.py +0 -0
  59. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
  60. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/graph_data_operations.py +0 -0
  61. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
  62. {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: graphiti-core
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Summary: A temporal graph building library
5
5
  License: Apache-2.0
6
6
  Author: Paul Paliychuk
@@ -29,7 +29,7 @@ Description-Content-Type: text/markdown
29
29
  <h1 align="center">
30
30
  Graphiti
31
31
  </h1>
32
- <h2 align="center"> Temporal Knowledge Graphs for Agentic Applications</h2>
32
+ <h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
33
33
  <br />
34
34
 
35
35
  [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
@@ -38,12 +38,16 @@ Graphiti
38
38
  [![MyPy Check](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
39
39
  [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/getzep/Graphiti)
40
40
 
41
- :star: *Help us reach more developers and grow the Graphiti community. Star this repo!*
41
+ :star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
42
42
  <br />
43
43
 
44
- Graphiti builds dynamic, temporally aware Knowledge Graphs that represent complex, evolving relationships between
45
- entities over time. Graphiti ingests both unstructured and structured data, and the resulting graph may be queried using
46
- a fusion of time, full-text, semantic, and graph algorithm approaches.
44
+ Graphiti is a framework for building and querying temporally-aware knowledge graphs, specifically tailored for AI agents operating in dynamic environments. Unlike traditional retrieval-augmented generation (RAG) methods, Graphiti continuously integrates user interactions, structured and unstructured enterprise data, and external information into a coherent, queryable graph. The framework supports incremental data updates, efficient retrieval, and precise historical queries without requiring complete graph recomputation, making it suitable for developing interactive, context-aware AI applications.
45
+
46
+ Use Graphiti to:
47
+
48
+ - Integrate and maintain dynamic user interactions and business data.
49
+ - Facilitate state-based reasoning and task automation for agents.
50
+ - Query complex, evolving data with semantic, keyword, and graph-based search methods.
47
51
 
48
52
  <br />
49
53
 
@@ -53,31 +57,21 @@ a fusion of time, full-text, semantic, and graph algorithm approaches.
53
57
 
54
58
  <br />
55
59
 
56
- Graphiti helps you create and query Knowledge Graphs that evolve over time. A knowledge graph is a network of
57
- interconnected facts, such as _“Kendra loves Adidas shoes.”_ Each fact is a “triplet” represented by two entities, or
60
+ A knowledge graph is a network of interconnected facts, such as _“Kendra loves Adidas shoes.”_ Each fact is a “triplet” represented by two entities, or
58
61
  nodes (_”Kendra”_, _“Adidas shoes”_), and their relationship, or edge (_”loves”_). Knowledge Graphs have been explored
59
62
  extensively for information retrieval. What makes Graphiti unique is its ability to autonomously build a knowledge graph
60
63
  while handling changing relationships and maintaining historical context.
61
64
 
62
- With Graphiti, you can build LLM applications such as:
63
-
64
- - Assistants that learn from user interactions, fusing personal knowledge with dynamic data from business systems like
65
- CRMs and billing platforms.
66
- - Agents that autonomously execute complex tasks, reasoning with state changes from multiple dynamic sources.
67
-
68
- Graphiti supports a wide range of applications in sales, customer service, health, finance, and more, enabling long-term
69
- recall and state-based reasoning for both assistants and agents.
70
-
71
65
  ## Graphiti and Zep Memory
72
66
 
73
- Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for LLM-powered Assistants and Agents.
67
+ Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for AI Agents.
74
68
 
75
69
  Using Graphiti, we've demonstrated Zep is
76
70
  the [State of the Art in Agent Memory](https://blog.getzep.com/state-of-the-art-agent-memory/).
77
71
 
78
72
  Read our paper: [Zep: A Temporal Knowledge Graph Architecture for Agent Memory](https://arxiv.org/abs/2501.13956).
79
73
 
80
- We're excited to open-source Graphiti, believing its potential reaches far beyond memory applications.
74
+ We're excited to open-source Graphiti, believing its potential reaches far beyond AI memory applications.
81
75
 
82
76
  <p align="center">
83
77
  <a href="https://arxiv.org/abs/2501.13956"><img src="images/arxiv-screenshot.png" alt="Zep: A Temporal Knowledge Graph Architecture for Agent Memory" width="700px"></a>
@@ -85,34 +79,41 @@ We're excited to open-source Graphiti, believing its potential reaches far beyon
85
79
 
86
80
  ## Why Graphiti?
87
81
 
88
- We were intrigued by Microsoft’s GraphRAG, which expanded on RAG text chunking by using a graph to better model a
89
- document corpus and making this representation available via semantic and graph search techniques. However, GraphRAG did
90
- not address our core problem: It's primarily designed for static documents and doesn't inherently handle temporal
91
- aspects of data.
92
-
93
- Graphiti is designed from the ground up to handle constantly changing information, hybrid semantic and graph search, and
94
- scale:
82
+ Traditional RAG approaches often rely on batch processing and static data summarization, making them inefficient for frequently changing data. Graphiti addresses these challenges by providing:
95
83
 
96
- - **Temporal Awareness:** Tracks changes in facts and relationships over time, enabling point-in-time queries. Graph
97
- edges include temporal metadata to record relationship lifecycles.
98
- - **Episodic Processing:** Ingests data as discrete episodes, maintaining data provenance and allowing incremental
99
- entity and relationship extraction.
100
- - **Hybrid Search:** Combines semantic and BM25 full-text search, with the ability to rerank results by distance from a
101
- central node e.g. “Kendra”.
102
- - **Scalable:** Designed for processing large datasets, with parallelization of LLM calls for bulk processing while
103
- preserving the chronology of events.
104
- - **Supports Varied Sources:** Can ingest both unstructured text and structured JSON data.
84
+ - **Real-Time Incremental Updates:** Immediate integration of new data episodes without batch recomputation.
85
+ - **Bi-Temporal Data Model:** Explicit tracking of event occurrence and ingestion times, allowing accurate point-in-time queries.
86
+ - **Efficient Hybrid Retrieval:** Combines semantic embeddings, keyword (BM25), and graph traversal to achieve low-latency queries without reliance on LLM summarization.
87
+ - **Custom Entity Definitions:** Flexible ontology creation and support for developer-defined entities through straightforward Pydantic models.
88
+ - **Scalability:** Efficiently manages large datasets with parallel processing, suitable for enterprise environments.
105
89
 
106
90
  <p align="center">
107
91
  <img src="/images/graphiti-intro-slides-stock-2.gif" alt="Graphiti structured + unstructured demo" width="700px">
108
92
  </p>
109
93
 
94
+ ## Graphiti vs. GraphRAG
95
+
96
+ | Aspect | GraphRAG | Graphiti |
97
+ | -------------------------- | ------------------------------------- | ------------------------------------------------ |
98
+ | **Primary Use** | Static document summarization | Dynamic data management |
99
+ | **Data Handling** | Batch-oriented processing | Continuous, incremental updates |
100
+ | **Knowledge Structure** | Entity clusters & community summaries | Episodic data, semantic entities, communities |
101
+ | **Retrieval Method** | Sequential LLM summarization | Hybrid semantic, keyword, and graph-based search |
102
+ | **Adaptability** | Low | High |
103
+ | **Temporal Handling** | Basic timestamp tracking | Explicit bi-temporal tracking |
104
+ | **Contradiction Handling** | LLM-driven summarization judgments | Temporal edge invalidation |
105
+ | **Query Latency** | Seconds to tens of seconds | Typically sub-second latency |
106
+ | **Custom Entity Types** | No | Yes, customizable |
107
+ | **Scalability** | Moderate | High, optimized for large datasets |
108
+
109
+ Graphiti is specifically designed to address the challenges of dynamic and frequently updated datasets, making it particularly suitable for applications requiring real-time interaction and precise historical queries.
110
+
110
111
  ## Installation
111
112
 
112
113
  Requirements:
113
114
 
114
115
  - Python 3.10 or higher
115
- - Neo4j 5.26 or higher
116
+ - Neo4j 5.26 or higher (serves as the embeddings storage backend)
116
117
  - OpenAI API key (for LLM inference and embedding)
117
118
 
118
119
  Optional:
@@ -145,7 +146,7 @@ from graphiti_core import Graphiti
145
146
  from graphiti_core.nodes import EpisodeType
146
147
  from datetime import datetime, timezone
147
148
 
148
- # Initialize Graphiti
149
+ # Initialize Graphiti as Your Memory Layer
149
150
  graphiti = Graphiti("bolt://localhost:7687", "neo4j", "password")
150
151
 
151
152
  # Initialize the graph database with Graphiti's indices. This only needs to be done once.
@@ -166,7 +167,7 @@ for i, episode in enumerate(episodes):
166
167
  reference_time=datetime.now(timezone.utc)
167
168
  )
168
169
 
169
- # Search the graph
170
+ # Search the graph for semantic memory retrieval
170
171
  # Execute a hybrid search combining semantic similarity and BM25 retrieval
171
172
  # Results are combined and reranked using Reciprocal Rank Fusion
172
173
  results = await graphiti.search('Who was the California Attorney General?')
@@ -198,11 +199,12 @@ results = await graphiti.search('Who was the California Attorney General?')
198
199
  # Results are weighted by their proximity, with distant edges receiving lower scores.
199
200
  await graphiti.search('Who was the California Attorney General?', center_node_uuid)
200
201
 
201
- # Close the connection
202
+ # Close the connection when chat state management is complete
202
203
  graphiti.close()
203
204
  ```
204
205
 
205
206
  ## Graph Service
207
+
206
208
  The `server` directory contains an API service for interacting with the Graphiti API. It is built using FastAPI.
207
209
 
208
210
  Please see the [server README](./server/README.md) for more information.
@@ -218,6 +220,54 @@ to enable Neo4j's parallel runtime feature for several of our search queries.
218
220
  Note that this feature is not supported for Neo4j Community edition or for smaller AuraDB instances,
219
221
  as such this feature is off by default.
220
222
 
223
+ ## Using Graphiti with Azure OpenAI
224
+
225
+ Graphiti supports Azure OpenAI for both LLM inference and embeddings. To use Azure OpenAI, you'll need to configure both the LLM client and embedder with your Azure OpenAI credentials.
226
+
227
+ ```python
228
+ from openai import AsyncAzureOpenAI
229
+ from graphiti_core import Graphiti
230
+ from graphiti_core.llm_client import OpenAIClient
231
+ from graphiti_core.embedder.openai import OpenAIEmbedder, OpenAIEmbedderConfig
232
+ from graphiti_core.cross_encoder.openai_reranker_client import OpenAIRerankerClient
233
+
234
+ # Azure OpenAI configuration
235
+ api_key = "<your-api-key>"
236
+ api_version = "<your-api-version>"
237
+ azure_endpoint = "<your-azure-endpoint>"
238
+
239
+ # Create Azure OpenAI client for LLM
240
+ azure_openai_client = AsyncAzureOpenAI(
241
+ api_key=api_key,
242
+ api_version=api_version,
243
+ azure_endpoint=azure_endpoint
244
+ )
245
+
246
+ # Initialize Graphiti with Azure OpenAI clients
247
+ graphiti = Graphiti(
248
+ "bolt://localhost:7687",
249
+ "neo4j",
250
+ "password",
251
+ llm_client=OpenAIClient(
252
+ client=azure_openai_client
253
+ ),
254
+ embedder=OpenAIEmbedder(
255
+ config=OpenAIEmbedderConfig(
256
+ embedding_model="text-embedding-3-small" # Use your Azure deployed embedding model name
257
+ ),
258
+ client=azure_openai_client
259
+ ),
260
+ # Optional: Configure the OpenAI cross encoder with Azure OpenAI
261
+ cross_encoder=OpenAIRerankerClient(
262
+ client=azure_openai_client
263
+ )
264
+ )
265
+
266
+ # Now you can use Graphiti with Azure OpenAI
267
+ ```
268
+
269
+ Make sure to replace the placeholder values with your actual Azure OpenAI credentials and specify the correct embedding model name that's deployed in your Azure OpenAI service.
270
+
221
271
  ## Documentation
222
272
 
223
273
  - [Guides and API documentation](https://help.getzep.com/graphiti).
@@ -228,10 +278,11 @@ as such this feature is off by default.
228
278
 
229
279
  Graphiti is under active development. We aim to maintain API stability while working on:
230
280
 
231
- - [ ] Supporting custom graph schemas:
232
- - Allow developers to provide their own defined node and edge classes when ingesting episodes
233
- - Enable more flexible knowledge representation tailored to specific use cases
281
+ - [x] Supporting custom graph schemas:
282
+ - Allow developers to provide their own defined node and edge classes when ingesting episodes
283
+ - Enable more flexible knowledge representation tailored to specific use cases
234
284
  - [x] Enhancing retrieval capabilities with more robust and configurable options
285
+ - [ ] Graphiti MCP Server
235
286
  - [ ] Expanding test coverage to ensure reliability and catch edge cases
236
287
 
237
288
  ## Contributing
@@ -7,7 +7,7 @@
7
7
  <h1 align="center">
8
8
  Graphiti
9
9
  </h1>
10
- <h2 align="center"> Temporal Knowledge Graphs for Agentic Applications</h2>
10
+ <h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
11
11
  <br />
12
12
 
13
13
  [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
@@ -16,12 +16,16 @@ Graphiti
16
16
  [![MyPy Check](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
17
17
  [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/getzep/Graphiti)
18
18
 
19
- :star: *Help us reach more developers and grow the Graphiti community. Star this repo!*
19
+ :star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
20
20
  <br />
21
21
 
22
- Graphiti builds dynamic, temporally aware Knowledge Graphs that represent complex, evolving relationships between
23
- entities over time. Graphiti ingests both unstructured and structured data, and the resulting graph may be queried using
24
- a fusion of time, full-text, semantic, and graph algorithm approaches.
22
+ Graphiti is a framework for building and querying temporally-aware knowledge graphs, specifically tailored for AI agents operating in dynamic environments. Unlike traditional retrieval-augmented generation (RAG) methods, Graphiti continuously integrates user interactions, structured and unstructured enterprise data, and external information into a coherent, queryable graph. The framework supports incremental data updates, efficient retrieval, and precise historical queries without requiring complete graph recomputation, making it suitable for developing interactive, context-aware AI applications.
23
+
24
+ Use Graphiti to:
25
+
26
+ - Integrate and maintain dynamic user interactions and business data.
27
+ - Facilitate state-based reasoning and task automation for agents.
28
+ - Query complex, evolving data with semantic, keyword, and graph-based search methods.
25
29
 
26
30
  <br />
27
31
 
@@ -31,31 +35,21 @@ a fusion of time, full-text, semantic, and graph algorithm approaches.
31
35
 
32
36
  <br />
33
37
 
34
- Graphiti helps you create and query Knowledge Graphs that evolve over time. A knowledge graph is a network of
35
- interconnected facts, such as _“Kendra loves Adidas shoes.”_ Each fact is a “triplet” represented by two entities, or
38
+ A knowledge graph is a network of interconnected facts, such as _“Kendra loves Adidas shoes.”_ Each fact is a “triplet” represented by two entities, or
36
39
  nodes (_”Kendra”_, _“Adidas shoes”_), and their relationship, or edge (_”loves”_). Knowledge Graphs have been explored
37
40
  extensively for information retrieval. What makes Graphiti unique is its ability to autonomously build a knowledge graph
38
41
  while handling changing relationships and maintaining historical context.
39
42
 
40
- With Graphiti, you can build LLM applications such as:
41
-
42
- - Assistants that learn from user interactions, fusing personal knowledge with dynamic data from business systems like
43
- CRMs and billing platforms.
44
- - Agents that autonomously execute complex tasks, reasoning with state changes from multiple dynamic sources.
45
-
46
- Graphiti supports a wide range of applications in sales, customer service, health, finance, and more, enabling long-term
47
- recall and state-based reasoning for both assistants and agents.
48
-
49
43
  ## Graphiti and Zep Memory
50
44
 
51
- Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for LLM-powered Assistants and Agents.
45
+ Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for AI Agents.
52
46
 
53
47
  Using Graphiti, we've demonstrated Zep is
54
48
  the [State of the Art in Agent Memory](https://blog.getzep.com/state-of-the-art-agent-memory/).
55
49
 
56
50
  Read our paper: [Zep: A Temporal Knowledge Graph Architecture for Agent Memory](https://arxiv.org/abs/2501.13956).
57
51
 
58
- We're excited to open-source Graphiti, believing its potential reaches far beyond memory applications.
52
+ We're excited to open-source Graphiti, believing its potential reaches far beyond AI memory applications.
59
53
 
60
54
  <p align="center">
61
55
  <a href="https://arxiv.org/abs/2501.13956"><img src="images/arxiv-screenshot.png" alt="Zep: A Temporal Knowledge Graph Architecture for Agent Memory" width="700px"></a>
@@ -63,34 +57,41 @@ We're excited to open-source Graphiti, believing its potential reaches far beyon
63
57
 
64
58
  ## Why Graphiti?
65
59
 
66
- We were intrigued by Microsoft’s GraphRAG, which expanded on RAG text chunking by using a graph to better model a
67
- document corpus and making this representation available via semantic and graph search techniques. However, GraphRAG did
68
- not address our core problem: It's primarily designed for static documents and doesn't inherently handle temporal
69
- aspects of data.
70
-
71
- Graphiti is designed from the ground up to handle constantly changing information, hybrid semantic and graph search, and
72
- scale:
60
+ Traditional RAG approaches often rely on batch processing and static data summarization, making them inefficient for frequently changing data. Graphiti addresses these challenges by providing:
73
61
 
74
- - **Temporal Awareness:** Tracks changes in facts and relationships over time, enabling point-in-time queries. Graph
75
- edges include temporal metadata to record relationship lifecycles.
76
- - **Episodic Processing:** Ingests data as discrete episodes, maintaining data provenance and allowing incremental
77
- entity and relationship extraction.
78
- - **Hybrid Search:** Combines semantic and BM25 full-text search, with the ability to rerank results by distance from a
79
- central node e.g. “Kendra”.
80
- - **Scalable:** Designed for processing large datasets, with parallelization of LLM calls for bulk processing while
81
- preserving the chronology of events.
82
- - **Supports Varied Sources:** Can ingest both unstructured text and structured JSON data.
62
+ - **Real-Time Incremental Updates:** Immediate integration of new data episodes without batch recomputation.
63
+ - **Bi-Temporal Data Model:** Explicit tracking of event occurrence and ingestion times, allowing accurate point-in-time queries.
64
+ - **Efficient Hybrid Retrieval:** Combines semantic embeddings, keyword (BM25), and graph traversal to achieve low-latency queries without reliance on LLM summarization.
65
+ - **Custom Entity Definitions:** Flexible ontology creation and support for developer-defined entities through straightforward Pydantic models.
66
+ - **Scalability:** Efficiently manages large datasets with parallel processing, suitable for enterprise environments.
83
67
 
84
68
  <p align="center">
85
69
  <img src="/images/graphiti-intro-slides-stock-2.gif" alt="Graphiti structured + unstructured demo" width="700px">
86
70
  </p>
87
71
 
72
+ ## Graphiti vs. GraphRAG
73
+
74
+ | Aspect | GraphRAG | Graphiti |
75
+ | -------------------------- | ------------------------------------- | ------------------------------------------------ |
76
+ | **Primary Use** | Static document summarization | Dynamic data management |
77
+ | **Data Handling** | Batch-oriented processing | Continuous, incremental updates |
78
+ | **Knowledge Structure** | Entity clusters & community summaries | Episodic data, semantic entities, communities |
79
+ | **Retrieval Method** | Sequential LLM summarization | Hybrid semantic, keyword, and graph-based search |
80
+ | **Adaptability** | Low | High |
81
+ | **Temporal Handling** | Basic timestamp tracking | Explicit bi-temporal tracking |
82
+ | **Contradiction Handling** | LLM-driven summarization judgments | Temporal edge invalidation |
83
+ | **Query Latency** | Seconds to tens of seconds | Typically sub-second latency |
84
+ | **Custom Entity Types** | No | Yes, customizable |
85
+ | **Scalability** | Moderate | High, optimized for large datasets |
86
+
87
+ Graphiti is specifically designed to address the challenges of dynamic and frequently updated datasets, making it particularly suitable for applications requiring real-time interaction and precise historical queries.
88
+
88
89
  ## Installation
89
90
 
90
91
  Requirements:
91
92
 
92
93
  - Python 3.10 or higher
93
- - Neo4j 5.26 or higher
94
+ - Neo4j 5.26 or higher (serves as the embeddings storage backend)
94
95
  - OpenAI API key (for LLM inference and embedding)
95
96
 
96
97
  Optional:
@@ -123,7 +124,7 @@ from graphiti_core import Graphiti
123
124
  from graphiti_core.nodes import EpisodeType
124
125
  from datetime import datetime, timezone
125
126
 
126
- # Initialize Graphiti
127
+ # Initialize Graphiti as Your Memory Layer
127
128
  graphiti = Graphiti("bolt://localhost:7687", "neo4j", "password")
128
129
 
129
130
  # Initialize the graph database with Graphiti's indices. This only needs to be done once.
@@ -144,7 +145,7 @@ for i, episode in enumerate(episodes):
144
145
  reference_time=datetime.now(timezone.utc)
145
146
  )
146
147
 
147
- # Search the graph
148
+ # Search the graph for semantic memory retrieval
148
149
  # Execute a hybrid search combining semantic similarity and BM25 retrieval
149
150
  # Results are combined and reranked using Reciprocal Rank Fusion
150
151
  results = await graphiti.search('Who was the California Attorney General?')
@@ -176,11 +177,12 @@ results = await graphiti.search('Who was the California Attorney General?')
176
177
  # Results are weighted by their proximity, with distant edges receiving lower scores.
177
178
  await graphiti.search('Who was the California Attorney General?', center_node_uuid)
178
179
 
179
- # Close the connection
180
+ # Close the connection when chat state management is complete
180
181
  graphiti.close()
181
182
  ```
182
183
 
183
184
  ## Graph Service
185
+
184
186
  The `server` directory contains an API service for interacting with the Graphiti API. It is built using FastAPI.
185
187
 
186
188
  Please see the [server README](./server/README.md) for more information.
@@ -196,6 +198,54 @@ to enable Neo4j's parallel runtime feature for several of our search queries.
196
198
  Note that this feature is not supported for Neo4j Community edition or for smaller AuraDB instances,
197
199
  as such this feature is off by default.
198
200
 
201
+ ## Using Graphiti with Azure OpenAI
202
+
203
+ Graphiti supports Azure OpenAI for both LLM inference and embeddings. To use Azure OpenAI, you'll need to configure both the LLM client and embedder with your Azure OpenAI credentials.
204
+
205
+ ```python
206
+ from openai import AsyncAzureOpenAI
207
+ from graphiti_core import Graphiti
208
+ from graphiti_core.llm_client import OpenAIClient
209
+ from graphiti_core.embedder.openai import OpenAIEmbedder, OpenAIEmbedderConfig
210
+ from graphiti_core.cross_encoder.openai_reranker_client import OpenAIRerankerClient
211
+
212
+ # Azure OpenAI configuration
213
+ api_key = "<your-api-key>"
214
+ api_version = "<your-api-version>"
215
+ azure_endpoint = "<your-azure-endpoint>"
216
+
217
+ # Create Azure OpenAI client for LLM
218
+ azure_openai_client = AsyncAzureOpenAI(
219
+ api_key=api_key,
220
+ api_version=api_version,
221
+ azure_endpoint=azure_endpoint
222
+ )
223
+
224
+ # Initialize Graphiti with Azure OpenAI clients
225
+ graphiti = Graphiti(
226
+ "bolt://localhost:7687",
227
+ "neo4j",
228
+ "password",
229
+ llm_client=OpenAIClient(
230
+ client=azure_openai_client
231
+ ),
232
+ embedder=OpenAIEmbedder(
233
+ config=OpenAIEmbedderConfig(
234
+ embedding_model="text-embedding-3-small" # Use your Azure deployed embedding model name
235
+ ),
236
+ client=azure_openai_client
237
+ ),
238
+ # Optional: Configure the OpenAI cross encoder with Azure OpenAI
239
+ cross_encoder=OpenAIRerankerClient(
240
+ client=azure_openai_client
241
+ )
242
+ )
243
+
244
+ # Now you can use Graphiti with Azure OpenAI
245
+ ```
246
+
247
+ Make sure to replace the placeholder values with your actual Azure OpenAI credentials and specify the correct embedding model name that's deployed in your Azure OpenAI service.
248
+
199
249
  ## Documentation
200
250
 
201
251
  - [Guides and API documentation](https://help.getzep.com/graphiti).
@@ -206,10 +256,11 @@ as such this feature is off by default.
206
256
 
207
257
  Graphiti is under active development. We aim to maintain API stability while working on:
208
258
 
209
- - [ ] Supporting custom graph schemas:
210
- - Allow developers to provide their own defined node and edge classes when ingesting episodes
211
- - Enable more flexible knowledge representation tailored to specific use cases
259
+ - [x] Supporting custom graph schemas:
260
+ - Allow developers to provide their own defined node and edge classes when ingesting episodes
261
+ - Enable more flexible knowledge representation tailored to specific use cases
212
262
  - [x] Enhancing retrieval capabilities with more robust and configurable options
263
+ - [ ] Graphiti MCP Server
213
264
  - [ ] Expanding test coverage to ensure reliability and catch edge cases
214
265
 
215
266
  ## Contributing
@@ -0,0 +1,20 @@
1
+ """
2
+ Copyright 2025, Zep Software, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ """
16
+
17
+ from .client import CrossEncoderClient
18
+ from .openai_reranker_client import OpenAIRerankerClient
19
+
20
+ __all__ = ['CrossEncoderClient', 'OpenAIRerankerClient']
@@ -18,7 +18,7 @@ import logging
18
18
  from typing import Any
19
19
 
20
20
  import openai
21
- from openai import AsyncOpenAI
21
+ from openai import AsyncAzureOpenAI, AsyncOpenAI
22
22
  from pydantic import BaseModel
23
23
 
24
24
  from ..helpers import semaphore_gather
@@ -36,21 +36,29 @@ class BooleanClassifier(BaseModel):
36
36
 
37
37
 
38
38
  class OpenAIRerankerClient(CrossEncoderClient):
39
- def __init__(self, config: LLMConfig | None = None):
39
+ def __init__(
40
+ self,
41
+ config: LLMConfig | None = None,
42
+ client: AsyncOpenAI | AsyncAzureOpenAI | None = None,
43
+ ):
40
44
  """
41
- Initialize the OpenAIClient with the provided configuration, cache setting, and client.
45
+ Initialize the OpenAIRerankerClient with the provided configuration and client.
46
+
47
+ This reranker uses the OpenAI API to run a simple boolean classifier prompt concurrently
48
+ for each passage. Log-probabilities are used to rank the passages.
42
49
 
43
50
  Args:
44
51
  config (LLMConfig | None): The configuration for the LLM client, including API key, model, base URL, temperature, and max tokens.
45
- cache (bool): Whether to use caching for responses. Defaults to False.
46
- client (Any | None): An optional async client instance to use. If not provided, a new AsyncOpenAI client is created.
47
-
52
+ client (AsyncOpenAI | AsyncAzureOpenAI | None): An optional async client instance to use. If not provided, a new AsyncOpenAI client is created.
48
53
  """
49
54
  if config is None:
50
55
  config = LLMConfig()
51
56
 
52
57
  self.config = config
53
- self.client = AsyncOpenAI(api_key=config.api_key, base_url=config.base_url)
58
+ if client is None:
59
+ self.client = AsyncOpenAI(api_key=config.api_key, base_url=config.base_url)
60
+ else:
61
+ self.client = client
54
62
 
55
63
  async def rank(self, query: str, passages: list[str]) -> list[tuple[str, float]]:
56
64
  openai_messages_list: Any = [
@@ -62,7 +70,7 @@ class OpenAIRerankerClient(CrossEncoderClient):
62
70
  Message(
63
71
  role='user',
64
72
  content=f"""
65
- Respond with "True" if PASSAGE is relevant to QUERY and "False" otherwise.
73
+ Respond with "True" if PASSAGE is relevant to QUERY and "False" otherwise.
66
74
  <PASSAGE>
67
75
  {passage}
68
76
  </PASSAGE>
@@ -15,8 +15,9 @@ limitations under the License.
15
15
  """
16
16
 
17
17
  from collections.abc import Iterable
18
+ from typing import Union
18
19
 
19
- from openai import AsyncOpenAI
20
+ from openai import AsyncAzureOpenAI, AsyncOpenAI
20
21
  from openai.types import EmbeddingModel
21
22
 
22
23
  from .client import EmbedderClient, EmbedderConfig
@@ -33,13 +34,23 @@ class OpenAIEmbedderConfig(EmbedderConfig):
33
34
  class OpenAIEmbedder(EmbedderClient):
34
35
  """
35
36
  OpenAI Embedder Client
37
+
38
+ This client supports both AsyncOpenAI and AsyncAzureOpenAI clients.
36
39
  """
37
40
 
38
- def __init__(self, config: OpenAIEmbedderConfig | None = None):
41
+ def __init__(
42
+ self,
43
+ config: OpenAIEmbedderConfig | None = None,
44
+ client: Union[AsyncOpenAI, AsyncAzureOpenAI, None] = None,
45
+ ):
39
46
  if config is None:
40
47
  config = OpenAIEmbedderConfig()
41
48
  self.config = config
42
- self.client = AsyncOpenAI(api_key=config.api_key, base_url=config.base_url)
49
+
50
+ if client is not None:
51
+ self.client = client
52
+ else:
53
+ self.client = AsyncOpenAI(api_key=config.api_key, base_url=config.base_url)
43
54
 
44
55
  async def create(
45
56
  self, input_data: str | list[str] | Iterable[int] | Iterable[Iterable[int]]
@@ -30,10 +30,10 @@ EPISODIC_NODE_SAVE_BULK = """
30
30
  """
31
31
 
32
32
  ENTITY_NODE_SAVE = """
33
- MERGE (n:Entity {uuid: $uuid})
33
+ MERGE (n:Entity {uuid: $entity_data.uuid})
34
34
  SET n:$($labels)
35
35
  SET n = $entity_data
36
- WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
36
+ WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $entity_data.name_embedding)
37
37
  RETURN n.uuid AS uuid"""
38
38
 
39
39
  ENTITY_NODE_SAVE_BULK = """
@@ -189,6 +189,9 @@ async def extract_nodes(
189
189
  new_nodes = []
190
190
  for name in extracted_node_names:
191
191
  entity_type = node_classifications.get(name)
192
+ if entity_types is not None and entity_type not in entity_types:
193
+ entity_type = None
194
+
192
195
  labels = (
193
196
  ['Entity']
194
197
  if entity_type is None or entity_type == 'None' or entity_type == 'null'
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "graphiti-core"
3
- version = "0.8.0"
3
+ version = "0.8.2"
4
4
  description = "A temporal graph building library"
5
5
  authors = [
6
6
  "Paul Paliychuk <paul@getzep.com>",
File without changes
File without changes