0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

graphifyがApple Siliconで全滅した — x86_64 tree-sitterの罠と、コード+ドキュメントを丸ごと知識グラフ化するまでの実録

0
Posted at

この記事は Zenn に投稿したものの転載です。

Claude Codeが毎回ファイルを読み直す問題

Claude Codeで大きめのプロジェクトを触っていると、毎セッション同じことが起きる。「あのファイルどこだっけ」でgrep、全文Read、また別のファイルをRead……。コードベースはgrepには大きすぎ、コンテキストに丸ごと積むには高すぎる。

これを解くのが graphify(PyPIパッケージ名はgraphifyyで yを2つ重ねる/CLIコマンドはgraphify)。フォルダを丸ごと知識グラフにして、Claudeがファイルを読み直す代わりにグラフを引く。公称「クエリあたり最大71.5xのトークン削減」。

知識グラフとは何かを一言で。コードとドキュメントを解析して「関数・クラス・概念=ノード」「呼ぶ・依存する・参照する=有向エッジ」の有向グラフとして抽出したもの。質問すると、全文を読み直す代わりに関連ノードだけを部分グラフで返す。だから軽い。graphifyはコードをtree-sitterでローカルAST解析(LLM不使用)し、ドキュメントだけをモデルで意味抽出する。

M1 Max(Apple Silicon)で、自分のプロジェクト——シェルのオーケストレーション群、Swiftのメニューバーアプリ、設計ドキュメント——を丸ごとグラフ化しようとした。そしていきなり全滅した。この記事はその実録。

トラブルシューティング

全滅:incompatible architecture

uv tool install graphifyy で入れて、AST抽出を走らせた瞬間これが出た。

ImportError: dlopen(.../tree_sitter/_binding.cpython-313-darwin.so, 0x0002):
  tried: '.../tree_sitter/_binding.cpython-313-darwin.so'
  (mach-o file, but is an incompatible architecture
   (have 'x86_64', need 'arm64e' or 'arm64'))

tree_sitter のネイティブバインディング(.so)が x86_64 で、arm64のPythonがロードできない。graphifyはコードをtree-sitterでAST解析するので、ここが死ぬとコード抽出が全滅する。

Apple Siliconあるあるだが、厄介なのは「graphify自体が抱えていたx86_64依存」だったこと。自分のコードでもモデルでもなく、ツールのネイティブ依存がx86_64前提でインストールされていた。原因はシンプルで、arm64のPythonがx86_64の.soをdlopenできずに落ちている。uv toolの解決時にx86_64ホイールを掴んでいた。

修正①:tree-sitterをarm64で入れ直す

uv tool環境にはpipが無いので、uv pipでその環境を指定して強制再インストールする。

PY=/Users/you/.local/share/uv/tools/graphifyy/bin/python
uv pip install --python "$PY" --reinstall-package tree-sitter --no-cache 'tree-sitter>=0.23.0'

tree-sitter 0.26.0(arm64)が入り、dlopenの悲鳴は止まった。……が、まだAST結果は0ノードだった。

修正②:言語grammarが「そもそも」入っていなかった

再試行で今度はこう出た。

warning: 32 .swift file(s) contributed nothing to the graph
  because a dependency is missing: tree_sitter_swift not installed.

tree-sitterのコアは直ったが、各言語のgrammartree_sitter_swift等)が別パッケージで、未導入だった。ここで一気に入れる。特に tree-sitter-bash を入れると、シェルスクリプトのオーケストレーション群もAST解析できるようになる——これが自分の環境では本命だった。

uv pip install --python "$PY" --no-cache \
  tree-sitter-bash tree-sitter-swift tree-sitter-python \
  tree-sitter-typescript tree-sitter-javascript tree-sitter-json tree-sitter-go

7言語すべてimportOK。このtree-sitter-bash導入が効いて、それまで0ノードだったシェル13本+Swift32本が解析対象になった。 再々試行:

Swift AST: 323 nodes, 759 edges

動いた。 archを直し、grammarを入れる——この2段で復活する。片方だけだと0ノードで沈黙するので、両方必須。全体の流れはこう。

全滅から復活へ — Apple Siliconのgraphify、2段の修正(archエラー→arm64再インストール→まだ0ノード→言語grammar導入→0から332ノードへ)

段階 状態
初期 dlopen incompatible architecture で全滅
修正①後(arm64 tree-sitter) archエラーは消えるが 0ノード
修正②後(言語grammar導入) 332ノード / 653エッジ

コードグラフ構築:bash+Swiftを1グラフに

コード → 332ノード

まずコード資産をASTで(LLM不使用・完全無料)。シェルのオーケストレーション13本(GPU調停・ディスパッチャ・監視系など)+Swiftアプリ32本=45本を1グラフに。

Graph: 332 nodes, 653 edges, 23 communities
God node: 中核ViewModel   ← アプリの中枢を正しく検出

ここでベストプラクティスをひとつ。testは除外、infra/docsは含める。 testはノードを3-4倍に膨らませてクラスタリングを濁す(graphifyの公式ガイドでも指摘される経験則)。逆にインフラ設定やドキュメントは「システムがどう配線されているか(何が何に依存するか)」を教えてくれる。

+ドキュメント → 629ノード

次に、CLAUDE.mdや設計ドキュメント60本をsemantic抽出(並列サブエージェント)でグラフに足した。結果:

ENRICHED Graph: 629 nodes, 986 edges, 76 communities

コード構造と設計知識が1つのグラフに同居した。構築の流れを図にするとこう。

コード+ドキュメント → 1つの知識グラフ → 副産物(コード45本はローカルAST・無料、設計doc60本はsemantic抽出。629ノード/986エッジのグラフから graph.html・Obsidian・Wiki・MCPサーバ・graphify query が全部出る)

実際に引いてみる

「GPU調停まわりは何と繋がってる?」を聞くと、BFSでこう返る(識別子は汎用名にしてある。形式は実出力のまま)。

$ graphify query "gpu arbitration freeze thaw"
Traversal: BFS depth=2 | Start: [GpuMonitor] | 13 nodes found

NODE GpuMonitor       [src=app/services/gpu_monitor.swift  L9   community=8]
NODE MemSwitchScript  [src=scripts/mem_switch.sh           L1   community=29]
NODE thaw_ollama()    [src=scripts/mem_switch.sh           L38  community=29]
NODE LocalLLMRuntime  [src=docs/env_snapshot.md            —    community=6]

EDGE GpuMonitor      --shares_data_with--> CoreViewModel   [INFERRED  0.85]
EDGE MemSwitchScript --references-->       LocalLLMRuntime [EXTRACTED 1.0]
EDGE thaw_ollama()   --calls-->            LocalLLMRuntime [EXTRACTED 1.0]

Swiftの型(コード)、シェルのスクリプトと関数(コード)、設計メモの「ローカルLLM基盤」(ドキュメント)が1つの答えに混ざって出てくるshares_data_with(INFERRED 0.85)やreferences(EXTRACTED 1.0)のように、関係の種類と確信度まで付く。「実装」と「なぜ・どこに繋がるか」を一度に返す——これがコードとドキュメントを同居させた効果だ。graphify explain "<ノード>"ならType / Community / Degreeと接続先一覧を平易に出してくれる。

性能計測:約215xのトークン削減

graphify benchmarkの実測がこれ。

Corpus:          31,450 words → ~41,933 tokens (naive)
Graph:           629 nodes, 986 edges
Avg query cost:  ~195 tokens

表にするとこう。

方式 1回のコスト 倍率
コーパス丸ごと積む(naive) ~41,933 tokens 1x
graphify query ~195 tokens 約215x削減

(コーパス 31,450 words / グラフ 629ノード・986エッジ/graphify benchmark実測)

数字は2つある。公称「最大71.5x」はgraphify公式のベンチ値この自分のコーパスでの自測値は約215xgraphify benchmarkの出力)。コーパスの内容と質問で変わる——構造・依存を尋ねる質問ほど効き、編集そのものやグラフ外のファイルには効かない。ただ「毎回コードベースを積み直す税」が桁で消えるのは共通だ。

副産物も全部おいしい

graphifyは1回のビルドで大量の成果物を吐く。全部使うと効く。

  • HTMLgraph.html):ブラウザで開く対話グラフ。サーバ不要。
  • Obsidian vault:1ノード1mdの双方向リンク。「第二の脳」化。
  • Wiki:コミュニティ別の記事。エージェントがwiki/index.mdから辿る。
  • MCPサーバpython -m graphify.serve graph.jsonget_node/get_neighbors/shortest_pathをツール露出。エージェントがグラフをライブ照会できる(要mcpパッケージ)。
  • 常時ON統合graphify claude installでCLAUDE.mdにルールとPreToolUseフックが入り、以後は明示/graphifyなしでコードベースの質問前に自動でグラフを参照する。

生成されるObsidianノートは1ノード=1メモで、frontmatterと[[…]]のbacklinkが付く(識別子は汎用名)。まずGpuMonitorのノート:

---
source_file: "app/services/gpu_monitor.swift"
type: "code"
community: "Community 8"
---
# GpuMonitor
## Connections
- [[CoreViewModel]] - `shares_data_with`
- [[MemSwitchScript]] - `conceptually_related_to`

繋がった先のCoreViewModelノートを開くと、逆向きのリンクが自動で張られている(双方向):

---
source_file: "app/models/core_view_model.swift"
type: "code"
community: "Community 1"
---
# CoreViewModel
## Connections
- [[GpuMonitor]] - `shares_data_with`
- [[MetricsProbe]] - `calls`
- [[SessionProbe]] - `calls`

Obsidianのグラフビューで開けば、この双方向リンクがそのままノード網になり、コードを1行も読まずに「どのモジュールが何と繋がるか」を辿れる。

教訓(Apple Siliconでgraphifyを動かす人へ)

  1. archエラーは2段で直すtree-sitter本体をarm64で再インストール → 言語grammar(tree-sitter-bash/swift/…)を導入。片方だけだと0ノードで沈黙する。
  2. bash grammarを入れる:シェル中心のオーケストレーションこそグラフ化の価値が高い。
  3. testは切り、infra/docsは入れる:グラフの主役はクラスタの純度と「配線」。
  4. docのsemanticはモデルAPIを使う:コードはローカルAST(無料)、doc/画像はモデル呼び出しでトークンを食う。コスト意識するならスコープを絞る(画像はvisionで特に高い=依存グラフには不要なので除外が正解)。

archの罠を抜ければ、graphifyはApple Siliconで完全に動く。そして一度グラフにすると、AIが「プロジェクト全体の文脈を持った状態」で動き始める——速度だけの話ではない、というのが一番の収穫だった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?