13
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vibe Coding のトークン消費量の40-60%を占めることもある、Markdownファイルの読み込みトークン消費量を最大98%以上圧縮する markdown-query スキル

13
Posted at

背景

私は、ソフトウェアエンジニアリングの 設計書をほぼ Markdown で作成しています
業務要件、ユースケース一覧、サービス記述書、API 仕様、ADR、ナレッジベース。気づけば、社内外で扱うドキュメントの大半が Markdown になっていました。
さらに、最近は GitHub Copilot や Claude Code の出力結果そのものも Markdown で返ってきます。つまり、インプットもアウトプットも Markdown という状況が、現場では当たり前になりつつあります。

そうなると、次に困るのが「この大量の Markdown を、どうやって AI エージェントに効率よく読ませるか」です。

Vibe Coding でエージェントに「この仕様に従って実装して」と頼むとき、関連 Markdown を全部 read_file させると、Context Window があっという間に埋まります。
正直、最初は「context window が大きくなったから大丈夫だろう」と思っていたのですが、実務で重めのセッションを回すと、思ったより早く窮屈になるんですよね。

この実感から、Markdown の効果的な検索と読み取りに特化したスキル markdown-query を作って公開しました。

この記事では、その背景にある Token 消費の話と、スキルの中身、セットアップ、GitHub Copilot からの使い方、ベンチマークの読み方までをまとめておきます。


注意点 / 前提

最初に断っておきます。

  • これはあくまで 私個人の見解 であり、所属する組織の公式見解ではありません
  • 数値(後述の Token 配分・削減率)は ツール・モデル・タスク・リポジトリの内容 によって大きくブレます
  • プロダクション運用や、組織標準としてそのまま採用することは想定していません
  • 紹介するスキルも「銀の弾丸」ではなく、特定の状況で効く道具として捉えてください
  • ベンチマークの数値は、私のリポジトリ・私の環境で測ったものです。同じ結果は保証できません

万能ではありません。ここを踏まえた上で読んでいただけると助かります。


整理:そもそも Context Window は何で埋まるのか

「Token が足りない」と言うとき、私たちは何を消費しているのか。
ここで一度、整理してみます。

context window の中身は、ざっくり次の5つに分けられます。

  • System / Tools / MCP / instructions
  • 会話履歴
  • ファイル読込
  • コマンド出力・ログ
  • 空き・buffer

つまり、AI に送っているのはユーザーの質問だけではなく、ツール定義・指示書・履歴・読み込んだファイル・実行ログまで全部含んだものです。
ここを誤解していると、「自分はそんなに長く話していないのに、なぜ context が圧迫されるのか」が分からなくなります。

問題は「会話量」ではなく、累積した周辺情報 だ、というのがポイントです。


本文:Vibe Coding における Token 消費のざっくり感

200k tokens の context window を前提にすると、重めの開発セッションは大体こんな配分になりがちです。

構成要素 軽い状態 重い状態
System / Tools / MCP / instructions 10〜20% 25〜35%
会話履歴 10〜25% 40〜70%
ファイル読込 10〜30% 40〜60%
コマンド出力・ログ 5〜15% 20〜40%
空き・buffer 20〜60% 0〜20%

正直、最初にこの内訳を見たとき「ファイル読込と会話履歴だけで大半が食われるのか」と少し驚きました。
ただ、考えてみれば当然で、AI エージェントはファイルを読むたびに、その内容をまるごと context に積んでいきます。grepcat の出力も同じです。

GitHub Copilot CLI は約 80% 到達で background compaction を開始し、95% 近くまで埋まると compaction の完了待ちが発生する挙動が説明されています。実務上の目安は 80% を超える前に整理する こと、です。

実務での影響としては、

  • セッション後半になるほど、修正提案がブレる
  • 過去に決めた前提を AI が忘れて、同じ議論を繰り返す
  • compaction 待ちで、体感のレスポンスが落ちる

このあたりが、地味にストレスとして効いてきます。
だからこそ、ファイル読込のところを賢くする のが、現場で一番効く節約ポイントだと感じています。


markdown-query スキルとは

markdown-query は、リポジトリ内の Markdown 群(仕様書、設計書、ナレッジ、README など)を ローカル完結で横断検索 し、ヒットした 見出し単位の小さなチャンク(snippet)だけ をエージェントに返すスキルです。

特徴

  • 独自のインデックスを持つ.mdq/index.sqlite にチャンク・メタデータを保存し、増分更新可能
  • 日本語の Tokenizer を使っている — 日本語の Markdown でも実用的にヒットする
  • 完全にオフラインで動作する — 外部 API(埋め込み、ベクトル検索サービス等)を一切呼びません
  • BM25 / grep / タグ・パス絞り込み に対応
  • 見出し階層の俯瞰 や、チャンク ID 指定での本文取得 もできる

クラウド埋め込みやリモートベクトル DB を使わないので、社内のクローズドな設計書群でも安心して使えます。
逆に、Markdown の編集・生成はしません。読み取り専用 の道具です。

何が嬉しいのか(Why)

  • 「全文を read_file させる」 → 数万トークン消費、関係ない章まで読まれる
  • markdown-query 経由 → 該当チャンク数百〜千トークン程度に圧縮されて投入される

実測値は後述しますが、特定条件下で 97% 以上の Token 削減 が出ることもあります。もちろん、これは「特定条件下」の話です。


スキルパッケージに含まれるもの

スキル本体だけでなく、CLI とベンチマークツールが同梱されています。

パス 内容
skills/markdown-query/SKILL.md スキル本体。エージェントが読み込むトリガー定義と手順
skills/markdown-query/references/cli-reference.md mdq CLI の全サブコマンド・全オプション仕様
skills/markdown-query/references/query-patterns.md よくあるクエリ例
skills/markdown-query/references/indexing-internals.md 索引のデータモデルとチャンク分割ルール
skills/markdown-query/examples/prompt-snippets.md Copilot Chat / Custom Agent 向けプロンプト例
mdq/ スキルが内部で呼び出す Python 製 CLI 本体
setup/setup-markdown-query.{ps1,sh} mdq.venv にインストールするスクリプト
tools/markdown-query/ Context 削減効果を数値で確認するベンチマーク CLI

セットアップ手順

前提条件

  • Git CLI
  • Python 3.11 以上(mdq CLI の動作要件)
  • 利用するエージェント CLI(copilot / claude / gemini / apm のいずれか)

1. スキルのインストール

GitHub Copilot CLI を例にすると、対話セッション内で次を実行します(初回のみマーケットプレイス追加)。

/plugin marketplace add dahatake/skills
/plugin install dahatake-skills@dahatake-skills

Claude Code、Gemini CLI、APM 経由のインストール手順は README を参照してください。

2. mdq CLI のインストール(必須)

スキルは内部で mdq CLI を呼び出します。プラグインを入れただけでは動きません
リポジトリをクローンしたうえで、OS に応じてセットアップスクリプトを実行します。

Windows (PowerShell)

git clone https://github.com/dahatake/skills.git
cd skills
./setup/setup-markdown-query.ps1

macOS / Linux (bash)

git clone https://github.com/dahatake/skills.git
cd skills
chmod +x ./setup/setup-markdown-query.sh
./setup/setup-markdown-query.sh

スクリプトはリポジトリルートに .venv を作り、その中に mdq をインストールします。
-WithWatch / --with-watch を付けると、ファイル変更を監視する mdq watch 用の watchdog も入ります。


使い方 — GitHub Copilot から

ここからが本題です。
普段の Vibe Coding に組み込むときの流れを、順番に書いていきます。

1. インデックスの作成(初回・必須)

このスキルを使う前に、必ず 1 回実行してください。検索対象のリポジトリのルートで実行します。

mdq index
  • 既定でカレントディレクトリを再帰走査し、.md / .markdown を索引化
  • 既定で .git / node_modules / .venv などは除外
  • .gitignore は既定で尊重
  • .mdq/ 自体を .gitignore に追加することを推奨

2. インデックスの更新

ファイルを追加・編集した後は、もう一度 mdq index を実行するだけです。SHA-1 + mtime で増分更新されるので、変わっていないファイルは再処理しません。

ファイル変更を逐次反映したい場合は、別ターミナルで watch モードを起動できます。

mdq watch

3. GitHub Copilot からの呼び出し例

インデックス作成後、Copilot Chat や Copilot CLI に、こんな感じで依頼します。

このリポジトリ配下の Markdown から「会員 同意管理」に関する設計を探して、要点だけ教えて。

docs/** 配下の Markdown から "context window" を含む見出しを横断的に拾って。引用元の path:lines も付けて。

業務要件とユースケース一覧を踏まえて、ロイヤルティポイント付与のサービス記述書の該当箇所だけを抜粋して。

スキルが起動すると、内部で mdq search が呼ばれ、ヒットした見出し単位のチャンクだけが Context に積まれます。
全文を読ませる場合と比べて、Context Window への影響が桁で変わります。

4. 手動で mdq を叩いてみる(動作確認)

エージェントに任せる前に、自分で叩いて感触を掴むのもおすすめです。

mdq search --q "会員 同意管理" --top-k 5 --max-tokens 800

主なオプション:

オプション 説明
--q 検索クエリ(必須)
--top-k 返すヒット数(既定 5、推奨 3〜5)
--max-tokens 出力の最大トークン数(既定 800、推奨 400〜800)
--paths 検索対象パスを絞り込み(例: "docs/**"
--tags frontmatter のタグで絞り込み
--mode bm25(既定) / grep
--snippet-radius ヒット行前後の表示行数(既定 ±2)

出力は JSONL(1 行 = 1 ヒット)です。気になるチャンクがあれば、chunk_id を指定して本文取得できます。

mdq get --chunk-id <ID>

ベンチマーク:本当に Token を節約できているか

「いい感じです」だけだと信用できないので、自分のリポジトリで数値確認するためのベンチマーク CLI を同梱しています。

何を測るのか

同一クエリ集合に対し、3 つのシナリオを比較します。

シナリオ Context に投入する内容 想定する使い方
baseline_full 索引対象配下の 全 Markdown 本文 スキルを使わない場合の上限値
mdq_bm25 mdq search --mode bm25 のヒットのみ 既定の検索モード
mdq_grep mdq search --mode grep のヒットのみ 厳密一致モード

各シナリオで 応答トークン数 / 検索 wall-clock / ベースライン比削減率 / coverage(任意) を計測します。

実行手順

  1. インデックス作成(未作成なら --ensure-index で自動作成可)

    mdq index
    
  2. 計測したいクエリを 1 行 1 件で書いたファイルを用意(サンプル: tools/markdown-query/queries.sample.txt

  3. ベンチマーク実行

    python tools/markdown-query/benchmark.py \
      --queries-file tools/markdown-query/queries.sample.txt \
      --top-k 5 --max-tokens 800 --repeat 3 --ensure-index
    
  4. 結果は tools/markdown-query/results/bench-<UTCタイムスタンプ>.{json,md} に出力されます。

レポートの読み解き方

bench-*.md には、次のセクションが順に並びます。

  1. Environment — トークナイザ、Python・OS・コミットハッシュ。他環境と絶対比較するときは必ずここを確認
  2. Parameters--top-k --max-tokens --repeat などの実行条件
  3. Index summary--ensure-index 時の索引作成所要時間
  4. baseline_full — 全文投入時の files / chars / tokens。これが 削減率の分母
  5. Skill なし vs Skill あり (プロンプトトークン比較) — シナリオごとに次を表示
    • avg_response_tokens — クエリ平均の応答トークン数(小さいほど節約)
    • avg_vs_baseline_savings_pct — 削減率(例: 98.5% なら全文比 1.5% に圧縮)
    • latency_ms_all — 全クエリ × --repeatmean / p50 / p95 / min / max
    • per_query[] — クエリごとの hits 数、トークン、削減率、coverage_proxy

実行例(参考値)

リポジトリ同梱の sample/ 配下(業務要件・ユースケース・サービス記述書 4 ファイル)に対して、5 クエリで実行した結果です。

あくまで「例」です。ユーザーの環境で同じ結果や精度を保証するものではありません

測定環境: tiktoken/cl100k_base / Python 3.12.10 / Windows 11 / top_k=5, max_tokens=800, repeat=3

baseline_full: 4 files / 83,230 chars / 68,440 tokens

シナリオ avg tokens (with skill) avg savings vs baseline latency mean / p50 / p95 (ms)
mdq_bm25 1,794.6 97.38% 13.35 / 13.65 / 14.20
mdq_grep 700.6 98.98% 1.45 / 0.47 / 3.33

クエリ別(mdq_bm25、抜粋):

query hits tokens savings %
ロイヤルティプログラム 5 2,484 96.37
生成AI パーソナライズ 5 1,816 97.35
ポイント付与 失効 5 1,250 98.17
会員 同意管理 5 1,402 97.95
ユースケース 5 2,021 97.05

この例では、全文投入の 約 1〜3% までプロンプトトークンが圧縮されました。
一方で mdq_grep は語の表記揺れに弱く、ヒットしないクエリも出ます(savings % = 100 は「ヒットなし」を意味するので、別途 coverage_proxy で精度を確認する必要があります)。

削減率だけで判断しない、というのが大事なところです。期待パスを紐付けた JSON で coverage まで見るのが、現実的な評価方法だと思います。


リポジトリ構成

README.md                           プロジェクトの README
LICENSE                             MIT ライセンス
plugin.json                         プラグイン定義(Copilot CLI / 共通)
apm.yml                             APM マーケットプレイス定義
.claude-plugin/marketplace.json     Claude Code / Copilot CLI 用マーケットプレイス
.claude-plugin/plugin.json          Claude Code 用プラグイン定義
gemini-extension.json               Gemini CLI 拡張定義
setup/                              スキル別の追加 CLI インストールスクリプト
  setup-markdown-query.ps1
  setup-markdown-query.sh
skills/                             スキル本体
  markdown-query/
    SKILL.md
    examples/prompt-snippets.md
    references/
      cli-reference.md
      query-patterns.md
      indexing-internals.md
mdq/                                Python 製 CLI 本体
tools/markdown-query/               ベンチマーク CLI と結果
  benchmark.py
  queries.sample.txt
  results/
sample/                             デモ用の Markdown 群

plugin.json(ルート)と .claude-plugin/plugin.json は内容を重複させているため、片方を更新するときはもう片方も同期する必要があります。apm.yml.claude-plugin/marketplace.json も同様です。


ここまでの整理

一度、箇条書きでまとめておきます。

良い点

  • Markdown の設計書を AI エージェントに渡すときの Token 消費を、桁単位で減らせる可能性がある
  • 完全オフライン動作なので、社内クローズドな設計書群でも使える
  • 日本語 Tokenizer 対応で、日本語 Markdown でも実用的にヒットする
  • path:lines での引用元明示ができる

注意点

  • スキル本体だけでなく mdq CLI のセットアップが必要(プラグインを入れただけでは動かない)
  • インデックスは事前作成・更新が必要(セッション間で共有されない前提)
  • grep モードは表記揺れに弱い

限界

  • 読み取り専用(Markdown を編集・生成する用途には使えない)
  • 埋め込みベースの意味検索は行わない
  • ベンチマークの数値は環境依存。回答品質まで保証するものではない

まとめ

設計書もアウトプットも Markdown、という現場は今後ますます増えると思います。
そのとき、ファイル読込まわりの Token 消費 をどう設計するかは、Vibe Coding の体験を左右する地味だけど大事なポイントです。

markdown-query は万能ではありません。
ただ、

  • 普段から Markdown で設計書を書いている
  • 既に Markdown 化されたファイルが沢山ある
  • Copilot の出力結果(Markdown)も含めて、エージェントに横断的に参照させたい

こういう状況であれば、効果が出やすい場面が多いと感じています。

まずは自分のリポジトリでインデックスを作って、benchmark.py を一度回してみる。
そこで出てきた数字を見て、自分の現場での落としどころを決める のが、現実的な向き合い方だと思います。

万能な解はありません。
ただ、Context Window を「有限のリソース」として扱う癖をつけるだけで、AI との付き合い方は確実に変わってきます。
まずはここまでで、現場で試してみる価値はあると思います。

13
20
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
13
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?