Neo4j Graphrag Skill
Build GraphRAG retrieval pipelines on Neo4j using the neo4j-graphrag Python
- Skill ID
- neo4j-contrib/neo4j-skills/neo4j-graphrag-skill
- Publisher
- neo4j-contrib
- Repository
- neo4j-skills
- Installs
- 0
- Files
- 5
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
neo4j-contrib/neo4j-skills/neo4j-graphrag-skillInstalls these files- README.md
- SKILL.md
- references/kg-builder.md
- references/knowledge-graph-construction.md
- references/retrievers.md
What this skill tells the agent
Neo4j GraphRAG Skill
When to Use
- Building GraphRAG retrieval pipelines with
neo4j-graphragPython package - Choosing between VectorRetriever, HybridRetriever, VectorCypherRetriever, HybridCypherRetriever
- Writing
retrieval_queryCypher fragments for graph-augmented context - Wiring retriever + LLM into a
GraphRAGpipeline - Using LLM-routed multi-retriever with
ToolsRetriever - Debugging low retrieval quality
- Integrating Neo4j with LangChain, LlamaIndex, or Haystack
When NOT to Use
- KG construction from documents →
neo4j-document-import-skill - Plain vector/semantic search without graph traversal →
neo4j-vector-index-skill - Hybrid search that combines vector with fulltext or other ranked sources →
neo4j-vector-index-skill - GDS algorithms (PageRank, Louvain, node embeddings) →
neo4j-gds-skill - Agent long-term memory →
neo4j-agent-memory-skill - Writing raw Cypher queries →
neo4j-cypher-skill
Retriever Selection
Has fulltext index?
YES → Hybrid variants (HybridRetriever / HybridCypherRetriever)
NO → Vector variants (VectorRetriever / VectorCypherRetriever)
Need graph traversal after vector lookup?
YES → Cypher variants (VectorCypherRetriever / HybridCypherRetriever)
NO → plain variants
Natural-language-to-Cypher? → Text2CypherRetriever (no embedder needed)
LLM should route between retrievers? → ToolsRetriever
Vectors stored in external DB? → WeaviateNeo4jRetriever / PineconeNeo4jRetriever / QdrantNeo4jRetriever| Retriever | Vector | Fulltext | Graph | Best For |
|---|---|---|---|---|
VectorRetriever | ✓ | — | — | Baseline semantic search |
HybridRetriever | ✓ | ✓ | — | Better recall, no graph expansion |
VectorCypherRetriever | ✓ | — | ✓ | GraphRAG without fulltext |
HybridCypherRetriever | ✓ | ✓ | ✓ | Production GraphRAG — default |
Text2CypherRetriever | — | — | ✓ | NL→Cypher, no embedder |
ToolsRetriever | varies | varies | varies | LLM-routed multi-retriever |
WeaviateNeo4jRetriever | ✓ | — | ✓ | Vectors in Weaviate |
PineconeNeo4jRetriever | ✓ | — | ✓ | Vectors in Pinecone |
QdrantNeo4jRetriever | ✓ | — | ✓ | Vectors in Qdrant |
Install
pip install neo4j-graphrag[openai] # OpenAI LLM + embeddings
pip install neo4j-graphrag[anthropic] # Anthropic Claude
pip install neo4j-graphrag[google] # Vertex AI / Gemini
pip install neo4j-graphrag[bedrock] # Amazon Bedrock (boto3)
pip install neo4j-graphrag[cohere] # Cohere
pip install neo4j-graphrag[mistralai] # MistralAI
pip install neo4j-graphrag[ollama] # Ollama (local)
pip install neo4j-graphrag[weaviate] # Weaviate external retriever
pip install neo4j-graphrag[pinecone] # Pinecone external retriever
pip install neo4j-graphrag[qdrant] # Qdrant external retrieverRequires: Python >= 3.10, neo4j >= 5.17.0 (driver 6.x supported).
Step 2 — Choose Retriever
Has fulltext index? YES → Hybrid variants (better recall)
NO → Vector variants (baseline)
Needs graph context after vector lookup? YES → Cypher variants
NO → plain variants
For natural-language-to-Cypher? → Text2CypherRetriever (no embedder needed)
For multi-tool LLM routing? → ToolsRetriever
Using external vector DB? → WeaviateNeo4jRetriever / PineconeNeo4jRetriever / QdrantNeo4jRetriever| Retriever | Vector | Fulltext | Graph | When to use |
|---|---|---|---|---|
VectorRetriever | ✓ | — | — | Baseline; quick start |
HybridRetriever | ✓ | ✓ | — | Better recall; no graph context |
VectorCypherRetriever | ✓ | — | ✓ | GraphRAG without fulltext |
HybridCypherRetriever | ✓ | ✓ | ✓ | Production GraphRAG — default choice |
Text2CypherRetriever | — | — | ✓ | LLM generates Cypher; no embedder |
ToolsRetriever | varies | varies | varies | Multi-retriever LLM routing |
For custom Cypher hybrid search outside the neo4j-graphrag retriever APIs, use neo4j-vector-index-skill.
Vector backend selection [v1.16+, auto]: on Neo4j 2026.01+ all four vector/hybrid retrievers auto-route through the Cypher 25 SEARCH ... WHERE clause when filters are SEARCH-compatible (simple AND comparisons) and all filter props are declared in the index WITH [n.prop] list. $or, $in, $like, or undeclared props → automatic fallback to db.index.vector.queryNodes() procedure path (with warning log). Declare filterable properties via filterable_properties=[...] on create_vector_index().
Step 3 — Create Indexes (run once)
// Vector index (all retrievers need this)
CREATE VECTOR INDEX chunk_embedding IF NOT EXISTS
FOR (c:Chunk) ON (c.embedding)
OPTIONS { indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
} };
// Fulltext index (Hybrid retrievers only)
CREATE FULLTEXT INDEX chunk_fulltext IF NOT EXISTS
FOR (c:Chunk) ON EACH [c.text];
// Confirm ONLINE before ingesting:
SHOW INDEXES YIELD name, state
WHERE name IN ['chunk_embedding', 'chunk_fulltext']
RETURN name, state;
// Both must show state = 'ONLINE'If index not ONLINE: wait, poll every 5s. Do NOT start ingestion until ONLINE.
Step 4 — Core Pattern (HybridCypherRetriever)
from neo4j import GraphDatabase
from neo4j_graphrag.embeddings import OpenAIEmbeddings
from neo4j_graphrag.generation import GraphRAG
from neo4j_graphrag.llm import OpenAILLM
from neo4j_graphrag.retrievers import HybridCypherRetriever
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USERNAME, NEO4J_PASSWORD))
embedder = OpenAIEmbeddings(model="text-embedding-3-large") # OPENAI_API_KEY from env
# retrieval_query: Cypher fragment executed after the vector/fulltext lookup.
# Auto-injected variables: node (matched node) score (similarity float)
# MUST include a RETURN clause. score must appear in RETURN.
retrieval_query = """
MATCH (node)<-[:HAS_CHUNK]-(article:Article)
OPTIONAL MATCH (article)-[:MENTIONS]->(org:Organization)
RETURN node.text AS chunk_text,
article.title AS article_title,
collect(DISTINCT org.name) AS mentioned_organizations,
score
"""
retriever = HybridCypherRetriever(
driver=driver,
vector_index_name="chunk_embedding",
fulltext_index_name="chunk_fulltext",
retrieval_query=retrieval_query,
embedder=embedder,
)
llm = OpenAILLM(model_name="gpt-4.1", model_params={"temperature": 0})
rag = GraphRAG(
retriever=retriever,
llm=llm,
)
response = rag.search(
query_text="Who does Alice work for?",
retriever_config={"top_k": 5},
)
print(response.answer)
driver.close()VectorCypherRetriever
from neo4j_graphrag.retrievers import VectorCypherRetriever
retriever = VectorCypherRetriever(
driver=driver,
index_name="chunk_embedding",
retrieval_query=retrieval_query,
embedder=embedder,
)
response = rag.search(
query_text="What happened at Apple?",
retriever_config={"top_k": 10},
)Text2CypherRetriever
Translates natural language to Cypher using an LLM. No embedder required.
Security (v1.16.0+): Every LLM-generated Cypher is run throughEXPLAINfirst. Any statement classified as write/destructive raisesText2CypherRetrievalErrorinstead of executing — prevents prompt-injection attacks.
from neo4j_graphrag.retrievers import Text2CypherRetriever
retriever = Text2CypherRetriever(
driver=driver,
llm=OpenAILLM(model_name="gpt-4.1"),
neo4j_schema=None, # None = auto-fetch schema from DB; pass string to trim
examples=[
"Q: Who works at Neo4j? A: MATCH (p:Person)-[:WORKS_AT]->(c:Company {name:'Neo4j'}) RETURN p.name"
],
)
results = retriever.search(query_text="Which people work at Neo4j?")ToolsRetriever (LLM-routed multi-retriever)
from neo4j_graphrag.retrievers import ToolsRetriever
More from neo4j-contrib
Use this skill in a project
Open any RiverX project, search the Skills panel for neo4j-contrib/neo4j-skills/neo4j-graphrag-skill, and install it in one click.
