Claude CodeのLumenプラグインでコード探索のトークンを減らす — ローカル意味検索の入れ方
LumenはコードをローカルのOllamaで埋め込み、MCPのsemantic_searchでClaude Codeに返すプラグインです。入れ方、対応言語、索引の置き場所、公開ベンチマークの読み方を説明します。
Lumenは、コードベースをローカルで意味検索できるようにするClaude Codeのプラグインです。提供元はOry Corpで、Claude Codeのマーケットプレイスには「Precise local semantic code search via MCP」という説明で載っています。クラウドもnpmも使いません。
仕組みは単純です。プロジェクトを関数や型の単位に切り、手元のOllamaかLM Studioで埋め込み、SQLiteに保存します。Claude Codeが何かを調べるとき、ファイルを丸ごと読む代わりにsemantic_searchというMCPツールを呼べるようになります。
この記事では、導入手順、入る中身、索引の置き場所と除外の指定、公開されているベンチマークの読み方、つまずきやすい点を順に説明します。
Lumenは何を足すプラグインか
マーケットプレイスのページによれば、Lumenは「Go ASTの解析でコードベースを索引化し、OllamaまたはLM Studioで埋め込み、MCPサーバー経由でClaudeにベクトル検索を渡す」ものです。ページにはインストール数651と提供元Oryの表記があります。
README側の整理では、主な特徴は次のとおりです。
Lumenが足す機能
意味ベースの検索
キーワードの一致ではなく意味で、関連する関数・型・モジュールを探します。
自動索引化
セッション開始時に索引し、変更のあったファイルだけをMerkleツリーの差分で処理し直します。
12の言語群
Go、Python、TypeScript、JavaScript、Svelte、Rust、Ruby、Java、PHP、C/C++、C#、Dartに対応します。
Gitワークツリー対応
ワークツリーは索引データを共有し、新しいワークツリーは兄弟の索引から種をもらって差分だけ再索引します。
データを外に出さない
埋め込みは手元のマシンに残り、ネットワークの外へデータは出ません。
「トークンを減らす」という狙いは、リポジトリの説明文にある「Claude Codeなどで30%のトークンコストを減らす」という主張に由来します。ただし、これは提供元の主張です。どの条件でどれだけ下がったかは、後述のベンチマークの節で数字と条件を分けて読みます。
入れる前に用意するもの
前提は2つです。
- Ollamaが入っていて起動していること
- Claude Code、Cursor、Codex、OpenCodeのいずれか
既定の埋め込みモデルはordis/jina-embeddings-v2-base-codeで、先にpullしておきます。
ollama pull ordis/jina-embeddings-v2-base-codeLM Studioを使う場合の既定モデルはnomic-ai/nomic-embed-code-GGUFです。対応OSはLinux、macOS、Windowsで、バックグラウンドの索引化の排他制御にはUnixでflock(2)、WindowsでLockFileExが使われます。
Claude Codeへの入れ方
マーケットプレイスを追加してからプラグインを入れます。Claude Codeのセッション内で実行します。
/plugin marketplace add ory/claude-plugins
/plugin install lumen@ory入れたあとは、新しいセッションを始めて/lumen:doctorを実行すると状態を確認できます。プラグインの入れ方そのものは、同じ形で配布されている他のプラグインと変わりません。例としてAikidoプラグインの記事も参照できます。
最初のセッション開始時にLumenが行うことは3つです。
- GitHubの最新リリースからバイナリを自動でダウンロードする
- Merkleツリーによる変更検出で、プロジェクトをバックグラウンドで索引化する
- ホストが自動で使える
semantic_searchというMCPツールを登録する
つまり、バイナリを手でビルドする必要はありません。ソースから試したい場合だけ、リポジトリをcloneしてmake plugin-devでClaude Codeのプラグインとして読み込めます。ビルドにはsqlite-vecのためにCGOが必要です。
同梱のMCPツールとskill
プラグインが公開するのは、MCPツール3つとskill 2つです。
| 種類 | 名前 | 役割 |
|---|---|---|
| MCPツール | 名前semantic_search | 役割意味でコードを検索する |
| MCPツール | 名前health_check | 役割埋め込みバックエンドとの接続などを確かめる |
| MCPツール | 名前index_status | 役割索引の状態を返す |
| skill | 名前/lumen:doctor | 役割健全性チェック |
| skill | 名前/lumen:reindex | 役割強制的な再索引 |
health_checkの役割は、READMEのトラブルシューティングが「Cursor・Codex・OpenCodeではdoctorのskillを使うか、health_checkとindex_statusを直接呼ぶ」と書いていることから、doctorに対応する診断用のツールと読めます。個別の戻り値までは、READMEにありません。
index_statusについては、プロジェクト内のファイル数とチャンク数に加えて、索引全体の一意なベクトル数、共有参照、重複排除率、ベクトルの精度、DBサイズ、回収可能なSQLiteページを報告すると説明されています。
検索はどう進むのか
READMEが示す流れは次のとおりです。
ファイルから検索結果まで
- 1
ファイルを意味の塊に切る
関数・型・メソッドの単位に分けます。GoはネイティブのAST、ほかの言語はtree-sitterの文法を使います。
- 2
埋め込みを作る
チャンクをOllamaまたはLM Studioでベクトルにします。ファイルごとの内容が変わっていなければ、やり直しません。
- 3
SQLiteに保存する
SQLiteとsqlite-vecに入れ、コサイン距離のKNNで引きます。
- 4
Claudeが検索を呼ぶ
コードを理解したいとき、Claudeはファイルを丸ごと読む代わりに
semantic_searchを呼びます。
ここで大事なのは「検索はファイルの代わりに候補を絞る」だけという点です。絞った箇所の中身を読む工程は、これまでどおりClaude Codeの通常のファイル読み取りが担います。Lumenが減らそうとしているのは、探すための読み込みです。
索引はどこに置かれ、何が対象になるか
索引の置き場所
索引はプロジェクトの外、~/.local/share/lumen/<hash>/index.dbに置かれます。リポジトリにファイルは追加されません。<hash>はGitの共通ディレクトリ(Gitでないプロジェクトは絶対パス)、索引の範囲、埋め込みモデルと次元数、ベクトル精度、チャンク分割の方針、索引のバージョンから決まります。
そのため、モデルを切り替えるとモデルごとに別の索引ができ、衝突しません。古い索引は自動では消えないので、容量を戻したいときはlumen cleanを使います。
lumen clean # 30日使われていない索引、またはプロジェクトが消えた索引を削除
lumen clean --days 7 # 基準を1週間に狭める
lumen clean --days 0 # 実行中の索引を除き、削除できる索引をすべて消す索引は開くたび(検索・索引化・状態確認・セッション開始)に「使われた」と数えられるため、日常的に触っているプロジェクトの索引は消えません。
何が索引されるか
索引に入るファイルは、複数の層を順に通ったものだけです。
- 組み込みの除外(
node_modules、vendor、dist、.venv、target、.next、testdataなどのディレクトリと、package-lock.jsonやCargo.lockなどのロックファイル) .gitignore.lumenignore.gitattributesのlinguist-generated指定- 対応する拡張子
.lumenignoreは.gitignoreと同じ書式で、プロジェクトのルートかサブディレクトリに置きます。.gitignoreには載っていないが検索のノイズになるファイル、たとえば生成されたprotobuf、テストのスナップショット、同梱された外部データを外すために使います。
# .lumenignore の例(.gitignoreと同じ書式)
*.pb.go
**/__snapshots__/
third_party/data/上の3行は書式を示す例で、READMEにある設定そのものではありません。
設定は環境変数で行う
設定はすべて環境変数です。
| 変数 | 既定値 | 内容 |
|---|---|---|
LUMEN_EMBED_MODEL | 既定値ordis/jina-embeddings-v2-base-code(Ollama) | 内容埋め込みモデル |
LUMEN_BACKEND | 既定値ollama | 内容ollamaまたはlmstudio |
OLLAMA_HOST | 既定値http://localhost:11434 | 内容OllamaサーバーのURL |
LM_STUDIO_HOST | 既定値http://localhost:1234 | 内容LM StudioのURL |
LUMEN_MAX_CHUNK_TOKENS | 既定値512 | 内容分割前の1チャンクの最大トークン数 |
LUMEN_VECTOR_STORAGE | 既定値int8 | 内容ベクトル精度(int8またはfloat32) |
LUMEN_EMBED_DIMS | 既定値なし | 内容次元数の上書き。登録外のモデルでは必須 |
LUMEN_EMBED_CTX | 既定値8192(登録外のモデル) | 内容コンテキスト長の上書き |
LUMEN_EMBED_MODELの既定値はバックエンドごとに違い、LM Studioではnomic-ai/nomic-embed-code-GGUFになります。
モデルの選び方
READMEは、登録済みモデルに推奨度を付けています。
| モデル | バックエンド | 次元数 | 位置づけ |
|---|---|---|---|
ordis/jina-embeddings-v2-base-code | バックエンドOllama | 次元数768 | 位置づけ既定。コストが最も低く、取りすぎない |
qwen3-embedding:8b | バックエンドOllama | 次元数4096 | 位置づけ品質は最良だが、索引化が非常に遅い |
nomic-ai/nomic-embed-code-GGUF | バックエンドLM Studio | 次元数3584 | 位置づけ使えるが、TypeScriptで取りすぎてコストが上がる |
qwen3-embedding:4b | バックエンドOllama | 次元数2560 | 位置づけ非推奨。コストが最も高い |
nomic-embed-text、qwen3-embedding:0.6b、all-minilmは「Untested」です。推奨度の高い既定モデルから試し、Untestedのモデルは動作や効果の裏づけがないため比較の対象外と考えるのが無難です。
登録されていないモデルを使うときは、LUMEN_EMBED_DIMSを必ず指定します。READMEの例は次のとおりです。
LUMEN_BACKEND=lmstudio
LM_STUDIO_HOST=http://localhost:8801
LUMEN_EMBED_MODEL=mlx-community/Qwen3-Embedding-8B-4bit-DWQ
LUMEN_EMBED_DIMS=4096
LUMEN_EMBED_CTX=40960 # 省略可。既定は8192複数のサーバーをconfig.yamlに定義している場合、lumen indexとlumen searchは--model/-mと--backend/-bで使うサーバーを選べます。同じモデル名を2つのバックエンドに設定すると索引が共有されてしまう点がREADMEに注意として書かれており、バックエンドごとにモデル名を分ける必要があります。
公開ベンチマークをどう読むか
READMEのベンチマークは、実在のGitHub issueを使ったSWE-bench形式の課題で、Lumenあり・なしを比べたものです。測っているのはコスト、時間、出力トークン、パッチの質で、生のJSONLやパッチの差分、判定の根拠もリポジトリに置かれているとされています。
9言語・難度「hard」の結果は、次のとおりです(埋め込みモデルは既定のOllama構成)。
| 言語 | コスト | 時間 | 出力トークン | 品質 |
|---|---|---|---|---|
| Rust | コスト-39% | 時間-34% | 出力トークン-31%(18K→12K) | 品質両方とも低い |
| JavaScript | コスト-33% | 時間-53% | 出力トークン-66%(14K→5K) | 品質両方とも完全 |
| TypeScript | コスト-27% | 時間-33% | 出力トークン-64%(5K→1.8K) | 品質両方とも良好 |
| PHP | コスト-27% | 時間-34% | 出力トークン-59%(1.9K→0.8K) | 品質両方とも良好 |
| Svelte | コスト-26% | 時間-31% | 出力トークン-26%(4.0K→3.0K) | 品質両方とも低い |
| Ruby | コスト-24% | 時間-11% | 出力トークン-9%(6.1K→5.6K) | 品質両方とも良好 |
| Python | コスト-20% | 時間-29% | 出力トークン-36%(1.7K→1.1K) | 品質両方とも完全 |
| Go | コスト-12% | 時間-9% | 出力トークン-10%(11K→10K) | 品質両方とも良好 |
| C++ | コスト-8% | 時間-3% | 出力トークン+42%(機能追加の課題) | 品質両方とも良好 |
読むときの注意点は3つです。
- コストの削減幅は言語によって8%から39%まで開いています。「30%減る」は平均的な見込みではなく、リポジトリの説明文にある宣伝上の数字です。
- 列は「出力トークン」で、入力側のトークンではありません。減るのは主にClaudeが生成する量とコストです。
- C++は出力トークンが42%増えています。READMEはこれを機能追加の課題だったためとしています。
READMEは「質はすべての課題で維持され、退行はゼロ」と述べています。RustとSvelteは、Lumenあり・なしのどちらでも課題が難しすぎて質が低かった例で、そこでも失敗のコストは26〜39%下がったとされています。これは提供元が自分で用意した課題での結果です。自分のリポジトリで同じ傾向になるかは、少数の質問で前後を比べて確かめるのが確実です。
プラグインがセッションに常駐させる固定のコンテキスト量は、claude plugin detailsの記事の手順で測れます。検索で減る量と、プラグイン自体が足す量を並べて見ると、手元での損得が分かります。
つまずいたときの切り分け
READMEのトラブルシューティングから、実際に起きそうなものを選びます。
Lumenが動かないときの順番
- QOllamaは起動していて、モデルをpullしてあるか?答えがいいえのとき答えがはい
ollama serveで起動し、ollama pull ordis/jina-embeddings-v2-base-codeを実行します。「connection refused」が出る典型的な原因です。 - Q`/lumen:doctor`は正常を返すか?答えがいいえのとき答えがはい
接続先やモデル名を環境変数で見直します。Cursor・Codex・OpenCodeでは、doctorのskillか
health_checkとindex_statusを直接呼びます。 - Q大きなリファクタのあとに結果が古いままか?答えがいいえのとき答えがはい
Claude Codeでは
/lumen:reindexで強制的に再索引します。CLIならlumen index --force .です。
それでも遅いとき
最初の索引化は全ファイルを埋め込むため、10万行を超えるプロジェクトでは数分かかることがあります。これは初回だけの費用で、以降は変更分だけが処理されます。
LM Studioを使う場合には、固有の落とし穴もあります。LM Studioは埋め込みモデルをGGUFのarchフィールドの許可リスト(bert、nomic-bert)で分類するため、nomic-embed-codeのようなQwen2系のモデルは「Embeddings」でなく「LLMs」に分類されます。GGUFでv0.3.16以降なら、My Modelsの歯車アイコンから「Override Domain Type」を「Text Embedding」にして直せます。Apple SiliconではMLX形式が大幅に速い一方、LM Studioはv0.3.30以降でMLXのドメイン種別の上書きを削除しました。そのためGGUF版を使うか、Ollama側のモデルに切り替えるのが回避策です。
入れる前の判断材料
Lumenは「コードを意味で引く」道具なので、効き方には向き不向きがあります。公式のページとREADMEから言える範囲を表にします。
| 状況 | 見立て |
|---|---|
| JavaScript・TypeScript・PHPが中心 | 見立て公開ベンチマークで出力トークンの減りが大きい(59〜66%) |
| Go・Rubyが中心 | 見立てコストは下がるが、トークンの減りは小さい(9〜10%) |
| ソースを外部に出せない | 見立て埋め込みが手元で完結するので、方針上は合わせやすい |
| 小さなリポジトリで探索が短い | 見立て小規模から大規模まで使えるとREADMEは説明している。削減幅は課題次第 |
| Javaが中心 | 見立て対応言語だが、ベンチマークの表では「Supported」止まり |
Dart(コスト-76%、トークン-82%、時間-79%)の数字は、言語の表には載っていますが、上の9言語の表には入っていません。同じREADME内でも集計の範囲が表ごとに違うため、数字は表の見出しとセットで読む必要があります。
同じマーケットプレイスでも、差分を外部サービスに送ってレビューを受けるQodoプラグインは、データを手元に残すLumenとは対照的です。
まとめ
Lumenが減らしたいのは、答えにたどり着くまでの探索コストです。導入は2コマンド、前提はOllamaと埋め込みモデルのpull、確認は/lumen:doctorで足ります。
数字を使うときは、提供元の「30%」を目標値と受け取らず、言語ごとに8%から39%まで幅がある公開結果として読みます。自分のリポジトリでは、同じ質問を入れる前と入れた後で投げ、トークンの内訳を見比べるのが確実です。索引は~/.local/share/lumen/にあるので、試して合わなければプラグインを外し、lumen clean --days 0で容量も戻せます。