The chunks in the knowledge graph include vector embeddings that allow for similarity search based on vector distance.
You can create a vector retriever that uses these embeddings to find the most relevant chunks for a given query.
The retriever can then use the structured and unstructured data in the knowledge graph to provide additional context.
Create the Vector Index
You will need to create a vector index on the Chunk nodes embedding properties:
CREATE VECTOR INDEX chunkEmbedding IF NOT EXISTS
FOR (n:Chunk)
ON n.embedding
OPTIONS {indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}};A vector index named chunkEmbedding will be created for nodes with a Chunk label, indexing the embedding property.
The index is configured to 1536 dimensions (as provided by the text-embedding-ada-002 embedding model) and use cosine similarity for distance calculations.
You can search the vector index by creating an embedding for a search term:
WITH genai.vector.encode(
"Retrieval Augmented Generation",
"OpenAI",
{ token: "sk-..." }) AS userEmbedding
CALL db.index.vector.queryNodes('chunkEmbedding', 5, userEmbedding)
YIELD node, score
RETURN node.text, scoreOpenAI Token
You will need to update the $token with your OpenAI API key.
Create a Vector + Cypher GraphRAG pipeline
The neo4j_graphrag package includes a VectorCypherRetriever class that combines vector similarity search with Cypher retrieval.
You can use this retriever to create a GraphRAG pipeline to:
-
Perform a vector similarity search to find the most relevant chunks for a given query.
-
Use a Cypher query to add additional information to the context.
-
Pass the context to an LLM to generate a response to the original query.
Open genai-graphrag-python/vector_cypher_rag.py and review the code:
import os
from dotenv import load_dotenv
load_dotenv()
from neo4j import GraphDatabase
from neo4j_graphrag.embeddings.openai import OpenAIEmbeddings
from neo4j_graphrag.retrievers import VectorCypherRetriever
from neo4j_graphrag.llm import OpenAILLM
from neo4j_graphrag.generation import GraphRAG
# Connect to Neo4j database
driver = GraphDatabase.driver(
os.getenv("NEO4J_URI"),
auth=(
os.getenv("NEO4J_USERNAME"),
os.getenv("NEO4J_PASSWORD")
)
)
# Create embedder
embedder = OpenAIEmbeddings(model="text-embedding-ada-002")
# Define retrieval query
retrieval_query = """
RETURN node.text as text, score
"""
# Create retriever
retriever = VectorCypherRetriever(
driver,
neo4j_database=os.getenv("NEO4J_DATABASE"),
index_name="chunkEmbedding",
embedder=embedder,
retrieval_query=retrieval_query,
)
# Create the LLM
llm = OpenAILLM(model_name="gpt-4o")
# Create GraphRAG pipeline
rag = GraphRAG(retriever=retriever, llm=llm)
# Search
query_text = "Where can I learn more about knowledge graphs?"
response = rag.search(
query_text=query_text,
retriever_config={"top_k": 5},
return_context=True
)
print(response.answer)
# Close the database connection
driver.close()The retriever is configured to use the chunkEmbedding vector index you just created.
retriever = VectorCypherRetriever(
driver,
neo4j_database=os.getenv("NEO4J_DATABASE"),
index_name="chunkEmbedding",
embedder=embedder,
retrieval_query=retrieval_query,
)When you run the code:
-
The
VectorCypherRetrieveruses the vector index to find chunks similar to the query:"Where can I learn more about knowledge graphs?"
-
The
GraphRAGpipelines passes the text from those chunks as context to the LLM. -
The response from the LLM is printed:
You can learn more about knowledge graphs in the Neo4j blog post linked here: What Is a Knowledge Graph?
You can print the context passed to the LLM by adding the following to the end of the code:
print("CONTEXT:", response.retriever_result.items)Retrieval Cypher Query
The VectorCypherRetriever also allows you to define a Cypher query to retrieve additional context from the knowledge graph.
Adding additional context can help the LLM generate more accurate responses.
Update the retrieval_query to add additional information about the lessons, technologies, and concepts related to the chunks:
retrieval_query = """
RETURN DISTINCT
node.text as text, score,
collect { MATCH (node)-[:FROM_DOCUMENT]->(d)-[:PDF_OF]->(lesson) RETURN lesson.url} as lesson_url,
collect { MATCH (node)<-[:FROM_CHUNK]-(e:Technology) RETURN e.name } as technologies,
collect { MATCH (node)<-[:FROM_CHUNK]-(e:Concept) RETURN e.name } as concepts
"""The retriever will execute the Cypher query adding more context.
Running the code again for the same query, "Where can I learn more about knowledge graphs?", will produce a more detailed response:
You can learn more about knowledge graphs in the Neo4j blog post linked here: What Is a Knowledge Graph?. Additionally, you can explore further lessons on knowledge graphs on the GraphAcademy website, specifically in the course "GenAI Fundamentals," including the sections "What is a Knowledge Graph" and "Creating Knowledge Graphs."
The retrieval query includes additional context relating to technologies and concepts mentioned in the chunks.
Experiment asking different questions relating to the knowledge graph such as "What technologies and concepts support knowledge graphs?".
Check your understanding
What are the steps taken by the GraphRAG pipeline when answering a question? (Select all that apply)
-
✓ Perform a vector similarity search to find the most relevant chunks for a given query
-
✓ Use a Cypher query to add additional information to the context
-
❏ Generate multiple embeddings for different interpretations of the user query
-
✓ Pass the context to an LLM to generate a response to the original query
Hint
Think about the three main steps described in the lesson for how the VectorCypherRetriever and GraphRAG pipeline work together.
Solution
The GraphRAG pipeline follows these three main steps:
-
Perform a vector similarity search - Uses the vector index to find chunks most similar to the user’s query
-
Use a Cypher query to add additional information - Executes a retrieval query to gather more context from the knowledge graph related to the found chunks
-
Pass the context to an LLM - Sends all the gathered context to the language model to generate a response to the original query
The incorrect option about "generating multiple embeddings for different interpretations" is not part of the described pipeline. The pipeline generates one embedding for the user query and uses it to find similar chunks, rather than creating multiple interpretations.
Lesson Summary
In this lesson, you:
-
Created a vector index on the
Chunknodes in the knowledge graph. -
Used the
VectorCypherRetrieverto perform vector similarity search and Cypher retrieval. -
Created a
GraphRAGpipeline to generate responses with context from the knowledge graph.
In the next lesson, you will use the Text2CypherRetriever retriever to get information from the knowledge graph based on natural language questions.