pathfinderのパス解決とMCP検証
Rust製pathfinderを約4,000ファイルでfilesystem MCPと比較し、contextを約10,000 tokens減らしました。LLM導入の開発支援向けに、ColBERTのパス候補検索と未解決2件を示します。
作成したツールと結果
ローカル LLM の tool_call で、誤ったパスから実在パスを探す pathfinder を Rust で作りました。32B以下のモデルで、typo、拡張子違い、階層の省略などを繰り返したためです。
MCP 側で候補を絞り、ColBERT(Late Interaction)で再順位付けします。INT8 は16MB、CPU-only、10ms未満で、GPU VRAM は使いません。
約4,000ファイルのモノレポで filesystem MCP と比較しました。精度は僅差で、context 消費は約10,000 tokens少なくなりました。list_directory の祖先チェックによる O(n) の出力を、候補の絞り込みで減らしています。
ModernBERT 推論を Rust に実装し、複数プロジェクトを検索する CLI も作りました。LLM導入の開発支援に加え、手元のコードを探す用途です。

ローカルモデルのパス失敗
手元では Claude / GPT-4より、7B〜32Bのローカルモデルでパスの失敗が多く見られました。
確認した失敗の例です。
| 失敗パターン | 例 |
|---|---|
| ディレクトリ名の typo | src/componets/Button.tsx → components |
| 拡張子の取り違え | config.yaml → 実際は config.yml |
| 階層の省略 | utils/helper.go → 実際は internal/pkg/utils/helper.go |
| 類似ファイル名の混同 | auth/login.ts vs auth/login.test.ts |
エラーと再試行で context が増えます。ツール側で解決し、再試行の回数と入力を減らす狙いです。
正確なパスを使う指示だけでは解消しなかったため、ツールで補う方針にしました。parameter 数だけを原因として切り分けた検証ではありません。
アーキテクチャ
stdin/stdout の JSON-RPC 2.0で、Claude Code / Zed Editor などと通信する Rust 製 MCP です。
三段階のパス解決
パスを3段階で絞り込みます。
- レキシカルスコアリング — 内部実装は非公開です。1ms未満です
- 履歴の相関 — 直近の結果を ring buffer に残し、作業に近い候補を優先します
- ColBERT再順位付け — 上位候補を MaxSim で並べ直します。約5–8msです
レキシカルスコアが十分高ければニューラル再順位付けを省きます。多くのクエリは1ms未満で返ります。
ColBERT モデル
ColBERT(Late Interaction)を再順位付けに使います。
| 項目 | 値 |
|---|---|
| モデル | lateon-code-edge(コード特化)/ mxbai-edge-colbert(汎用) |
| パラメータ数 | 約 17M |
| 量子化 | INT8(ONNX Runtime) |
| モデルサイズ | 約 16MB |
| 埋め込み次元 | 128 |
| 推論 | CPU のみ(GPU 不要) |
ONNX Runtime と HuggingFace Tokenizers を使い、Python には依存しません。
MCP ツール
主なツールです。
path_resolve— 失敗したパスから実在パスの候補を返します。intent_text(「Go config loader」などの短い目的記述)で候補を絞りますtool_retry_with_resolve— パスを解決し、元の操作(read_file、list_dir 等)を自動リトライしますcandidate_list— 上位候補をリストで返す。曖昧なケースのブラウジング用roots_list/reindex_paths/server_version— 管理系ツール
read_file の ENOENT後に tool_retry_with_resolve を使うと、パス解決と操作の再試行を1回の tool_callで行えます。
パス解決の実例
ディレクトリ名を間違えた例です。
path_resolve:
check_path: "content/ja/docs/tech/infrastrcture/podman-quadlet-systemd-ubuntu.md"
^^^^^^^^^^^ typo
→ resolved: "content/ja/docs/tech/infrastructure/podman-quadlet-systemd-ubuntu.md"
$ pathfinder --help
pathfinder — semantic path finder & MCP resolution server
USAGE
pathfinder [OPTIONS] Interactive semantic directory finder (default).
pathfinder --mcp [OPTIONS] Start as an MCP server.
FINDER OPTIONS
--include-builds Include build/artifact dirs (target, dist, …).
MCP OPTIONS
--root <PATH> Add a project root directory to watch and index.
May be specified multiple times. Defaults to $PWD.
GENERAL OPTIONS
-h, --help Print this help message and exit.
-V, --version Print version, model, and PCA config to stderr and exit.
MCP TOOLS
1. path_resolve Resolve a failed file path to the best match.
2. tool_retry_with_resolve Resolve + retry the operation in one call.
3. roots_list Return configured root directories.
4. reindex_paths Force a full index rebuild.
ENVIRONMENT VARIABLES
PF_MCP_INFERENCE Inference mode: "general" (default) or "code".
Models (both INT8 quantized):
general → mxbai-edge-colbert (17M, 48-dim)
code → lateon-code-edge (17M, 48-dim)
CLIでのプロジェクト検索
同じ ColBERT 推論を使う対話 CLIです。domain / infra / presentation を含む複数プロジェクトを検索します。
操作体系
pf(コード特化)または pfg(汎用)で検索画面を開きます。
- vim キーバインド で候補リストをナビゲート
- ディレクトリ階層をたどり、最深部でファイル一覧を表示します
- 右キー(→) で選択ファイルを
lessで開く - 結果を選択すると、そのディレクトリに
cdします
pf # コード特化モード(lateon-code-edge)
pfg # 汎用モード(mxbai-edge-colbert)
ModernBERT の Rust 実装で、体感ではほぼ即時に検索結果が返りました。

ベンチマーク: filesystem MCP との比較
約4,000ファイルのサンプルで filesystem MCP と比べました。
パス解決精度
単体の精度テストは70ケース、12カテゴリです。
| カテゴリ | 内容 | 結果 |
|---|---|---|
| 正しいパス | そのまま返る | 8/8 |
| ディレクトリ typo | componets → components | 10/10 |
| ファイル名 typo | 文字の入れ替え・欠落 | 10/10 |
| 拡張子の取り違え | .yaml → .yml | 7/7 |
| 階層の省略 | 中間ディレクトリが欠落 | 5/5 |
| intent ベースクエリ | 目的記述からの推定 | 4/5 |
| リトライ操作 | resolve + retry の一体動作 | 3/3 |
| 紛らわしいパスペア | 類似名ファイルの区別 | 6/6 |
| 深いネスト | 8 階層以上 | 4/4 |
| 言語横断クエリ | 「Go の設定ファイル」等 | 4/6 |
| テスト/設定ファイル | test, config の区別 | 4/4 |
| 合計 | 67/70 (95.7%) |
コンテキスト消費量
精度差は僅差でしたが、context 消費は約10,000 tokens少なくなりました。
filesystem MCP の祖先確認は、list_directory の出力がファイル数とともに増えます。今回の4,000ファイルを超える規模は未検証です。
pathfinder は候補を絞って返します。8K〜32Kの window で不要な context を減らすための方式です。
リソースフットプリント
| 項目 | 値 |
|---|---|
| バイナリサイズ | シングルバイナリ(Rust) |
| モデルサイズ | 約 16MB(INT8) |
| メモリオーバーヘッド | 50MB 未満 |
| GPU VRAM 消費 | ゼロ |
| 典型的レイテンシ | 10ms 未満(レキシカルのみなら 1ms 未満) |
GPU を使わないため、vLLM / llama.cpp の VRAM に追加の領域は必要ありません。CPU 資源は使います。
注意事項
- レキシカルスコアリングは非公開です。ctree とともに自社の OSS LLM pipeline で使っています
- 70ケースのうち、intent_text で言語を指定する2件が未解決です
- 数万ファイルの規模は未検証です
- モデルのコード特化 / 汎用は
PF_MCP_INFERENCEで切り替えます - MCP 2024-11-05に対応し、Claude Code / Zed Editor などから使えます
