neo4j-graphrag-skill について
neo4j-graphrag-skillは、neo4j-graphrag Pythonパッケージを使ったNeo4j GraphRAG検索パイプラインの構築を支援します。リトリーバーの選択、Cypherによるグラフ拡張、LLM連携、検索の問題解決を扱います。
主な機能
- 01ベクトル・ハイブリッド・Cypherリトリーバーの選択
- 02GraphRAGとLLMの構成
- 03検索用Cypherフラグメントの作成
- 04複数リトリーバーへのクエリ振り分け
- 05ベクトル・全文検索インデックスの設定
活用シーン
- 01Neo4j GraphRAG検索パイプラインの構築
- 02グラフ走査の要件に応じたリトリーバー選択
- 03検索品質の問題の調査
- 04自然言語によるNeo4jグラフ検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ neo4j-contrib/ neo4j-skills --skill neo4j-graphrag-skillインストール後、Claude Code で/neo4j-graphrag-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/kg-builder.mdknowledge-graph-construction.mdpipeline-dsl.mdproviders.mdretrievers.md詳細
Neo4j GraphRAG スキル
使用する場合
neo4j-graphragPython パッケージで GraphRAG 検索パイプラインを構築する- VectorRetriever、HybridRetriever、VectorCypherRetriever、HybridCypherRetriever のいずれかを選ぶ
- グラフで拡張したコンテキストを取得するための
retrieval_queryCypher フラグメントを記述する - リトリーバーと LLM を
GraphRAGパイプラインに接続する ToolsRetrieverで LLM が振り分けるマルチリトリーバーを使用する- 検索品質が低い場合の問題をデバッグする
- Neo4j を LangChain、LlamaIndex、または Haystack と統合する
使用しない場合
- ドキュメントからの KG 構築 →
neo4j-document-import-skill - グラフ走査を伴わない単純なベクトル/セマンティック検索 →
neo4j-vector-index-skill - ベクトル検索と全文検索、またはその他のランキング済みソースを組み合わせるハイブリッド検索 →
neo4j-vector-index-skill - GDS アルゴリズム(PageRank、Louvain、ノード埋め込み) →
neo4j-gds-skill - エージェントの長期メモリ →
neo4j-agent-memory-skill - 生の Cypher クエリの記述 →
neo4j-cypher-skill
リトリーバーの選択
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
| リトリーバー | ベクトル | 全文検索 | グラフ | 最適な用途 |
|---|---|---|---|---|
VectorRetriever | ✓ | — | — | ベースラインとなるセマンティック検索 |
HybridRetriever | ✓ | ✓ | — | グラフ拡張を伴わない、より高い再現率 |
VectorCypherRetriever | ✓ | — | ✓ | 全文検索を使わない GraphRAG |
HybridCypherRetriever | ✓ | ✓ | ✓ | 本番環境の GraphRAG — デフォルト |
Text2CypherRetriever | — | — | ✓ | NL→Cypher、埋め込みモデル不要 |
ToolsRetriever | さまざま | さまざま | さまざま | LLM が振り分けるマルチリトリーバー |
WeaviateNeo4jRetriever | ✓ | — | ✓ | Weaviate 内のベクトル |
PineconeNeo4jRetriever | ✓ | — | ✓ | Pinecone 内のベクトル |
QdrantNeo4jRetriever | ✓ | — | ✓ | Qdrant 内のベクトル |
インストール
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 retriever
必要条件:Python >= 3.10、neo4j >= 5.17.0(ドライバー 6.x に対応)。
ステップ 2 — リトリーバーを選ぶ
上記のリトリーバーの選択表から選んでください。
neo4j-graphrag のリトリーバー API を使わずにカスタム Cypher ハイブリッド検索を行う場合は、neo4j-vector-index-skill を使用してください。
ベクトルバックエンドの選択 [v1.16+, 自動]:Neo4j 2026.01+ では、フィルターが SEARCH に対応しており(単純な AND 比較)、すべてのフィルタープロパティがインデックスの WITH [n.prop] リストで宣言されている場合、4 種類すべてのベクトル/ハイブリッドリトリーバーが Cypher 25 の SEARCH ... WHERE 句を経由するよう自動的にルーティングされます。$or、$in、$like、または宣言されていないプロパティを使う場合は、db.index.vector.queryNodes() プロシージャのパスに自動的にフォールバックします(警告ログが記録されます)。create_vector_index() の filterable_properties=[...] でフィルター可能なプロパティを宣言してください。
ステップ 3 — インデックスを作成する(一度だけ実行)
// 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'
インデックスが ONLINE でない場合は、待機して 5 秒ごとに確認してください。ONLINE になるまで取り込みを開始しないでください。
ステップ 4 — 基本パターン(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
LLM を使って自然言語を Cypher に変換します。埋め込みモデルは不要です。
セキュリティ(v1.16.0+): LLM が生成した Cypher はすべて、最初に
EXPLAINを通して実行されます。 書き込み/破壊的操作に分類された文は実行されず、代わりにText2CypherRetrievalErrorが発生します。 これにより、プロンプトインジェクション攻撃を防ぎます。
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 が振り分けるマルチリトリーバー)
from neo4j_graphrag.retrievers import ToolsRetriever
tools_retriever = ToolsRetriever(
llm=llm,
retrievers=[vector_retriever, text2cypher_retriever],
)
# LLM decides which retriever(s) to invoke per query
# Convert any retriever to a standalone Tool:
tool = vector_retriever.convert_to_tool()
フィルター(ベクトル検索前の事前フィルタリング)
results = retriever.search(
query_text="quarterly earnings",
top_k=5,
filters={
"date": {"$gte": "2024-01-01"},
"source": {"$eq": "10-K"},
},
)
# Operators: $eq $ne $lt $lte $gt $gte $between $in $like $ilike
query_params(パラメーター化された retrieval_query)
retrieval_query = """
MATCH (node)<-[:HAS_CHUNK]-(a:Article)-[:MENTIONS]->(org:Organization {name: $entity_name})
RETURN node.text, a.title, score
"""
# Pass via retriever.search directly:
results = retriever.search(
query_text="What happened at Apple?",
top_k=10,
query_params={"entity_name": "Apple"},
)
# Or via GraphRAG.search:
response = rag.search(
query_text="What happened at Apple?",
retriever_config={"top_k": 10, "query_params": {"entity_name": "Apple"}},
)
Cypher 25 SEARCH 句(v1.16.0、Neo4j 2026.x+)
# Enable SEARCH clause syntax in vector/hybrid retrievers (requires Neo4j 2026+)
retriever = VectorRetriever(
driver=driver,
index_name="chunk_embedding",
embedder=embedder,
use_search_clause=True,
)
v1.19 以降、ベクトルリトリーバーとベクトル Cypher リトリーバーは、SEARCH クエリに自動的に CYPHER 25 を付加し、SEARCH がサポートされていない場合、または失敗した場合は、プロシージャベースのベクトル検索にフォールバックします。
コンポーネントのインポート(v1.19 — 破壊的変更、2.0 に向けた準備)
すべてのコンポーネントが experimental 名前空間の外に移動しました。古いインポートも引き続き機能しますが、DeprecationWarning が発生し、2.0 で削除されます。
# v1.19+ — preferred
from neo4j_graphrag.components.text_splitters.fixed_size_splitter import FixedSizeSplitter
# deprecated (removed in 2.0)
from neo4j_graphrag.experimental.components.text_splitters.fixed_size_splitter import FixedSizeSplitter
# SimpleKGPipeline did NOT move — only valid path:
from neo4j_graphrag.experimental.pipeline.kg_builder import SimpleKGPipeline
neo4j_graphrag.pipeline(v1.21 以降)は新しい遅延評価型データフロー DSL(Pipeline、LocalInterpreter、Sink)です。SimpleKGPipeline が使用する実験的なタスクグラフの Pipeline とは無関係です。neo4j_graphrag.pipeline.kg_builder は存在しないため、ModuleNotFoundError が発生します。
また v1.19 以降、Component/RunContext/TaskProgressNotifierProtocol は neo4j_graphrag.components.base にあります。また、不正なコンポーネントを指定すると PipelineDefinitionError ではなく ComponentDefinitionError が発生します。
データフローパイプライン DSL とオブザーバー(v1.21)
遅延評価型の neo4j_graphrag.pipeline.Pipeline と LocalInterpreter(observers=[...])、および TextSplitter.iter_chunks() を使用します。API の詳細 → references/pipeline-dsl.md。
Cypher リトリーバーでの ORDER BY(v1.16.0)
results = retriever.search(
query_text="...",
top_k=10,
order_by="score DESC",
)
neo4j_schema=None の場合、リトリーバーがスキーマを自動で取得します。大規模なスキーマの場合は、LLM のプロンプトサイズを抑えるため、短縮した文字列を渡してください。
破壊的クエリのガード[v1.16 以降]:Text2CypherRetriever は、生成された Cypher を実行前に EXPLAIN で検証し、書き込みを行うクエリ(CREATE、MERGE、DELETE、SET、REMOVE など)を拒否します。LLM が生成した書き込みクエリがグラフに対して実行されることはありません。
カスタムプロンプトテンプレート
from neo4j_graphrag.generation.prompts import RagTemplate
template = RagTemplate(
template="""Answer using ONLY the context below.
Context: {context}
Question: {query_text}
Answer:""",
expected_inputs=["context", "query_text"],
)
rag = GraphRAG(retriever=retriever, llm=llm, prompt_template=template)
return_context と response_fallback
response = rag.search(
query_text="...",
retriever_config={"top_k": 5},
return_context=True, # include raw retrieved chunks
response_fallback="No relevant context.", # skip LLM call if retriever returns nothing
)
print(response.answer)
print(response.retriever_result) # RawSearchResult when return_context=True
メッセージ履歴(複数ターン)
from neo4j_graphrag.message_history import InMemoryMessageHistory
history = InMemoryMessageHistory()
r1 = rag.search(query_text="Who is Alice?", message_history=history)
r2 = rag.search(query_text="Where does she work?", message_history=history)
外部リトリーバー、LLM とエンベッダープロバイダー
- Weaviate/Pinecone/Qdrant のコンストラクター → references/retrievers.md
- LLM クラス(
OpenAILLM、AnthropicLLM、GeminiLLM、VertexAILLM、BedrockLLM、…)、base_url、トークン使用量、close();エンベッダークラスと次元数 → references/providers.md
インデックスのセットアップ
from neo4j_graphrag.indexes import create_vector_index
# Vector index — adjust dimensions to match your embedding model
create_vector_index(
driver,
name="chunk_embedding",
label="Chunk",
embedding_property="embedding",
dimensions=1536,
similarity_fn="cosine", # or "euclidean"
)
# Fulltext index (run as Cypher)
# CREATE FULLTEXT INDEX chunk_fulltext IF NOT EXISTS
# FOR (c:Chunk) ON EACH [c.text]
スキーマの検査
from neo4j_graphrag.schema import get_schema, get_structured_schema
schema_str = get_schema(driver, sample=1000) # human-readable string
schema_dict = get_structured_schema(driver, sample=1000) # dict with labels/rels/props
よくあるエラー
| エラー | 原因 | 対処法 |
|---|---|---|
ModuleNotFoundError: neo4j_genai | 古いパッケージ名 | pip uninstall neo4j-genai && pip install neo4j-graphrag |
retrieval_query が 0 行を返す | MATCH がない、またはリレーションの方向が誤っている | フラグメントに EXPLAIN を実行し、CALL db.schema.visualization() を確認する |
結果で KeyError: 'score' が発生する | retrieval_query の RETURN に score がない | すべての retrieval_query の RETURN 句に score を追加する |
score 変数が見つからない | retrieval_query で score を再宣言している | score を再宣言しないでください。自動的に挿入されます |
Text2CypherRetrievalError | LLM が書き込みステートメントを生成した | 仕様どおりのセキュリティ動作です(v1.16.0 以降)。プロンプトまたはスキーマを見直してください |
TypeError: coroutine | await/asyncio.run() がない | 非同期呼び出しを asyncio.run(pipeline.run_async(...)) で囲む |
| HybridRetriever の結果が空 | 全文検索インデックスが ONLINE ではない | SHOW INDEXES YIELD name, state WHERE state <> 'ONLINE' |
VectorCypherRetriever と filters の併用で「requires: node_label, embedding_node_property, …」が発生する(v1.19 の名前不一致バグ) | _fetch_index_infos は self._embedding_node_property を設定する一方、コンストラクターは _node_embedding_property を設定する | 構築後にシムを適用する:r._node_embedding_property = r._embedding_node_property or "embedding";フィルタープロパティを r._filterable_properties に追加する |
| エンベッダーの次元数の不一致 | インデックスの次元数とモデルの次元数が異なる | 正しい dimensions= 値でインデックスを再作成する |
検証チェックリスト
-
neo4j-genaiではなくneo4j-graphragがインストールされていること。ドライバーはneo4j >= 5.17.0であること - 埋め込みの取り込みまたはリトリーバーの実行前に、ベクトルインデックスが ONLINE であること
- Hybrid バリアントを使用する場合、全文検索インデックスが ONLINE であること
-
create_vector_indexの埋め込み次元が、エンベッダーの出力と一致していること -
retrieval_queryの RETURN でnodeとscoreを返していること(再宣言していないこと) -
query_paramsはリトリーバーのコンストラクターではなく、rag.search()のretriever_config経由で渡すこと - API キーは環境変数に設定し、ハードコードしないこと
- リソースを解放するため、処理が終わったら
llm.close()を呼び出すこと
参考資料
必要に応じて読み込んでください:
- references/retrievers.md — リトリーバーごとのコンストラクターパラメーター、外部ベクトル DB リトリーバー、
result_formatter、事前フィルター演算子 - references/providers.md — LLM とエンベッダーのプロバイダークラス、追加パッケージ、デフォルト値
- references/pipeline-dsl.md — データフロー
PipelineDSL、Source/Sink、ステージオブザーバー [v1.21] - references/kg-builder.md —
SimpleKGPipelineのコンストラクター、スキーマ、分割器 - references/knowledge-graph-construction.md — 高度な KG パイプラインのカスタマイズ
- neo4j-graphrag package docs — neo4j-graphrag パッケージのドキュメント
- RAG & GraphRAG user guide — RAG と GraphRAG のユーザーガイド
- KG Builder user guide — KG Builder のユーザーガイド
- GitHub — neo4j-graphrag-python — GitHub — neo4j-graphrag-python
- Examples folder — サンプルフォルダー