GraphRAG is a FastAPI-based Retrieval-Augmented Generation (RAG) service that stores uploaded knowledge in Neo4j and answers questions with graph-aware retrieval.
The project ingests Markdown or text documents, builds both lexical and property/community graph representations, and exposes an HTTP chat interface for querying that knowledge base with an LLM-powered agent.
GraphRAG provides an end-to-end flow for graph-backed question answering:
- Upload a ZIP archive containing
.mdor.txtfiles. - Create or update a knowledge base record in Neo4j.
- Ingest the documents into two retrieval structures:
- Lexical graph: chunk-level document text and embeddings for semantic search.
- Property/community graph: extracted structured knowledge, communities, and summaries.
- Ask questions through the chat API.
- The RAG agent retrieves relevant lexical and community context and returns an answer.
api/
main.py FastAPI application entry point
routers/
chat.py Chat endpoint
knowledge_base.py Knowledge-base ingestion endpoint
dependencies/ Dependency providers for LLMs, vector stores, graph DB, and agent
schema/ API request and response models
bruno/ Bruno API collection
common/
graph/ Neo4j client and configuration
schema/ Shared knowledge-base schemas
services/ Knowledge-base persistence service
utils/ Environment and logging helpers
ingestion/
pipeline.py Ingestion orchestration
ingestors/ Lexical and property graph ingestors
readers/ Markdown/text readers
prompts/ Extraction prompts
schema/ Ingestion models
rag/
agent.py RAG agent factory
retrievers/ Vector, similarity, and DRIFT retrievers
tools/ Agent search tools
prompts/ Agent and retriever prompts
cyphers/ Cypher snippets
schema/ RAG context and retriever schemas
main.py Local/manual experimentation script
compose.yaml Docker Compose configuration
dockerfile Container image definition
pyproject.toml Python package metadata
- Python 3.13 for the application runtime.
- FastAPI for the HTTP API.
- Neo4j for graph persistence and vector-backed retrieval through LangChain Neo4j.
- Neo4j Graph Data Science (GDS) for Leiden community detection during property-graph ingestion.
- LangChain for document, vector-store, prompt, parser, and chat-model integrations.
- LangGraph with a SQLite checkpointer for conversational agent state.
- Google Generative AI embeddings through
langchain-google-genaifor vector embeddings. - OpenAI-compatible chat models through
langchain-openai; defaults point at OpenRouter unless overridden by environment variables. - Pydantic for API and extraction schemas.
- uv for container dependency installation.
- Docker / Docker Compose for containerized API startup.
Document ingestion is handled by the knowledge-base ingestion route and the Pipeline class. The route extracts an uploaded ZIP archive, keeps .md and .txt files, reads them as documents, and then runs both lexical and property graph ingestors.
The lexical ingestor stores document chunks in the Neo4j vector store, attaches each chunk to the knowledge base, creates a File node, and links chunks to their source file. It then retrieves chunk embeddings and creates SIMILAR relationships between chunks whose vector similarity is above the configured lexical threshold.
The property graph ingestor uses the configured chat model to extract structured graph data from document text. If the knowledge base does not already provide an ontology, the ingestor first asks the LLM to derive one from the knowledge extraction prompt. That ontology defines allowed entity labels and relationship rules.
For each document chunk, the ingestor sends the chunk text, ontology, and previously discovered entities to the LLM. The LLM response is parsed into entities and triplets with Pydantic output parsers. The ingestor deduplicates entities within the file, assigns stable internal IDs, writes entity nodes, links entities back to source chunks with BELONGS_TO, and creates extracted relationships between entities.
After entities and relationships are written, the property graph ingestor can run community extraction. It projects the file's graph into Neo4j GDS, runs the Leiden algorithm, writes community IDs, creates Community nodes, and links entities with IN_COMMUNITY. It then asks the LLM to summarize each community's triplets and embeds those summaries so the chat flow can retrieve community-level context.
The FastAPI application is configured with a /v1 root path.
Returns a basic service message.
Example response:
{
"message": "GraphRAG API"
}Uploads and ingests a knowledge base.
The endpoint accepts multipart form data described by IngestionRequest.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Knowledge-base identifier. |
name |
string | Yes | Human-readable knowledge-base name. |
description |
string | No | Optional knowledge-base description. |
knowledge_extraction_prompt |
string | No | Optional prompt used to guide property graph extraction. |
ontology |
object | No | Optional ontology definition for extracted entities and relationships. |
files |
file | Yes | ZIP archive containing .md or .txt files. |
During ingestion, the API extracts the archive, reads supported files, creates a KnowledgeBase, and schedules the ingestion pipeline as a background task.
Sends a question to the RAG agent.
Request body:
{
"query": "What does the knowledge base say about Ayrton Senna?",
"thread_id": "optional-existing-thread-id"
}| Field | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | User question. |
thread_id |
string | No | Existing conversation thread ID. If omitted, the API creates one. |
Example response:
{
"thread_id": "generated-or-supplied-thread-id",
"message": {
"content": "..."
}
}The chat route invokes the RAG agent with lexical and community vector stores plus DRIFT retrieval settings:
{
"top_k": 5,
"max_depth": 2,
"max_follow_ups": 3
}- Python
>=3.13 - Neo4j
- Provider credentials for the configured embedding model and chat model
Core Python dependencies include FastAPI, LangChain, LangChain Neo4j, LangChain OpenAI, LangChain Google GenAI, LangGraph SQLite checkpointing, Pydantic, NumPy, and python-dotenv.
Create environment variables for Neo4j and any model providers used by your deployment.
Common Neo4j variables:
NEO4J_URI=
NEO4J_USER=
NEO4J_PASSWORD=Depending on the selected LLM and embedding providers, you may also need provider-specific API keys such as:
GOOGLE_API_KEY=
OPENAI_API_KEY=
OPENROUTER_API_KEY=Install dependencies, then run the FastAPI application.
Using the FastAPI CLI:
fastapi dev api/main.pyUsing Uvicorn:
uvicorn api.main:app --reloadThe API routes are exposed under /v1.
The repository includes a dockerfile and compose.yaml for containerizing the API service. The image is based on python:3.13-slim, installs uv, runs uv sync --no-dev, copies the application into /app, creates a non-root appuser, exposes port 8000, and starts Uvicorn with api.main:app bound to 0.0.0.0:8000.
Build and run the API container with Docker Compose:
docker compose up --buildThe compose file maps host port 8000 to container port 8000, so the API is available at:
http://localhost:8000/v1/
The current compose file defines only the graphrag API service. You still need an accessible Neo4j instance configured through environment variables. Make sure the container receives the required Neo4j and model-provider variables, either through your shell environment, a Compose environment: block, or a Compose env_file: entry.
Example .env values:
NEO4J_URI=bolt://host.docker.internal:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
NEO4J_DATABASE=neo4j
LLM_MODEL=openai/gpt-oss-120b:free
LLM_BASE_URL=https://openrouter.ai/api/v1
LLM_TEMPERATURE=0.7
SQL_LITE_DB=database.dbThe top-level main.py script demonstrates manual setup for embeddings, chat models, Neo4j vector stores, ingestion checks, retrieval checks, and RAG-agent invocation. It is separate from the FastAPI app entry point in api/main.py.
A Bruno collection is included in api/bruno/ with example requests and environment configuration for the API.