Agent skill

graphrag-patterns

GraphRAG implementation patterns for hybrid search, Text2Cypher, and agentic retrieval. Use when implementing RAG workflows with Neo4j.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/graphrag-patterns

SKILL.md

GraphRAG Patterns

Hybrid Search (Vector + Keyword)

Combine vector similarity with full-text search for better recall:

python
from langchain_neo4j import Neo4jVector

def create_hybrid_retriever(driver, embeddings):
    return Neo4jVector.from_existing_graph(
        embeddings,
        driver=driver,
        index_name="article_embeddings",
        keyword_index_name="article_fulltext",
        search_type="hybrid",  # Combines vector + keyword
        node_label="Article",
        text_node_properties=["content", "summary"],
        embedding_node_property="embedding",
    )

Text2Cypher with Few-Shot Examples

Always provide examples for better query generation:

python
FEW_SHOT_EXAMPLES = [
    {
        "question": "What articles discuss requirements traceability?",
        "cypher": '''
            MATCH (a:Article)
            WHERE a.content CONTAINS 'traceability'
            RETURN a.title, a.summary
            LIMIT 10
        '''
    },
    {
        "question": "Which chapters have the most articles?",
        "cypher": '''
            MATCH (c:Chapter)-[:CONTAINS]->(a:Article)
            RETURN c.title, count(a) as article_count
            ORDER BY article_count DESC
        '''
    },
]

from langchain_neo4j import GraphCypherQAChain

chain = GraphCypherQAChain.from_llm(
    llm=llm,
    graph=graph,
    cypher_prompt=CYPHER_PROMPT,
    example_selector=SemanticSimilarityExampleSelector.from_examples(
        FEW_SHOT_EXAMPLES,
        embeddings,
        k=3,
    ),
    validate_cypher=True,
)

Agentic Router Pattern

Route queries to the best retrieval strategy:

python
from langchain_core.prompts import ChatPromptTemplate

ROUTER_PROMPT = ChatPromptTemplate.from_template('''
Classify the query into one of these retrieval strategies:

- VECTOR: Semantic similarity search (concepts, topics, "similar to")
- CYPHER: Structured queries (counts, relationships, specific filters)
- HYBRID: Complex queries needing both approaches

Query: {query}

Strategy:''')

async def route_query(query: str, llm) -> str:
    response = await llm.ainvoke(ROUTER_PROMPT.format(query=query))
    return response.content.strip().upper()

Graph-Enriched Retrieval

Augment vector results with graph context:

python
async def graph_enriched_search(driver, query: str, embeddings) -> list[dict]:
    # Step 1: Vector search for relevant articles
    vector_results = await vector_search(driver, query, embeddings, limit=5)

    # Step 2: Expand with graph traversal
    article_ids = [r["id"] for r in vector_results]

    enrichment_query = '''
        MATCH (a:Article) WHERE a.id IN $ids
        OPTIONAL MATCH (a)<-[:CONTAINS]-(c:Chapter)
        OPTIONAL MATCH (a)-[:RELATED_TO]->(related:Article)
        RETURN a, c.title as chapter, collect(DISTINCT related.title) as related_articles
    '''

    enriched = await execute_read_query(driver, enrichment_query, {"ids": article_ids})
    return enriched

RAGAS Evaluation Metrics

Evaluate retrieval quality:

python
from ragas.metrics import (
    context_precision,
    context_recall,
    faithfulness,
    answer_relevancy,
)
from ragas import evaluate

def evaluate_retrieval(questions, ground_truths, contexts, answers):
    dataset = Dataset.from_dict({
        "question": questions,
        "ground_truth": ground_truths,
        "contexts": contexts,
        "answer": answers,
    })

    results = evaluate(
        dataset,
        metrics=[
            context_precision,
            context_recall,
            faithfulness,
            answer_relevancy,
        ],
    )
    return results

Stepback Prompting

For complex queries, generate a broader question first:

python
STEPBACK_PROMPT = '''
Given a specific question, generate a more general "stepback" question
that would help gather broader context before answering the specific question.

Specific question: {question}
Stepback question:'''

async def stepback_retrieval(query: str, retriever, llm):
    # Generate stepback question
    stepback_q = await llm.ainvoke(STEPBACK_PROMPT.format(question=query))

    # Retrieve for both questions
    specific_docs = await retriever.ainvoke(query)
    stepback_docs = await retriever.ainvoke(stepback_q.content)

    # Combine and deduplicate
    all_docs = {doc.page_content: doc for doc in specific_docs + stepback_docs}
    return list(all_docs.values())

Didn't find tool you were looking for?

Be as detailed as possible for better results