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?

背景

ざっくり言うと「コードの関係(どれがどれを呼ぶ・依存する)を型付きのグラフにしてエージェントに渡すと、ファイルを grep しまくらずに済んでトークンが減るよ」という話。
元記事は Claude Code の話だけど、GitHub Copilot でも効くやろってことでお試し

オントロジーって何?
情報科学の用語で、ある領域の「概念」と「概念どうしの関係」を明示的に定義したもの。タグやフォルダは"並べる"だけだけど、オントロジーは depends-on(依存する)・implements(実装する)・calls(呼ぶ)みたいに関係を型として持てるのが違い。AI に渡すと「たぶん呼び出し関係だろう」という推測が減る。
有名なパランティアさんがこれを使って大儲け :laughing:

概要

  • モノレポ(Python のクリーンアーキテクチャ構成)に、コミット型の docs/architecture/ontology.md を1枚作った。中身はモジュール/インターフェース/実装の型付き関係depends-on / implements / calls)。

  • copilot-instructions.md に「構造・依存・影響範囲の問いはまずこれを読む」を1行足した。

  • GitHub Copilot CLI + OpenTelemetry(ファイル出力) で実トークン取得

  • 同じ「アーキテクチャ説明して」を オントロジー有り/無し同一モデルで投げた結果:

指標 無し(実ソース探索) 有り(オントロジー) 削減
input tokens(Σ) 364,614 67,609 −81.5%
in+out 合計 369,242 68,800 −81.4%
ツール実行回数 29 2 −93%
LLM 実時間 91.9s 25.2s −72.6%(約3.6倍速)

用途によっては効くので、入れておいてもいいかなって気はした。

問題は、ontology.md の更新を CI で行うかどうかってところだね

詳細

1. なぜ Copilot でも効くか

だって、エージェントだから :sweat_smile:

仕組みはシンプル。「アーキテクチャ全体を説明して」みたいな広い問いを投げると、エージェントは関連ファイルを片っ端から grep して read する。これが大量のトークンを食う。

オントロジーは、その「広く浅く読む」作業を1枚のグラフで肩代わりする。点(ファイル)がバラバラに散らばっている代わりに、点と点が型のついた線で結ばれているので、関係を辿るだけで答えが出る。

2. オントロジーを書く(最小フォーマット)

厳密な RDF/OWL は要らない。Markdown にエンティティと関係を書くだけで推測は減る。

ポイントは2つ。

  • 関係をdepends-on / implements / calls / produces)で書く。自由文にしない。
  • 正本はソースコード。関係を変えたら同じ PR でこのファイルも直す、と決めておきたい。

ってことで、deepwiki-open とか、copilot cli なんかで、定期的に構造化をさせるのがよさげ。

3. instructions から参照させる

書いただけだと読んでくれない。copilot-instructions.md に1行入れて、広い問いでは先にグラフを読むよう仕向ける。

> 構造・依存・影響範囲の問いはまず docs/architecture/ontology.md を読む。
> モジュール/Protocol/実装の型付き関係がまとまっており、
> 広い問いでファイルを grep する前に参照するとトークンを節約できる。

4. Copilot での計測

ダメだった方法

  • セッション履歴 DB(VS Code の Copilot ローカル index)→ turns テーブルはユーザー発話と応答のテキストだけ。token 列が無い。
  • デバッグログmain.jsonl)→ trace span のみで、トークン使用量は記録されていない。

chatからは出来そうになかったので・・

GitHub Copilot CLI + OpenTelemetry

そして決め手が OpenTelemetry のファイルエクスポータ。環境変数 COPILOT_OTEL_FILE_EXPORTER_PATH を渡すと、トークン数・ツール呼び出し・コスト・所要時間を JSONL でローカル出力してくれる(コレクタ不要・オフライン)。

レシピ(A/B 実行)

公平性のため、両方とも 同一の問い同一モデル--no-custom-instructions(instructions のオントロジー誘導を無効化)で揃える。

$core = "このリポジトリのアーキテクチャを説明して。主要モジュールと依存・呼び出し関係を整理して。"

# Arm A: オントロジー無し(実ソース探索)
$env:COPILOT_OTEL_FILE_EXPORTER_PATH = "$PWD\otel-A.jsonl"
copilot -p "$core ただし docs/architecture/ontology.md は読まず実ソースを調べて答えること。" `
  --allow-all-tools --allow-all-paths --no-custom-instructions --no-color

# Arm B: オントロジーのみ
$env:COPILOT_OTEL_FILE_EXPORTER_PATH = "$PWD\otel-B.jsonl"
copilot -p "$core docs/architecture/ontology.md だけを根拠に答えること。" `
  --allow-all-tools --allow-all-paths --no-custom-instructions --no-color

--allow-all-tools はツール承認をスキップして自動実行する(公式も Security considerations で注意喚起)。信頼できるディレクトリでだけ使うこと。計測用途なので read 中心の問いにしている。

パース(フラット JSON に注意)

このCLIの OTel ファイルは 1行1span のフラット JSON(よくある resourceSpans 入れ子ではない)。attributes 直下にトークンが入っている。

{
  "type": "span",
  "name": "chat claude-sonnet-4.6",
  "attributes": {
    "gen_ai.request.model": "claude-sonnet-4.6",
    "gen_ai.usage.input_tokens": 21092,
    "gen_ai.usage.output_tokens": 109,
    "gen_ai.usage.cache_read.input_tokens": 21089,
  },
}

なので chat span を拾って gen_ai.usage.input_tokens / output_tokens を合算するだけ。PowerShell ならこんな感じ。

$in=0;$out=0;$chat=0
foreach ($l in Get-Content .\otel-A.jsonl) {
  $o = $l | ConvertFrom-Json
  if ($o.type -ne 'span' -or $o.name -notlike 'chat*') { continue }
  $chat++
  $in  += [double]$o.attributes.'gen_ai.usage.input_tokens'
  $out += [double]$o.attributes.'gen_ai.usage.output_tokens'
}
"chat=$chat input=$in output=$out"

属性名は OpenTelemetry の GenAI Semantic Conventions に準拠している(gen_ai.usage.* など)。だから他の OTel 対応ツールでも同じ要領で集計できる。

5. 結果

同じ問い・同一モデル claude-sonnet-4.6(OTel の span で確認できた)での実測。

指標 A: オントロジー無し B: オントロジー 削減
input tokens(Σ) 364,614 67,609 −81.5%
output tokens(Σ) 4,628 1,191 −74.3%
cache_read(Σ) 298,029 57,832 −80.6%
in+out 合計 369,242 68,800 −81.4%
LLM 呼び出し(chat) 10 3 −70%
ツール実行(execute_tool) 29 2 −93.1%
LLM 実時間 91.9s 25.2s −72.6%

入力トークン約 5.4 分の1、ツール往復 29→2、時間 約3.6倍速。回答の質は劣化どころか、依存制約(「indexer は base を import せず subprocess 経由」みたいな話)まで正確になった。グラフが推測を消したぶん、嘘が減った感じ。

コスト表記の注意
GitHub Copilot の課金は「トークン$」ではなく AI クレジット(旧 premium request) 単位(GitHub Copilot billing)。なので元記事の"コスト半減"とは課金体系が違う。ただし処理トークンとレイテンシが直接クレジット消費に効くので、この削減はそのままコスト削減に効く。

あとがき

効きそうだけど、問題は頻度と、同期、だろうね。

CI か、PR 時に構造検出して、更新させるようにするのが良さそうな気もするけど、とりあえず暫し更新は手動で放置予定

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?