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.
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/PKG-INFO +93 -42
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/README.md +92 -41
- graphiti_core-0.8.2/graphiti_core/cross_encoder/__init__.py +20 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/openai_reranker_client.py +16 -8
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/openai.py +14 -3
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/models/nodes/node_db_queries.py +2 -2
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/node_operations.py +3 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/pyproject.toml +1 -1
- graphiti_core-0.8.0/graphiti_core/utils/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/LICENSE +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/edges.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/embedder/voyage.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/errors.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/graphiti.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/helpers.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/anthropic_client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/config.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/errors.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/groq_client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/openai_client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/openai_generic_client.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/utils.py +0 -0
- {graphiti_core-0.8.0/graphiti_core/cross_encoder → graphiti_core-0.8.2/graphiti_core/models}/__init__.py +0 -0
- {graphiti_core-0.8.0/graphiti_core/models → graphiti_core-0.8.2/graphiti_core/models/edges}/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/models/edges/edge_db_queries.py +0 -0
- {graphiti_core-0.8.0/graphiti_core/models/edges → graphiti_core-0.8.2/graphiti_core/models/nodes}/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/nodes.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/dedupe_edges.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/dedupe_nodes.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/eval.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_edge_dates.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_edges.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/extract_nodes.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/invalidate_edges.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/lib.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/models.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/prompt_helpers.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/prompts/summarize_nodes.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/py.typed +0 -0
- {graphiti_core-0.8.0/graphiti_core/models/nodes → graphiti_core-0.8.2/graphiti_core/search}/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_config.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_config_recipes.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_filters.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/search/search_utils.py +0 -0
- {graphiti_core-0.8.0/graphiti_core/search → graphiti_core-0.8.2/graphiti_core/utils}/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/bulk_utils.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/datetime_utils.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/__init__.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/community_operations.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/graph_data_operations.py +0 -0
- {graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
- {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.
|
|
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">
|
|
32
|
+
<h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
|
|
33
33
|
<br />
|
|
34
34
|
|
|
35
35
|
[](https://discord.com/invite/W8Kw6bsgXQ)
|
|
@@ -38,12 +38,16 @@ Graphiti
|
|
|
38
38
|
[](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
|
|
39
39
|
[](https://codespaces.new/getzep/Graphiti)
|
|
40
40
|
|
|
41
|
-
:star:
|
|
41
|
+
:star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
|
|
42
42
|
<br />
|
|
43
43
|
|
|
44
|
-
Graphiti
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
- **
|
|
97
|
-
|
|
98
|
-
- **
|
|
99
|
-
|
|
100
|
-
- **
|
|
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
|
-
- [
|
|
232
|
-
|
|
233
|
-
|
|
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">
|
|
10
|
+
<h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
|
|
11
11
|
<br />
|
|
12
12
|
|
|
13
13
|
[](https://discord.com/invite/W8Kw6bsgXQ)
|
|
@@ -16,12 +16,16 @@ Graphiti
|
|
|
16
16
|
[](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
|
|
17
17
|
[](https://codespaces.new/getzep/Graphiti)
|
|
18
18
|
|
|
19
|
-
:star:
|
|
19
|
+
:star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
|
|
20
20
|
<br />
|
|
21
21
|
|
|
22
|
-
Graphiti
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
- **
|
|
75
|
-
|
|
76
|
-
- **
|
|
77
|
-
|
|
78
|
-
- **
|
|
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
|
-
- [
|
|
210
|
-
|
|
211
|
-
|
|
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']
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/openai_reranker_client.py
RENAMED
|
@@ -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__(
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
config: LLMConfig | None = None,
|
|
42
|
+
client: AsyncOpenAI | AsyncAzureOpenAI | None = None,
|
|
43
|
+
):
|
|
40
44
|
"""
|
|
41
|
-
Initialize the
|
|
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
|
-
|
|
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
|
-
|
|
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__(
|
|
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
|
-
|
|
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 = """
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/node_operations.py
RENAMED
|
@@ -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'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/cross_encoder/bge_reranker_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/llm_client/openai_generic_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.8.0/graphiti_core/search → graphiti_core-0.8.2/graphiti_core/utils}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/community_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/edge_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/graph_data_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.8.0 → graphiti_core-0.8.2}/graphiti_core/utils/maintenance/temporal_operations.py
RENAMED
|
File without changes
|
|
File without changes
|