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?

GitHub Copilot CLI の token 消費を正確に計測する

0
Posted at

はじめに

appium-cli というツールを作成している最中に、「GitHub Copilot CLI が内部でどれだけ token を消費しているか?」を確認したくなりました。今回は、OpenTelemetry ログを使って正確に計測する方法 についてメモを残しておくことにします。

この記事では、「Yahoo のエンタメニュースを 3 本取得する」 という具体的なタスクを実際に実行し、取得した OTel ログから GitHub Copilot CLI が内部で消費する token 数を確認する。

まとめ

  • OPILOT_OTEL_FILE_EXPORTER_PATH を設定するだけで OTel ログが取れる
  • OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true で「どの token がどの処理に使われたか」をログで追える
  • 集計対象は chat span
  • input_tokens は cache 込みの総量

STEP 1:計測環境を整える(環境変数 2 つ)

GitHub Copilot CLI v1.0.43 以上で使えます。

# ① token 数だけ知りたいとき(最小構成)
COPILOT_OTEL_FILE_EXPORTER_PATH=/tmp/copilot-otel.jsonl \
copilot -p "タスク" --allow-all -s

# ② 「何の token か」まで把握したいとき(プロンプト・応答も記録)
COPILOT_OTEL_FILE_EXPORTER_PATH=/tmp/copilot-otel.jsonl \
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true \
copilot -p "タスク" --allow-all -s
環境変数 効果
COPILOT_OTEL_FILE_EXPORTER_PATH 設定するだけで OTel が有効になり JSON Lines 形式でログが出力される
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT プロンプト・応答・ツール引数の本文もキャプチャする(デフォルト false

OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true は注意
コード・ファイル内容・ユーザープロンプト・ツール引数がすべてログに記録されます。信頼できるローカル環境だけで使用する

STEP 2:OTel ログの構造を把握する

出力された JSONL には複数種類のレコードが混在しています。1 回の Copilot 実行では、ざっくりこういう構造になります。

各レコードの役割と、token 計測での扱いを整理します。

レコード 役割 token 計測での扱い
chat <model> LLM API を 1 回呼び出した単位 = ターンごとの token が入っている 集計する
invoke_agent セッション全体の root span。全ターン合計を保持 照合のみ
execute_tool ツール実行ログ 参照のみ
gen_ai.client.token.usage セッション合計の Histogram メトリクス 照合のみ

STEP 3:token フィールドの意味

chat span には以下の token フィールドがあります。実際のログはこのような形です。

{
  "gen_ai.usage.input_tokens": 20913,
  "gen_ai.usage.output_tokens": 429,
  "gen_ai.usage.cache_creation.input_tokens": 8220,
  "gen_ai.usage.cache_read.input_tokens": 12683
}

最重要ポイントinput_tokens は cache 込みの総量です。cache_creationcache_read は内訳です。

フィールド 意味 集計ルール
gen_ai.usage.input_tokens そのターンで送った総入力 token ✅ これを合計する
gen_ai.usage.output_tokens そのターンで返ってきた出力 token ✅ これを合計する
gen_ai.usage.cache_creation.input_tokens cache への新規書き込み分(input_tokens の内訳) 内訳として参照
gen_ai.usage.cache_read.input_tokens cache ヒット分(input_tokens の内訳) 内訳として参照
github.copilot.current_tokens 送信前コンテキストの推定サイズ 実使用量としては使わない

github.copilot.current_tokens は CompactionProcessor によるコンテキスト管理上の推定値のようです。OTel の gen_ai.usage.input_tokens と一致しないケースがあるようなので。正確な API 使用量は gen_ai.usage.input_tokens を参照するのが良いでしょう。

STEP 4:集計スクリプトで数値化する

chat span だけを抽出して集計する Python スクリプト

# token_summary.py
import json
import sys

path = sys.argv[1] if len(sys.argv) > 1 else "/tmp/copilot-otel.jsonl"
spans = []

with open(path) as f:
    for line in f:
        obj = json.loads(line)
        if obj.get("type") == "span" and obj.get("name", "").startswith("chat "):
            a = obj.get("attributes", {})
            spans.append({
                "turn": a.get("github.copilot.turn_id"),
                "input": a.get("gen_ai.usage.input_tokens", 0),
                "output": a.get("gen_ai.usage.output_tokens", 0),
                "cache_create": a.get("gen_ai.usage.cache_creation.input_tokens", 0),
                "cache_read": a.get("gen_ai.usage.cache_read.input_tokens", 0),
            })

print(f"turns:        {len(spans)}")
print(f"total input:  {sum(s['input'] for s in spans):,}")
print(f"total output: {sum(s['output'] for s in spans):,}")
print()
print(f"{'turn':<6} {'input':>10} {'output':>8} {'cache_create':>14} {'cache_read':>12}")
print("-" * 56)
for s in spans:
    print(
        f"{str(s['turn']):<6} {s['input']:>10,} {s['output']:>8,}"
        f" {s['cache_create']:>14,} {s['cache_read']:>12,}"
    )
python3 token_summary.py /tmp/copilot-otel.jsonl

これで「何 turn あったか」「合計 input / output はいくつか」「cache がどれくらい効いていたか」まで一気に確認します

STEP 5:実際に計測してみる

ここからは実測です。「Yahoo のエンタメニュースを 3 本取得してまとめる」というタスクを、bash 経由の playwright-cli コマンドのみを使うよう Copilot に指示して実行しました。

実行コマンド

COPILOT_OTEL_FILE_EXPORTER_PATH=docs/evidence/yahoo-playwright-cli-otel-20260508-195200.jsonl \
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true \
copilot -p "yahoo.co.jp で最新のエンタメニュースを3本取得して、ざっくり内容をまとめて教えてください。bash で playwright-cli コマンドだけを使うこと。playwright-browser_* ツールは使わないこと。snapshot は --raw snapshot --filename を使って docs/evidence/ 配下に保存し、必要な情報だけを読むこと。" \
--allow-all --model claude-haiku-4.5 -s

計測結果サマリー

指標
モデル claude-haiku-4.5
chat span 数(=ターン数) 22
合計 input tokens 639,715
合計 output tokens 5,498
invoke_agent input / output 639,715 / 5,498

invoke_agent の値が chat 合計と一致しています。「全ターンの合算値を持つ root span」なので、chat 合計と同じ値になることが確認できます。

参考リンク

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?