Title: Claudeに「オントロジー」を持たせたら、コスト半分・3倍速になるかも

URL Source: https://zenn.dev/takupeso/articles/claude-ontology-knowledge-structuring

Markdown Content: Komlock lab VPoE阿部(@takupeso)です。

ClaudeCodeに既存設計・コードに関するナレッジを渡すとき、僕はずっと同じやり方をしていました。@でファイルを指定し、CLAUDE.mdにルールを足し、.claudeを整備していました。

これももちろん有効な手法です。ただ、AIの調子でアウトプットの精度にブレが出ます。同じナレッジを渡しても、関連する事実をうまく結びつけてくれる日もあれば、そうでない日もあります。もっと安定して効く情報整理の手法はないのかな、と思っていました。

そこで「オントロジー」について調べてみました。情報整理の文脈でたまに聞くものの、正体も導入方法も曖昧なままだった概念です。

調べてわかったのは、ブレの原因が「量」ではなく「形」にあるということでした。@指定もMarkdownの箇条書きも、結局は資料をフラットに並べているだけ。Claudeは一枚ずつのファイルは読めても、概念どうしの関係は書いていないので、毎回そこを推測することになります。この推測のブレが、アウトプットのブレの一因でした。

資料を並べても精度が上がらない理由

@でのファイル指定、CLAUDE.mdの箇条書き、.claudeの整備。これらに共通するのは、情報を置いたり、ラベルを貼ったりする操作だということです。order-service.mdというファイルに仕様を書いて置く。CLAUDE.mdに「APIはsrc/api/配下」と書く。どれも、モノがどこにあって何という名前か、を決めています。

ところが、ここには概念どうしの関係が抜けがちです。order-service.mdpayment-service.mdに、注文と決済それぞれの仕様が丁寧に書いてあったとします。それでも、「この2つがどう連携しているか」までは書かれていないことが往々にあります。連携まで全部書くとキリがないからです。Claudeは両方のファイルを読めますが、繋がりが書かれていなければ、その場の推測任せになります。

足りないのは、次の一点です。

  • ある(できている): モノの保存、名前、分類、検索
  • ない(できていない): モノとモノの関係、その関係を辿ること

人間なら「注文サービスが決済サービスを呼んでいるなら、決済が落ちたとき注文も巻き込まれる」と自然に繋ぎます。これは頭の中に依存関係のネットワークがあるからです。フラットに並べた資料には、このネットワークが存在しません。

この「関係の構造」を明示的に持たせる方法が、オントロジーです。

オントロジーとは何か

オントロジーは情報科学の用語で、一言で言えばある領域の概念と、概念どうしの関係を明示的に定義したものです。この定義で広く知られるGruber(知識共有の研究者)は、オントロジーを「概念化の明示的な仕様」と表現しました。

堅い定義だけだと掴みにくいので、構成要素に分解します。オントロジーは次の5つでできています。

要素意味バックエンドでの例
クラス概念の型マイクロサービスという種類
インスタンスクラスの具体例注文サービス, 決済サービス
プロパティ要素が持つ属性決済サービスは外部APIに依存する
関係要素どうしの繋がり注文サービス決済サービスを呼び出す
制約成り立つ条件サービスはDBを直接共有しない

この中で、タグやフォルダと決定的に違うのが関係です。関係には種類があります。is-a(〜の一種)、part-of(〜の一部)、calls(〜を呼び出す)、depends-on(〜に依存する)など、どう繋がっているかを型として持てます。

注文サービスと決済サービスの依存関係を、グラフにしてみます。

ファイルを並べただけの状態と比べてみると、違いがはっきりします。フラットな資料は、点(ファイル)が散らばっているだけです。オントロジーは、点と点が型のついた線で繋がったグラフになります。

ここで「タグも複数貼れるし関係っぽいのでは」と思うかもしれません。タグは多次元のラベルにはなりますが、#order #paymentと並べても、2つがどういう関係かは表現できません。フォルダやタクソノミー(分類体系。生物の界・門・綱のように、モノを親子の階層に整理したもの。フォルダ構造もこの一種)も同じで、こちらは親子の縦方向だけ。「決済 > Stripe連携」とは言えても、「注文サービスは決済サービスを呼ぶ」という横の関係は持てません。

整理方法ごとに、関係の扱い方を見比べてみます。

整理方法構造関係の表現Claudeでの扱い
タグ/フォルダラベル・一軸の階層持たない関係はモデルが推測するしかない
タクソノミー親子の階層上位下位のみ縦の階層は辿れるが横の関係は推測
オントロジー多軸のネットワークis-a, calls, depends-on などを型で明示書かれた関係を推測せず辿れる

タグやフラットな資料とオントロジーの違いは、関係をモデルに推測させるか、あらかじめ確定させておくかです。

order-service.mdpayment-service.mdを別々に渡すと、Claudeは「たぶん呼び出し関係だろう」と推測します。当たることもあれば、外すこともあります。この推測のはずれが、幻覚(もっともらしい嘘)の一因です。オントロジーは「注文サービスは決済サービスをcallsする」と関係そのものを確定させておきます。だからモデルは推測せず、書かれた線を辿るだけで済みます。

「注文サービスは決済サービスを呼ぶ」「決済サービスはStripeに依存する」が書いてあれば、「注文サービスはStripeに依存する」まで取りこぼさず辿れます。答えがぶれません。

関係が精度を上げる仕組みとRAGとの違い

関係を持たせると、なぜClaudeの出力が安定するのか。

一番効くのは、幻覚の抑制です。関係を自由な文章ではなく、定義済みの型(is-apart-of)から選ぶ形にすると、Claudeはあり得ない関係を作りにくくなります。選択肢が絞られるぶん、もっともらしい嘘の余地が狭まります。

次に効くのが、渡す文脈の密度です。グラフ構造があると、あるエンティティから関係を1〜2ホップ(関係を1〜2回たどること)進むだけで、本当に関連する事実だけを集められます。ドキュメントを丸ごと渡してノイズに埋もれさせる代わりに、関連ノードだけを濃く渡せます。

もう一つ、多ホップの推論も通るようになります。「注文サービスは決済サービスを呼ぶ」「決済サービスはStripeに依存する」を辿れば、「注文サービスはStripeに依存する」までたどり着きます。関係が線で結ばれているから、複数ステップの問いにも答えられます。Stripeの障害が誰に響くかを、関係を辿るだけで割り出せます。

ここで気になるのが、RAG(外部データを検索してAIに渡す技術)との違いです。僕も最初は「ベクトル検索で関連文書を引けば十分では」と思っていました。でも、両者は引き方の原理が違います。

RAGは「意味の近さ」で文書の断片を引きます。依頼に関連する特定の情報を探し当てるのは得意ですが、文書をまたいだ関係や、複数ステップの推論は苦手です。チャンク(分割された断片)に切るので、関係の情報が分断されやすくなります。

オントロジーは「関係を辿る」検索です。エンティティ間の繋がりが明示されているので、横断的な問いや比較に強くなります。用途を表で見比べると、得意分野がきれいに分かれます。

質問のタイプRAG(ベクトル検索)オントロジー(グラフ)
単一の事実を引く得意ほどほど
複数文書をまたぐ集約苦手得意
エンティティの比較ほどほど得意
関係を辿る多ホップ推論苦手得意

この2つは敵対するものではなく、組み合わせると効きます。ベクトル検索で起点を見つけ、グラフで関係を辿ります。この合わせ技がGraphRAGと呼ばれる手法です。MicrosoftのGraphRAGの研究では、従来のベクトルRAGに比べて回答の包括性と多様性で優位という評価が報告されています。

すべてをオントロジーにする必要はありません。曖昧な検索はRAGに任せ、構造が効くところ(用語の関係、依存関係、設計の制約)にオントロジーを足します。この使い分けが現実解になりそうです。

Claude Codeでオントロジーを使うメリット

Claude Codeでオントロジーというと難しく聞こえますが、実体は単純です。コードベースの関係(どのファイルがどれを呼び、何に依存するか)を、エージェントが使える形のグラフにすることです。厳密な意味のオントロジー(型や制約をスキーマとして人が定義したもの)ではなく、コードの関係を表した依存グラフですが、「関係を明示してAIに渡す」という発想は同じです。

トークン消費が減る

一番分かりやすい効果です。関係グラフがあると、Claudeは関連ファイルを丸ごと読まずに、必要なシンボルと関係だけを辿れます。Aider(ターミナルで動くOSSのAIペアプログラミングCLI。コードベースの依存を地図化する「repo map」で知られる)は「実装の全体を見せる必要はない。使えるだけ理解できればいい」として、重要な識別子だけを渡す設計になっています。

削減幅の報告も大きいです。Claude Code に知識グラフを足してトークンを平均6.8倍(最大49倍)削減したというベンチマークや、コードグラフMCPで複数リポジトリ平均59%削減・ツール呼び出し70%削減という測定があります。数値はリポジトリと質問の種類で大きく振れますが、関連だけを濃く渡す方向に効くのは一貫しています。

幻覚(ハルシネーション)が減る

もう一つが幻覚の抑制です。前提として、コーディングエージェントは関連の薄い情報を大量に抱えるほど焦点がぼけて精度が落ちます。これはコンテキストの汚染と呼ばれ、マルチターンのタスクでは精度が40〜60%下がるという指摘もあります。

オントロジーは、この汚染を一定防げます。関係で絞った事実だけを渡せるので、無関係なファイルでClaudeを迷わせずに済むからです。関係が書いてあれば、Claudeは推測しなくて済みます。検証できるデータを辿るぶん、当て推量による幻覚が減る、という報告もあります。

Claude Codeにオントロジーを導入するべきライン

メリットがあるとはいえ、全員が入れるべきではありません。効く状況と、そうでない状況がはっきりしています。

効く状況

  • 大きい・多ファイルのコードベース。数百〜数千ファイルになると、関連を毎回探させるコストが大きく、グラフの索引が効きます。逆に小さいプロジェクトでは効果が小さく、ノイズになりがちです。
  • アーキテクチャや呼び出し階層をまたぐ問いが多い。「どこから呼ばれているか」「変更の影響範囲は」を頻繁に聞くなら、関係グラフの価値が出ます。
  • 長いマルチターンの作業やチームでの長期運用。会話が長引くほどコンテキストは汚れやすく、構造化した索引で精度を保てます。索引を共有すればチームのROIも上がります。

ハンズオン:コードベースからグラフを作り、トークン消費量が減るか確かめる

MCP(Anthropicが公開したオープン標準)の公式リファレンス実装にある memory サーバを触ってみましょう。entities(ノード)と relations(関係)、observations(事実)でできた、永続的なナレッジグラフをClaudeに足せます。流れは「導入 → コードからグラフを作る → グラフ有り/無しでトークンを比べる」の3ステップです。

1. 導入

claude mcp add --transport stdio memory -- npx -y @modelcontextprotocol/server-memory

このコマンドで memory サーバが Claude Code に登録され、以降は手元(ローカル)のサブプロセスとして起動します。--transport stdio はローカル実行を指す指定で、クラウドには繋がりません。グラフのデータも手元の memory.jsonl に保存されます。

2. コードベースからグラフを作る

Claudeにリポジトリを解析させ、構造をグラフとして記録させます。

このリポジトリの主要なモジュール・サービスと、その依存・呼び出し関係を調べて、
memory に entities(種類つき)と relations(呼ぶ・依存する など)として記録して。
各要素の役割は observations に短く添えて。

Claudeがコードを一度読み込み、create_entities / create_relations / add_observations を呼んで、ローカルの memory.jsonl にグラフを作ります。read_graph で中身を確認できます。

3. グラフ有り・無しでトークンを比べる

比較はセッションを分けて行います。同じ問いを別々のセッションで一度ずつ投げ、それぞれ /usage(そのセッションのトークン量)を見ます。同じセッションで続けて聞くと使用量が混ざるので、必ず別セッションにします。/context を使うと、何がコンテキストを食っているかも見えます。

使うのは、ふだんトークンを多く食う「広い問い」です。たとえばアーキテクチャ全体の把握。

セッション①(グラフを使わない)で聞きます。

memory は使わず、コードを読んで答えて。
このリポジトリのアーキテクチャを説明して。主要なモジュールと、その依存・呼び出し関係を整理して。

Claudeは多数のファイルを grep して読み込みます。答えが出たら /usage でトークン量を控えます。

セッション②(新しいセッションで、グラフを使う)で、同じことを聞きます。

memory のグラフを使って答えて。
このリポジトリのアーキテクチャを説明して。主要なモジュールと、その依存・呼び出し関係を整理して。

Claudeは search_nodesread_graph でグラフから答え、ファイルはほとんど開きません。2つの /usage を比べると、広い構造の問いほどグラフ側のトークンが少なくなります。

実際に手元のリポジトリで、同じ「アーキテクチャを説明して」を投げて比べてみました。

指標グラフなしグラフあり
コスト$1.26$0.62
API応答時間2分7秒44秒
キャッシュ読取トークン764.7k118.1k

入力プロンプトはほぼ同じなのに、コストは約半分、応答は約3倍速になりました。差を生んだのはキャッシュ読取(読み込んだコンテキスト量)で、764.7k から 118.1k へ激減しています。グラフがファイルの読み込みを肩代わりしたぶんです。これは1リポジトリでの一例なので、効果は規模と問いの種類で変わります。自分の /usage で確かめてみてください。

まとめ

オントロジーの正体、効果、使いどころを順にまとめます。

  • 正体: オントロジーは概念を関係で繋いだ構造。タグやフォルダが「並べる」だけなのに対し、関係を型として明示するので、モデルが推測せず辿れる
  • 効果: 関係があると幻覚が減り、関連事実を濃く渡せて、多ホップ推論が通る。曖昧な検索が得意なRAGとは効き方が違い、組み合わせると強い
  • Claude Codeでの使いどころ: 大きく複雑なコードベースで、関係を辿る問いが多いときに効く(トークン削減・幻覚抑制)

オントロジーは派手な技術ではありません。やっていることは「コードの関係を、Claudeが辿れる形で持たせる」だけです。効くかどうかは、コードベースの規模と問いの種類で変わります。ハンズオンを実施して、トークン消費量が明らかに減っているのであれば、レポジトリに導入を検討しても良さそうです。

参考リンク


원문: https://zenn.dev/takupeso/articles/claude-ontology-knowledge-structuring