266 lines
11 KiB
Markdown
266 lines
11 KiB
Markdown
<p align="center">
|
||
<a href="https://www.getzep.com/">
|
||
<img src="https://github.com/user-attachments/assets/119c5682-9654-4257-8922-56b7cb8ffd73" width="150" alt="Zep Logo">
|
||
</a>
|
||
</p>
|
||
|
||
<h1 align="center">
|
||
Graphiti
|
||
</h1>
|
||
<h2 align="center"> Temporal Knowledge Graphs for Agentic Applications</h2>
|
||
<br />
|
||
|
||
[](https://discord.com/invite/W8Kw6bsgXQ)
|
||
[](https://github.com/getzep/Graphiti/actions/workflows/lint.yml)
|
||
[](https://github.com/getzep/Graphiti/actions/workflows/unit_tests.yml)
|
||
[](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
|
||
[](https://codespaces.new/getzep/Graphiti)
|
||
|
||
:star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
|
||
<br />
|
||
|
||
Graphiti builds dynamic, temporally aware Knowledge Graphs that represent complex, evolving relationships between
|
||
entities over time. Graphiti ingests both unstructured and structured data, and the resulting graph may be queried using
|
||
a fusion of time, full-text, semantic, and graph algorithm approaches, effectively serving as a powerful memory layer for AI applications.
|
||
|
||
<br />
|
||
|
||
<p align="center">
|
||
<img src="images/graphiti-graph-intro.gif" alt="Graphiti temporal walkthrough" width="700px">
|
||
</p>
|
||
|
||
<br />
|
||
|
||
Graphiti helps you create and query Knowledge Graphs that evolve over time. 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
|
||
nodes (_”Kendra”_, _“Adidas shoes”_), and their relationship, or edge (_”loves”_). Knowledge Graphs have been explored
|
||
extensively for information retrieval. What makes Graphiti unique is its ability to autonomously build a knowledge graph
|
||
while handling changing relationships and maintaining historical context.
|
||
|
||
With Graphiti, you can build LLM applications such as:
|
||
|
||
- Assistants that learn from user interactions, fusing personal knowledge with dynamic data from business systems like
|
||
CRMs and billing platforms through robust conversation history management.
|
||
- Agents that autonomously execute complex tasks, reasoning with state changes from multiple dynamic sources through persistent memory.
|
||
|
||
Graphiti supports a wide range of applications in sales, customer service, health, finance, and more, enabling long-term recall and state-based reasoning for both assistants and agents.
|
||
|
||
## Graphiti and Zep Memory
|
||
|
||
Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for LLM-powered Assistants and Agents.
|
||
|
||
Using Graphiti, we've demonstrated Zep is
|
||
the [State of the Art in Agent Memory](https://blog.getzep.com/state-of-the-art-agent-memory/).
|
||
|
||
Read our paper: [Zep: A Temporal Knowledge Graph Architecture for Agent Memory](https://arxiv.org/abs/2501.13956).
|
||
|
||
We're excited to open-source Graphiti, believing its potential reaches far beyond AI memory applications.
|
||
|
||
<p align="center">
|
||
<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>
|
||
</p>
|
||
|
||
## Why Graphiti?
|
||
|
||
We were intrigued by Microsoft's GraphRAG, which expanded on RAG (Retrieval-Augmented Generation) text chunking by using a graph to better model a
|
||
document corpus and making this representation available via semantic and graph search techniques. However, GraphRAG did
|
||
not address our core problem: It's primarily designed for static documents and doesn't inherently handle temporal
|
||
aspects of data.
|
||
|
||
Graphiti is designed from the ground up to handle constantly changing information, hybrid semantic and graph search, and
|
||
scale:
|
||
|
||
- **Temporal Awareness:** Tracks changes in facts and relationships over time, enabling point-in-time queries. Graph
|
||
edges include temporal metadata to record relationship lifecycles, creating a comprehensive context window extension.
|
||
- **Episodic Processing:** Ingests data as discrete episodes, maintaining data provenance and allowing incremental
|
||
entity and relationship extraction, ideal for chat state management.
|
||
- **Hybrid Search:** Combines semantic and BM25 full-text search, with the ability to rerank results by distance from a
|
||
central node e.g. "Kendra".
|
||
- **Scalable:** Designed for processing large datasets, with parallelization of LLM calls for bulk processing while
|
||
preserving the chronology of events and enabling efficient knowledge retrieval.
|
||
- **Supports Varied Sources:** Can ingest both unstructured text and structured JSON data.
|
||
|
||
<p align="center">
|
||
<img src="/images/graphiti-intro-slides-stock-2.gif" alt="Graphiti structured + unstructured demo" width="700px">
|
||
</p>
|
||
|
||
## Installation
|
||
|
||
Requirements:
|
||
|
||
- Python 3.10 or higher
|
||
- Neo4j 5.26 or higher (serves as the embeddings storage backend)
|
||
- OpenAI API key (for LLM inference and embedding)
|
||
|
||
Optional:
|
||
|
||
- Anthropic or Groq API key (for alternative LLM providers)
|
||
|
||
> [!TIP]
|
||
> The simplest way to install Neo4j is via [Neo4j Desktop](https://neo4j.com/download/). It provides a user-friendly
|
||
> interface to manage Neo4j instances and databases.
|
||
|
||
```bash
|
||
pip install graphiti-core
|
||
```
|
||
|
||
or
|
||
|
||
```bash
|
||
poetry add graphiti-core
|
||
```
|
||
|
||
## Quick Start
|
||
|
||
> [!IMPORTANT]
|
||
> Graphiti uses OpenAI for LLM inference and embedding. Ensure that an `OPENAI_API_KEY` is set in your environment.
|
||
> Support for Anthropic and Groq LLM inferences is available, too. Other LLM providers may be supported via OpenAI
|
||
> compatible APIs.
|
||
|
||
```python
|
||
from graphiti_core import Graphiti
|
||
from graphiti_core.nodes import EpisodeType
|
||
from datetime import datetime, timezone
|
||
|
||
# Initialize Graphiti as Your Memory Layer
|
||
graphiti = Graphiti("bolt://localhost:7687", "neo4j", "password")
|
||
|
||
# Initialize the graph database with Graphiti's indices. This only needs to be done once.
|
||
graphiti.build_indices_and_constraints()
|
||
|
||
# Add episodes
|
||
episodes = [
|
||
"Kamala Harris is the Attorney General of California. She was previously "
|
||
"the district attorney for San Francisco.",
|
||
"As AG, Harris was in office from January 3, 2011 – January 3, 2017",
|
||
]
|
||
for i, episode in enumerate(episodes):
|
||
await graphiti.add_episode(
|
||
name=f"Freakonomics Radio {i}",
|
||
episode_body=episode,
|
||
source=EpisodeType.text,
|
||
source_description="podcast",
|
||
reference_time=datetime.now(timezone.utc)
|
||
)
|
||
|
||
# Search the graph for semantic memory retrieval
|
||
# Execute a hybrid search combining semantic similarity and BM25 retrieval
|
||
# Results are combined and reranked using Reciprocal Rank Fusion
|
||
results = await graphiti.search('Who was the California Attorney General?')
|
||
[
|
||
EntityEdge(
|
||
│ uuid = '3133258f738e487383f07b04e15d4ac0',
|
||
│ source_node_uuid = '2a85789b318d4e418050506879906e62',
|
||
│ target_node_uuid = 'baf7781f445945989d6e4f927f881556',
|
||
│ created_at = datetime.datetime(2024, 8, 26, 13, 13, 24, 861097),
|
||
│ name = 'HELD_POSITION',
|
||
# the fact reflects the updated state that Harris is
|
||
# no longer the AG of California
|
||
│ fact = 'Kamala Harris was the Attorney General of California',
|
||
│ fact_embedding = [
|
||
│ │ -0.009955154731869698,
|
||
│ ...
|
||
│ │ 0.00784289836883545
|
||
│],
|
||
│ episodes = ['b43e98ad0a904088a76c67985caecc22'],
|
||
│ expired_at = datetime.datetime(2024, 8, 26, 20, 18, 1, 53812),
|
||
# These dates represent the date this edge was true.
|
||
│ valid_at = datetime.datetime(2011, 1, 3, 0, 0, tzinfo= < UTC >),
|
||
│ invalid_at = datetime.datetime(2017, 1, 3, 0, 0, tzinfo= < UTC >)
|
||
)
|
||
]
|
||
|
||
# Rerank search results based on graph distance
|
||
# Provide a node UUID to prioritize results closer to that node in the graph.
|
||
# Results are weighted by their proximity, with distant edges receiving lower scores.
|
||
await graphiti.search('Who was the California Attorney General?', center_node_uuid)
|
||
|
||
# Close the connection when chat state management is complete
|
||
graphiti.close()
|
||
```
|
||
|
||
## Graph Service
|
||
|
||
The `server` directory contains an API service for interacting with the Graphiti API. It is built using FastAPI.
|
||
|
||
Please see the [server README](./server/README.md) for more information.
|
||
|
||
## Optional Environment Variables
|
||
|
||
In addition to the Neo4j and OpenAi-compatible credentials, Graphiti also has a few optional environment variables.
|
||
If you are using one of our supported models, such as Anthropic or Voyage models, the necessary environment variables
|
||
must be set.
|
||
|
||
`USE_PARALLEL_RUNTIME` is an optional boolean variable that can be set to true if you wish
|
||
to enable Neo4j's parallel runtime feature for several of our search queries.
|
||
Note that this feature is not supported for Neo4j Community edition or for smaller AuraDB instances,
|
||
as such this feature is off by default.
|
||
|
||
## Using Graphiti with Azure OpenAI
|
||
|
||
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.
|
||
|
||
```python
|
||
from openai import AsyncAzureOpenAI
|
||
from graphiti_core import Graphiti
|
||
from graphiti_core.llm_client import OpenAIClient
|
||
from graphiti_core.embedder.openai import OpenAIEmbedder, OpenAIEmbedderConfig
|
||
|
||
# Azure OpenAI configuration
|
||
api_key = "<your-api-key>"
|
||
api_version = "<your-api-version>"
|
||
azure_endpoint = "<your-azure-endpoint>"
|
||
|
||
# Create Azure OpenAI client for LLM
|
||
azure_openai_client = AsyncAzureOpenAI(
|
||
api_key=api_key,
|
||
api_version=api_version,
|
||
azure_endpoint=azure_endpoint
|
||
)
|
||
|
||
# Initialize Graphiti with Azure OpenAI clients
|
||
graphiti = Graphiti(
|
||
"bolt://localhost:7687",
|
||
"neo4j",
|
||
"password",
|
||
llm_client=OpenAIClient(
|
||
client=azure_openai_client
|
||
),
|
||
embedder=OpenAIEmbedder(
|
||
config=OpenAIEmbedderConfig(
|
||
embedding_model="text-embedding-3-small" # Use your Azure deployed embedding model name
|
||
),
|
||
client=azure_openai_client
|
||
)
|
||
)
|
||
|
||
# Now you can use Graphiti with Azure OpenAI
|
||
```
|
||
|
||
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.
|
||
|
||
## Documentation
|
||
|
||
- [Guides and API documentation](https://help.getzep.com/graphiti).
|
||
- [Quick Start](https://help.getzep.com/graphiti/graphiti/quick-start)
|
||
- [Building an agent with LangChain's LangGraph and Graphiti](https://help.getzep.com/graphiti/graphiti/lang-graph-agent)
|
||
|
||
## Status and Roadmap
|
||
|
||
Graphiti is under active development. We aim to maintain API stability while working on:
|
||
|
||
- [x] Supporting custom graph schemas:
|
||
- Allow developers to provide their own defined node and edge classes when ingesting episodes
|
||
- Enable more flexible knowledge representation tailored to specific use cases
|
||
- [x] Enhancing retrieval capabilities with more robust and configurable options
|
||
- [ ] Expanding test coverage to ensure reliability and catch edge cases
|
||
|
||
## Contributing
|
||
|
||
We encourage and appreciate all forms of contributions, whether it's code, documentation, addressing GitHub Issues, or
|
||
answering questions in the Graphiti Discord channel. For detailed guidelines on code contributions, please refer
|
||
to [CONTRIBUTING](CONTRIBUTING.md).
|
||
|
||
## Support
|
||
|
||
Join the [Zep Discord server](https://discord.com/invite/W8Kw6bsgXQ) and make your way to the **#Graphiti** channel!
|