Skip to content
Published on

ドキュメントから知識グラフへ — 正直な構築パイプライン

シェア
Authors

はじめに — デモは一回の呼び出し、プロダクションはパイプライン

「ドキュメントを入れれば知識グラフが出てくる」。デモではこれが LLM 呼び出し一回のように見えます。LangChain の LLMGraphTransformer や LlamaIndex の PropertyGraphIndex にドキュメントをいくつか入れれば、ノードとエッジが描かれた立派な絵が出てきます。実演は5分で終わります。

問題はその直後です。顧客の数万ページをクエリ可能なグラフに変える仕事 — Forward Deployed Engineer が実際にやること — は、一回の呼び出しではなく6段階のパイプラインです。そしてコストと苦痛の大半は、誰もが注目する段階(抽出)ではなく、誰もデモで見せない段階(エンティティ解決)にあります。

この記事はそのパイプラインを正直にたどります — どこにお金がかかり、どこで壊れるかまで。

ドキュメント
  │  (1) スキーマ / オントロジーが先 — ノード・エッジ型を決める
チャンク ──(2) 抽出──▶ 生のトリプル   ← チャンク数だけの LLM 呼び出し、見積もれる
  │        LLM ベース、スキーマ制約
(3) エンティティ解決   ← 同じエンティティ、無数の表記 · 本当に難しい所
  │   ブロッキング → スコアリング → クラスタリング(正規化)
(4) グラフストアへロード   (+ すべてのエッジに出典)
  ├─(5) 増分更新 & スキーマドリフト  ← 一度きりでは終わらない
  └─(6) 品質 / 評価   ← 精度(正しい?) · 再現率(漏れた?)

労力が実際に集中する所 (おおよその感覚):
  抽出          ~20%   (見えて、見積もれる)
  エンティティ解決 ~50%   (ロングテール、手作業)
  評価 + 出典     ~30%   (無ければ信用できないグラフを出す羽目に)

スキーマが先だ — オントロジー無しではノイズが積み上がるだけ

抽出から始めたい誘惑は強い。しかし何を抽出するか決めずに抽出すれば、結果はグラフではなくノイズの山です。同じ概念が 会社企業組織 とバラバラに出て、関係名は文ごとに変わります。こういうグラフは描けてもクエリはできません。

だから最初の段階はコードではなく決定です — どのノード型とエッジ型が存在するか。 それが即ちドメインオントロジーであり、なぜこれを先にやるべきかはドメイン知識をオントロジーにするで別途扱いました。ここで重要なのは、その決定がパイプライン全体を左右するという点です。次の段階の抽出器はこのスキーマを制約として受け取り、スキーマに無いものは出しません。スキーマがグラフの文法になります。

抽出 — 従来型 NER か、LLM か

第二段階はテキストからエンティティと関係を実際に取り出すことです。大きく見れば二つの系譜があります。

従来型は固有表現抽出(NER)と関係抽出(relation extraction)をパイプラインでつなぎます。成熟していて、安く、大量処理に強い。代償も明確です — ドメインごとにラベル付き学習データが新たに要り、エンティティ認識段階の誤りが関係抽出へ伝播し(パイプラインの持病)、文をまたぐ文脈を捉えにくい。

LLM ベースの抽出は反対側のトレードオフです。ラベル無しでゼロショット/フューショットから始め、文脈を保ったまま結果をスキーマにマッピングします。代わりに二つの新しい問題が生じます — ハルシネーション(存在しない関係をでっち上げる)と表記のばらつき(同じものを毎回違う名で呼ぶ)。前者は後の第4段階を、後者は第3段階を難しくします。

実務ツール三つを見るとトレードオフが手に取れます。

  • LangChain LLMGraphTransformer convert_to_graph_documents がドキュメントをノードと関係に変えます。allowed_nodesallowed_relationships で型を制約でき(どちらも既定は空リスト = すべて許可)、allowed_relationships(始点型, 関係, 終点型) のタプルまで受け取ります。まだ experimental モジュールで、モデルによっては空の結果を返すこともあります。
  • LlamaIndex の抽出器。 同じ仕事を三通りで提供します。SimpleLLMPathExtractor はスキーマ無しで自由に抽出し "may produce a larger number of diverse relationships" だが "might lack consistency in entity and relation naming"。SchemaLLMPathExtractor は事前定義スキーマで "produces a more structured graph" だが "might miss a lot of relationships that don't fit the predefined schema"。DynamicLLMPathExtractor はその中間 — 初期スキーマの案内を受けつつ必要なら拡張し "a balance between diversity and consistency" を狙います。トレードオフがクラス名として化石化しているわけです。
  • Microsoft GraphRAG。 テキスト単位ごとにエンティティと関係を抽出してそれぞれに説明を付け、同じエンティティの複数の説明を "coherent, non-redundant descriptions" にまとめます。

コストは見積もれます。抽出は本質的にチャンク数だけの LLM 呼び出しです。コーパスに対して線形に増え、バッチで回せて、キャッシュが効きます。パイプラインで最も御しやすい段階です。難しい所は別にあります。

エンティティ解決 — 本当に難しい所

抽出が終わるとトリプルが数十万でき、その相当部分が同じものを指す別の名前です。田中太郎太郎 田中Tanaka, T. が一人かもしれないし、そうでないかもしれない。これを整理する仕事がエンティティ解決(entity resolution)であり、知識グラフ構築で品質が分かれる地点です。

定石は三段階です。

  1. ブロッキング(blocking)。 候補を絞ります。全エンティティ対を比較するとコストが n² で爆発するため(エンティティ10万なら比較は100億対)、埋め込みベースの近似最近傍探索などで「まだしも似ているもの」だけを同じブロックに集めます。現場の格言どおり、ブロッキングはマッチングより重要です — ここで取りこぼした対は後で決して出会えません。
  2. スコアリング(scoring)。 ブロック内の対に類似度を付けます — 文字列類似、関係的近接、埋め込み、行動シグナルなど。
  3. クラスタリング/正規化(canonicalization)。 スコアを根拠に同一エンティティをまとめ、各まとまりを一つの正規ノードにします。

失敗モードは対称に二方向です。

  • 過剰マージ(over-merge)。 別人の二人の 田中太郎 を一つのノードに合わせてしまう。もうグラフが嘘をつきます — 一人の経歴に二人分の事実が混ざる。静かに起きるので、危険です。
  • 過少マージ(under-merge)。 IBM CorpInternational Business MachinesIBM Corporation を三つのノードのままにする。クエリは三つのうち一つだけ当てて、残り三分の二を取りこぼします。

埋め込みはここで大いに助けになります。密ベクトルは文字列が重ならなくても意味でつなぎます — 上の IBM の三表記を "without a single explicit rule" 一つにまとめられます。しかし埋め込みだけでは足りません。ルールベースも純粋な LLM も、ウェブスケールでは単独では持ちません。実戦のエンティティ解決はブロッキング + 類似マッチング + 確率/ML 分類 + 全体整合性の検証の組み合わせです。

ここで正直になるべき点が一つ。多くのツールはこの段階を代行してくれません。 例えば GraphRAG の既定パイプラインは名前が完全に一致するメンションを合わせて説明を要約するだけで、IBM CorpIBM Corporation をつなぎはしません。本当のエンティティ解決はあなたの仕事です。FDE が顧客プロジェクトで最も時間を費やすのが、まさにここです。

グラフストアへロード — そしてすべてのエッジに出典を

解決済みのトリプルはグラフストアへ入ります。プロパティグラフ(Neo4j など)ならノード・エッジに属性を付け、RDF ならトリプルストアに入れて SPARQL でクエリします。選択はチームのツール生態系とクエリパターンが決めます。

ロードで絶対に省いてはいけないのが**プロヴェナンス(provenance)**です。すべてのエッジは「どの文書、どのチャンクから出たか」を一緒に運ぶべきです。GraphRAG が文書メタデータを保存し、各文書をそこから生成されたテキスト単位に紐づけるのもこのためです。出典の付いたグラフは監査でき、引用でき、間違ったときにどこを直すか分かります。出典の無いグラフは、もっともらしい主張の山にすぎません。そしてこの出典は後でグラフ RAGが回答に根拠を付ける材料になります。

増分更新とスキーマドリフト — 一度きりでは終わらない

顧客のドキュメントは止まっていません。新しい契約書が来て、組織図が変わり、製品が増えます。グラフもそれに合わせて変わらねばなりません。

全量再構築は簡単ですが高い。だから増分更新が要ります。GraphRAG 1.0 の update コマンドは "computes the deltas between an existing index and newly added content and intelligently merges the updates to minimize re-indexing" — つまり新しい内容だけを反映しようとします。ただし正直な脚注があります。新しい内容がコミュニティ構造そのものを揺らすと相当部分を再計算する必要があり、最悪の場合は全量再インデックスに近づきます。せめてもの救いは、LLM キャッシュが再実行のコストを大きく下げることです。

より厄介なのがスキーマドリフトです。第1段階で凍結したオントロジーは、時が経つと現実とずれます。新しいエンティティ型や関係が現れ、スキーマ制約の抽出器はそれらを静かに取りこぼします。だからスキーマは立てて忘れるものではなく、ガバナンスを要する生きた資産です。構築はイベントではなく運用です。

品質と証拠 — 評価できないものは出すな

「グラフが良さそう」は評価ではありません。構築した知識グラフはトリプルの水準で測れるし、測るべきです。

基本の軸は四つ — 正確性(accuracy)、網羅性(completeness)、整合性(consistency)、冗長性(redundancy)。実務でまず測るのは前の二つです。精度(precision)で正しさを — 抽出したトリプルのうち正しいものの割合 — 測り、再現率(recall)で網羅性を — あるべきトリプルのうち拾えたものの割合 — 測ります。ゴールドサンプルを手で作ってエッジ単位で照合するのが最も正直な出発点で、リンク予測ベースの指標のようにゴールド無しで自動的に品質を測る方法もあります。

そして評価と信頼の接点に、再びプロヴェナンスがあります。各値に出典スパンを付けておけば(attribution)、ハルシネーションを濾せる — 根拠を示せないトリプルは疑えばよい — と同時に、エンドユーザーが答えを検証できます。評価パイプラインとプロヴェナンスは後付けの飾りではなく、グラフを信頼できるものにする唯一の方法です。

正直なコスト — どこで壊れるか

まとめると、コストはこう分布します。

  • 抽出はチャンク数に線形です。見えて、予算が立ち、キャッシュが効く。最も易しい段階です。
  • エンティティ解決はロングテールです。80%は自動化されますが、残り20%がドメイン知識と手作業を要求し、品質の大半がここで決まります。
  • コミュニティ要約(GraphRAG 系)はスケールが大きくなると抽出並み、時にそれ以上に高い。すべてのコミュニティごとに LLM レポートを生成するからです。
  • 増分更新はタダではなく、最悪の場合は全量再構築に退化します。

デモが見せるのは一行目だけです。残りはデモに出ないので見積もりから漏れ、だからプロジェクトが遅れます。

おわりに

FDE のレンズで見れば、ドキュメントをグラフに変える仕事はおおよそ 20% が抽出で、80% が解決・評価・プロヴェナンス・運用です。実行(抽出)は安くなりつつあり — LLM が代わりにやってくれます — 価値が残るのは判断です。何をノードと見なすか決めるスキーマ、同じものを同じと判定する解決ルール、間違いを証明できる評価。これらは今日のモデルが代わりに決めてくれる軸ではありません。

一文だけ残すなら、これです。スキーマを先に、証拠を常に。 グラフは目的ではなく手段であり、その手段が何のためか — 検索と回答 — はグラフ RAGで、そしてこのパイプラインを実際に回す道具は知識グラフのツール地形で続けます。

参考資料