シンプルでハッキングしやすい GraphRAG 実装
? GraphRAG は優れており強力ですが、公式実装は読み取りやハッキングが困難/苦痛です。
?このプロジェクトは、コア機能を維持しながら、より小さく、より高速で、よりクリーンな GraphRAGを提供します (ベンチマークと問題点を参照)。
? tests
とプロンプトを除くと、 nano-graphrag
のコードは約 1100 行になります。
?小さいながらも移植可能(faiss、neo4j、ollama...)、非同期で完全に型指定されています。
ソースからインストールする(推奨)
# clone this repo first
cd nano-graphrag
pip install -e .
PyPiからインストール
pip install nano-graphrag
ヒント
OpenAI APIキーを環境export OPENAI_API_KEY="sk-..."
に設定してください。
ヒント
Azure OpenAI API を使用している場合は、.env.example を参照して Azure OpenAI を設定します。次に、 GraphRAG(...,using_azure_openai=True,...)
渡して有効にします。
ヒント
Amazon Bedrock API を使用している場合は、 aws configure
などのコマンドを使用して認証情報が適切に設定されていることを確認してください。次に、次のように設定して有効にします: GraphRAG(...,using_amazon_bedrock=True, best_model_id="us.anthropic.claude-3-sonnet-20240229-v1:0", cheap_model_id="us.anthropic.claude-3-haiku-20240307-v1:0",...)
。スクリプト例を参照してください。
ヒント
キーがない場合は、 transformers
とollama
使用するこの例を確認してください。別の LLM または埋め込みモデルを使用したい場合は、「詳細」にチェックを入れてください。
チャールズ・ディケンズの『クリスマス・キャロル』のコピーをダウンロードします。
curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > ./book.txt
以下の Python スニペットを使用します。
from nano_graphrag import GraphRAG , QueryParam
graph_func = GraphRAG ( working_dir = "./dickens" )
with open ( "./book.txt" ) as f :
graph_func . insert ( f . read ())
# Perform global graphrag search
print ( graph_func . query ( "What are the top themes in this story?" ))
# Perform local graphrag search (I think is better and more scalable one)
print ( graph_func . query ( "What are the top themes in this story?" , param = QueryParam ( mode = "local" )))
次回同じworking_dir
からGraphRAG
初期化すると、すべてのコンテキストが自動的に再ロードされます。
graph_func . insert ([ "TEXT1" , "TEXT2" ,...])
nano-graphrag
増分挿入をサポートしており、重複した計算やデータは追加されません。
with open ( "./book.txt" ) as f :
book = f . read ()
half_len = len ( book ) // 2
graph_func . insert ( book [: half_len ])
graph_func . insert ( book [ half_len :])
nano-graphrag
コンテンツの md5-hash をキーとして使用するため、重複したチャンクはありません。ただし、挿入するたびに、グラフのコミュニティが再計算され、コミュニティ レポートが再生成されます。
nano-graphrag
単純な RAG 挿入とクエリもサポートしています。
graph_func = GraphRAG ( working_dir = "./dickens" , enable_naive_rag = True )
...
# Query
print ( rag . query (
"What are the top themes in this story?" ,
param = QueryParam ( mode = "naive" )
)
各メソッドNAME(...)
には、対応する非同期メソッドaNAME(...)
があります。
await graph_func . ainsert (...)
await graph_func . aquery (...)
...
GraphRAG
とQueryParam
Python のdataclass
です。 help(GraphRAG)
とhelp(QueryParam)
を使用して、利用可能なすべてのパラメータを確認してください。または、「Advances」セクションをチェックしていくつかのオプションを確認してください。
使用できるコンポーネントは次のとおりです。
タイプ | 何 | どこ |
---|---|---|
LLM | OpenAI | 内蔵 |
アマゾンの岩盤 | 内蔵 | |
ディープシーク | 例 | |
ollama | 例 | |
埋め込み | OpenAI | 内蔵 |
アマゾンの岩盤 | 内蔵 | |
センテンストランスフォーマー | 例 | |
ベクトルデータベース | nano-vectordb | 内蔵 |
hnswlib | 組み込みの例 | |
milvus-lite | 例 | |
ファイス | 例 | |
グラフストレージ | networkx | 内蔵 |
neo4j | 組み込み(ドキュメント) | |
視覚化 | グラフミリ | 例 |
チャンク化 | トークンサイズ別 | 内蔵 |
テキストスプリッターによる | 内蔵 |
Built-in
nano-graphrag
内に実装があることを意味します。 examples
その実装がサンプル フォルダー内のチュートリアル内にあることを意味します。
サンプル/ベンチマークをチェックして、コンポーネント間の比較をいくつか確認してください。
より多くのコンポーネントに貢献することを常に歓迎します。
GraphRAG(...,always_create_working_dir=False,...)
ディレクトリ作成ステップをスキップします。すべてのコンポーネントを非ファイル ストレージに切り替える場合に使用します。graph_func.query
ストリーミングせずに最終的な答えを返します。
プロジェクト内でnano-graphrag
統合したい場合は、 param=QueryParam(..., only_need_context=True,...)
を使用できます。これは、次のように、グラフから取得したコンテキストのみを返します。
# Local mode
-----Reports-----
```csv
id, content
0, # FOX News and Key Figures in Media and Politics...
1, ...
```
...
# Global mode
----Analyst 3----
Importance Score: 100
Donald J. Trump: Frequently discussed in relation to his political activities...
...
そのコンテキストをカスタマイズしたプロンプトに統合できます。
nano-graphrag
nano_graphrag.prompt.PROMPTS
dict オブジェクトのプロンプトを使用します。これを試して、内部のプロンプトを置き換えることができます。
いくつかの重要なプロンプト:
PROMPTS["entity_extraction"]
テキスト チャンクからエンティティと関係を抽出するために使用されます。PROMPTS["community_report"]
グラフ クラスターの説明を整理して要約するために使用されます。PROMPTS["local_rag_response"]
ローカル検索生成のシステム プロンプト テンプレートです。PROMPTS["global_reduce_rag_response"]
グローバル検索生成のシステム プロンプト テンプレートです。PROMPTS["fail_response"]
ユーザー クエリに何も関連していない場合のフォールバック応答です。nano-graphrag
と、独自のチャンキング方法をカスタマイズできます。例を確認してください。
組み込みのテキスト分割チャンク方式に切り替えます。
from nano_graphrag . _op import chunking_by_seperators
GraphRAG (..., chunk_func = chunking_by_seperators ,...)
nano-graphrag
では、優れたものと安価なものの 2 種類の LLM が必要です。前者は計画と対応に使用され、後者は要約に使用されます。デフォルトでは、優れたものはgpt-4o
で、安価なものはgpt-4o-mini
です。
独自の LLM 関数を実装できます ( _llm.gpt_4o_complete
を参照)。
async def my_llm_complete (
prompt , system_prompt = None , history_messages = [], ** kwargs
) -> str :
# pop cache KV database if any
hashing_kv : BaseKVStorage = kwargs . pop ( "hashing_kv" , None )
# the rest kwargs are for calling LLM, for example, `max_tokens=xxx`
...
# YOUR LLM calling
response = await call_your_LLM ( messages , ** kwargs )
return response
デフォルトのものを次のように置き換えます。
# Adjust the max token size or the max async requests if needed
GraphRAG ( best_model_func = my_llm_complete , best_model_max_token_size = ..., best_model_max_async = ...)
GraphRAG ( cheap_model_func = my_llm_complete , cheap_model_max_token_size = ..., cheap_model_max_async = ...)
LLM モデルとしてdeepseek-chat
を使用するこの例を参照できます。
ollama
LLM モデルとして使用するこの例を参照してください。
nano-graphrag
、 best_model_func
を使用して、パラメータ"response_format": {"type": "json_object"}
で JSON を出力します。ただし、一部のオープンソース モデルでは不安定な JSON が生成される可能性があります。
nano-graphrag
応答を JSON に変換するための後処理インターフェイスを導入します。この関数の署名は次のとおりです。
def YOUR_STRING_TO_JSON_FUNC ( response : str ) -> dict :
"Convert the string response to JSON"
...
そして、 GraphRAG(...convert_response_to_json_func=YOUR_STRING_TO_JSON_FUNC,...)
によって独自の関数を渡します。
たとえば、json_repair を参照して、LLM から返された JSON 文字列を修復できます。
デフォルトの埋め込み関数を任意の_utils.EmbedddingFunc
インスタンスに置き換えることができます。
たとえば、デフォルトでは OpenAI 埋め込み API が使用されます。
@ wrap_embedding_func_with_attrs ( embedding_dim = 1536 , max_token_size = 8192 )
async def openai_embedding ( texts : list [ str ]) -> np . ndarray :
openai_async_client = AsyncOpenAI ()
response = await openai_async_client . embeddings . create (
model = "text-embedding-3-small" , input = texts , encoding_format = "float"
)
return np . array ([ dp . embedding for dp in response . data ])
デフォルトの埋め込み関数を次のように置き換えます。
GraphRAG ( embedding_func = your_embed_func , embedding_batch_num = ..., embedding_func_max_async = ...)
sentence-transformer
使用してローカルで埋め込みを計算する例を参照できます。
すべてのストレージ関連コンポーネントを独自の実装に置き換えることができます。nano nano-graphrag
主に 3 種類のストレージを使用します。
データの key-json ペアを保存するためのbase.BaseKVStorage
GraphRAG(.., key_string_value_json_storage_cls=YOURS,...)
埋め込みのインデックス作成のためのbase.BaseVectorStorage
nano-vectordb
使用します。hnswlib
ストレージもあります。この例を確認してください。milvus-lite
を実装するこの例を確認してください (Windows では使用できません)。GraphRAG(.., vector_db_storage_cls=YOURS,...)
ナレッジグラフを保存するためのbase.BaseGraphStorage
networkx
バックエンドとして使用します。Neo4jStorage
が組み込まれています。このチュートリアルを確認してください。GraphRAG(.., graph_storage_cls=YOURS,...)
nano_graphrag.base
を参照して、各コンポーネントの詳細なインターフェイスを確認できます。
FQAを確認してください。
ROADMAP.md を参照してください。
nano-graphrag
あらゆる種類の貢献を歓迎します。貢献する前にこれをお読みください。
nano-graphrag
使用したプロジェクトプロジェクトで
nano-graphrag
使用している場合は、プル リクエストを歓迎します。他の人がこのリポジトリを信頼するのに役立ちます❤️
nano-graphrag
GraphRAG
のcovariates
機能を実装していませんでしたnano-graphrag
オリジナルとは異なるグローバル検索を実装しています。オリジナルは、map-reduce のようなスタイルを使用してすべてのコミュニティをコンテキストに埋め込みますが、 nano-graphrag
上位 K 個の重要な中心的なコミュニティのみを使用します (制御にはQueryParam.global_max_consider_community
を使用します。デフォルトは 512 コミュニティです)。