
テクニカルスペシャリスト
松尾 大輔 
今月からこちらのコラムを担当させていただくことになりました。よろしくお願いいたします。
私は主に、大規模言語モデル(LLM)を使ってシステム開発やシステム運用を支援するAIサービスの開発を行っています。特に最近では、LLMの精度向上もサービス開発を行う上での一つの課題となりつつあります。
そこで、初回のコラムでは、Microsoft Researchが公開しているGraphRAGを使い、従来のRAGと比べて、どのように精度向上ができるかを調べてみます。
従来のRAGとGraphRAGの違い
はじめに、従来のRAGとGraphRAGの違いについて整理したいと思います。どちらもLLMの出力を最適化するものであり、LLMが学習していない文書を外部ソースとして渡すことによって、回答の精度を向上させるものとなります。
従来のRAG
従来のRAGは、文書を500文字など一定量で区切り(チャンクと呼びます)、それを数値化(ベクトル化)して、ベクターストアと呼ばれる専用のデータベースに格納します。ユーザーがチャットなどでLLMに質問する際は、質問と関連性が高いチャンクをベクターストアから検索して、それを質問文と一緒にLLMに渡すことによって、LLMは自分が学習していない情報についても答えることができるようになります。
ちなみに、RAGについては、弊社代表の黒住が担当した以下のコラムにて、詳しく説明していますので、ご興味がある方はどうぞ!
生成AIのトレンド「LLM+RAG」を解説
GraphRAG
対して、GraphRAGは、文書を知識グラフと呼ばれる構造化されたデータに変換することによって、従来のRAGよりも、より精緻で文脈に即した応答を生成する点が特徴です。知識グラフとは、以下のようにエンティティを表すノードと、それらのエンティティ間の関係を表すエッジで構成されています。

知識グラフ
- Appleは果物(Fruit)の一種です。
- 果物は丸い(Rounded)形状で食用(Edible)です。
- Appleは緑(Green)、赤(Red)、黄色(Yellow)の色があります。
- Appleは果樹園(Orchards)で栽培されます。
- 主な栽培地として、アメリカ(USA)と中国(China)が挙げられています。
GraphRAGの実装チュートリアル
それでは、GraphRAGを使ってみましょう。今回のチュートリアルでは、Windows 11にインストールしたPython(3.12.2)にて、以下の公式ドキュメントの「Get Started」を参考に実施しています。
GraphRAG
https://microsoft.github.io/graphrag/
なお、手順の実施には、OpenAIのAPIキーが必要となりますので、あらかじめご準備をお願いします。
ライブラリのインストールとデータの入手
まずは、Pythonの仮想環境を準備します(Python自体のインストールは割愛させていただきます)。PS C:\python\graphrag> python -m venv venv
PS C:\python\graphrag> .\venv\Scripts\Activate.ps1
GraphRAGのライブラリをインストールします。
(venv) PS C:\python\graphrag> pip install graphrag
テストデータを格納するフォルダを作成します。
(venv) PS C:\python\graphrag> mkdir -p .\ragtest\input
テストデータを入手します。今回は青空文庫で提供されているコンテンツを利用したいと思います。事前に青空文庫からコンテンツをダウンロードして、作成したフォルダ(.\ragtest\input)に格納しておきます。
(venv) PS C:\python\graphrag> ls .\ragtest\input\
ディレクトリ: C:\python\graphrag\ragtest\input
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2024/09/18 13:27 1120767 wagahaiwa_nekodearu.txt
環境変数等の設定
以下コマンドを実行して環境変数を準備します。(venv) PS C:\python\graphrag> python -m graphrag.index --init --root .\ragtest\
.\ragtestフォルダに.envファイルが作成されます。ファイルを開いて、OpenAIのAPIキーを入力します。
■.env
# <API KEY>の部分を契約しているOpenAIのAPIキーに変更します。
GRAPHRAG_API_KEY=<API KEY>
OpenAIのAPIキー以外の設定は、settings.yamlに記載されています。
デフォルトだと使用するモデルがgpt-4-turbo-previewという古いモデルでしたので、最新のgpt-4oに変更します。
■settings.yaml
encoding_model: cl100k_base
skip_workflows: []
llm:
api_key: ${GRAPHRAG_API_KEY}
type: openai_chat # or azure_openai_chat
#model: gpt-4-turbo-preview
model: gpt-4o ## モデルをgpt-4oに変更
知識グラフの構築
以下のコマンドを実行して、知識グラフのインデックスを作成します。(venv) PS C:\python\graphrag> python -m graphrag.index --root .\ragtest\
なお、.\ragtest\inputに格納したコンテンツの文字コードがUTF-8でない場合は、以下のエラーが発生しますので、事前にUTF-8に変換する必要があります(今回使用した青空文庫の文字コードはShiftJISでした)。
× create_base_text_units
None
⠹ GraphRAG Indexer
├── Loading Input (InputFileType.text) - 1 files loaded (0 filtered)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 0:00:00
└── create_base_text_units
× Errors occurred during the pipeline run, see logs for more details.
処理が問題なく完了した場合は、以下のメッセージが表示されます。
All workflows completed successfully.
問合せの実行
それでは、構築した知識グラフに対して問合せをしてみましょう。問合せには、global searchとlocal searchの2種類があります。
global searchは、文書全体に対する整合性チェックなど、データ全体に対する理解が必要な場合に使用します。対して、local searchは、知識グラフの関連する部分と、生の文書のテキストの断片を組み合わせて回答を生成します。
こちらは、文書に記載された特定のエンティティの理解を必要とする質問に適しています。
今回は、夏目漱石の「吾輩は猫である」をサンプルデータとして使用していますので、以下の問い合わせをしてみます。
[問合せ] 吾輩とはなにものですか?
まずは比較のため、こちらの問いを通常のRAGに対して行ったところ、以下の回答を得ました。(RAGの仕組みはDifyを使っています)。
■通常のRAGの回答
「吾輩」とは、自己を指す言葉であり、特に日本文学でよく使われます。夏目漱石の「吾輩は猫である」の冒頭で使われていることが有名です。この場合、「吾輩」は猫自身を指しています。一般的には、古風な言い方で「私」や「自分」を意味します。
ホントにRAGを使ったのか分からない回答ですが(笑)、ログを確認したところ、「吾輩は猫である」の冒頭部分の「吾輩は猫である。名前はまだ無い。・・・」の部分を、きちんとRAGで参照していました。
物語の内容というよりは、吾輩という単語の一般的な意味について回答をしていますね。
次にGraphRAGのglobal searchを使って問合せしてみましょう。
(venv) PS C:\python\graphrag> python -m graphrag.query --root .\ragtest\ --
method global "吾輩とはなにものですか?"
回答は以下の通りです。通常のRAGとは違って、物語の内容を詳しく回答していますね。
■GraphRAG (global search)の回答
SUCCESS: Global Search Response:
### 吾輩の概要
吾輩(Wagahai)は、物語の中心的な語り手であり、観察者としての役割を果たす猫です。吾輩は、主人や他の登場人物との複雑な関 係を通じて、家庭内の動態や人間の行動についての洞察を提供します。吾輩の視点は、家庭内の出来事や社会的な規範、哲学的な問題に対する独自の見解を示しています [Data: Reports (217, 239, 212, 194, 81, +more)]。
### 吾輩の役割と関係
吾輩は、主人(主人)や他の登場人物(黒、Tatara-san、寒月第二世など)との相互作用を通じて、物語の進行に重要な役割を果たします。これらの相互作用は、家庭内の緊張や感情的なダイナミクスを反映しています。例えば、吾輩は最初はネズミを捕まえようとしましたが、後にそれをやめることを決意するなど、役割の変化が見られます [Data: Reports (239, 81, 79, 86, 218, +more)]。
### 吾輩の観察と哲学的洞察
吾輩は、人間の行動や環境条件についての観察を通じて、哲学的な問題や社会的な規範についても考察します。例えば、吾輩はエピクテトスの教えに対する疑問を投げかけたり、神の存在についての考察を行ったりします。これらの反映は、吾輩の学問的な傾向と世界を理解しようとする欲求を示しています [Data: Reports (239, 212, 207, 129, +more)]。
### 吾輩の家庭内での役割
吾輩は家庭内で重要な役割を果たし、子供たちを夜中に騒がせたり、妻君や迷亭との会話に登場したりします。これらの相互作用は、家庭内の動態に影響を与え、家族内の活動や関係性に新たな層を加えます [Data: Reports (218, 208, 261, 240, +more)]。
### 吾輩の社会的および文化的な関係
吾輩は、歴史的および文化的な人物との関係を持ち、単なる家庭内の猫以上の存在であることを示唆しています。例えば、吾輩は左甚五郎やスタンランといった文化的な人物と関連付けられています。これらの関係は、吾輩が文化的な物語の中で重要な役割を果たしていることを示しています [Data: Reports (129, 235, 245, 207, +more)]。
### 結論
吾輩は、物語の中心的な語り手であり、観察者としての役割を果たす猫です。家庭内の動態や人間の行動についての洞察を提供し、哲学的な問題や社会的な規範についても考察します。吾輩の視点は、物語の進行において重要な役割を果たし、家庭内および社会的な関係に新たな層を加えます。
local searchも試してみましょう。
(venv) PS C:\python\graphrag> python -m graphrag.query --root .\ragtest\ --
method local "吾輩とはなにものですか?"
回答は以下の通りです。こちらも物語の内容を詳しく回答しています。
global searchが「社会的および文化的な関係」も含めた広い視野で回答していることに対して、こちらは「吾輩の生活と日常」という風に、どちらかというと吾輩のキャラに主眼をおいて回答しているように見受けられます。
■GraphRAG (local search)の回答
SUCCESS: Local Search Response:
# 吾輩とはなにものですか?
吾輩 (Wagahai) は、物語の語り手であり、観察者としての役割を果たす猫です。彼は物語の中心的なキャラクターであり、主人 (Shujin) や他の登場人物との関係を通じて、物語の進行とともに多くの洞察を提供します。
## 吾輩の役割と視点
吾輩は、物語の中で非常に重要な役割を果たします。彼は主人の行動や思考、日常の習慣を詳細に観察し、コメントします。例えば、主人が風呂に行く様子や休息の必要性についても言及しています [Data: Relationships (78)]。吾輩の観察は、物語の進行において 重要な洞察を提供し、読者に対して登場人物の内面や関係性を深く理解させます。
## 吾輩と主人の関係
吾輩と主人の関係は複雑で、多面的です。吾輩は主人の膝の上に座り、彼の行動や習慣を観察しますが、時には主人から頭を叩かれることもあります。このように、吾輩と主人の関係は愛情と攻撃性が交錯するものです [Data: Relationships (78)]。吾輩はまた、主 人の日記を読み、彼の内面を探ることもあります。
## 吾輩の哲学的な視点
吾輩は単なる観察者にとどまらず、哲学的な視点から人間の行動や社会の規範についても考察します。彼は人間の行動や社会の規範について深く考え、時には批判的な視点を持ちます。例えば、吾輩は人間の利己的な愛の法則についても言及しています [Data: Sources (198)]。
## 吾輩の生活と日常
吾輩の生活は、主人の家での出来事や他の登場人物との関係を中心に展開されます。彼は台所で食べ物を探し、下女や他の猫たちとの関係も描かれています [Data: Sources (153, 286)]。吾輩の生活は、物語の中での彼の役割を強調し、読者に対して彼の視点から見 た世界を提供します。
## 吾輩の独自性
吾輩は、物語の中で独自の視点と声を持つキャラクターです。彼の観察とコメントは、物語の進行において重要な役割を果たし、読者に対して深い洞察を提供します。吾輩の視点は、物語の中での他のキャラクターとの関係や出来事を通じて、読者に対して新たな視点を提供します。
吾輩は、物語の中での観察者としての役割を果たし、読者に対して深い洞察を提供する重要なキャラクターです。彼の視点とコメントは、物語の進行において重要な役割を果たし、読者に対して新たな視点を提供します。
知識グラフの可視化
最後に、回答作成に使用された知識グラフがどのような構造なのか、可視化して確認しました(可視化にはNeo4jを使用)。主役である吾輩の周辺は、以下のようになっています。吾輩だけでも数多くのエンティティと関係があることが分かりますね。

知識グラフの可視化(吾輩周辺)

知識グラフの可視化(全体)
まとめ
同じ問い合わせを、従来のRAGとGraphRAGに対して行ってみましたが、GraphRAGは、登録した文書に対して、詳細な部分までを解析して回答していることが驚きでした。多くの方が、RAGの精度が上がらないと悩んでいると思いますが、GraphRAGを使用すると随分改善できるのではないかと思いました。
global searchとlocal searchのどちらを使うかですが、global searchは多くのトークンを使い、処理時間も長くなるので、local searchで精度が問題ない場合は、local searchを使った方がいいと思いました。
対して、global searchは、データ全体を理解しなければいけないような複雑なタスクに適していると感じました。
今回は、「Get Started」を中心に動かしてみましたが、その他にも、公式ドキュメントには、Pythonのプログラムから使用する方法や各種設定項目についての説明も記載されていますので、実際のプロダクト開発においては、それらを参照していくことになりそうです。
当サイトの内容、テキスト、画像等の転載・転記・使用する場合は問い合わせよりご連絡下さい。
エンジニアによるコラムやIDグループからのお知らせなどを
メルマガでお届けしています。