Claude Codeを使い込んでいると、ある種の「もやもや」が蓄積されてきます。処理が長時間続いているとき「いったい何をやっているのか」「このまま待つべきか止めるべきか」が分からない。サブエージェントが並列で動いているのに、どれが詰まっているか特定できない。課金明細を見て「なぜこんなにコストがかかったのか」が追えない。
これらはすべて、Claude Codeが内部動作を十分に見せてくれないことに起因します。ターミナルには「Read 3 files」「Searched for 1 pattern」といった要約しか表示されず、実際に何をどれだけ処理したかは見えません。
本記事では、この「ブラックボックス問題」に対応する3種類のアプローチを比較します。claude-devtools(ローカルログの可視化)、OpenTelemetry連携(外部観測基盤への送信)、cmux(複数セッション管理)の特徴と使いどころを整理します。
3つのアプローチを俯瞰する
まず全体像を把握するために比較表を示します。
| ツール | 主な用途 | ネットワーク | リアルタイム性 | サブエージェント可視化 |
|---|---|---|---|---|
| claude-devtools | ローカルログの詳細可視化 | 不要(ローカルのみ) | セッション後に確認 | あり(ツリー表示) |
| OpenTelemetry | 組織監視・定量改善 | 必要(外部送信) | あり(5〜60秒間隔) | なし |
| manaflow cmux | 複数セッションの注意管理 | 不要 | あり(即時通知) | 間接的に(通知で把握) |
| craigsc cmux | gitワークツリーの並列管理 | 不要 | — | なし |
「今すぐ何が起きているか調べたい」ならclaude-devtools、「チームで継続的に改善したい」ならOpenTelemetry、「複数エージェントを並列で動かしている」ならcmuxが出発点になります。
claude-devtools──「なぜそのトークン数になったか」が分かる
claude-devtoolsは「The missing DevTools for Claude Code」を謳うデスクトップアプリです。Claude Codeが~/.claude/に保存するJSONLログを読み取り、ブラウザの開発者ツールのようなUIで内容を再構築します。
最大の特徴はAPIキー不要・Claude Code本体への変更なしで動く点です。ローカルのログファイルを読むだけなので、外部への通信は一切発生しません。
インストール方法
brew install --cask claude-devtools
docker compose up # → localhost:3456 でアクセス
Linux(AppImage / .deb / .rpm)およびWindowsの.exeインストーラーもGitHubから入手できます。
主な機能
① Context Reconstruction(コンテキスト内訳)
ターン(1回のやり取り)ごとに、トークン消費を7カテゴリに分解して表示します。
| カテゴリ | 内容 |
|---|---|
| CLAUDE.md | CLAUDE.mdファイルで消費したトークン |
| スキル | スキル定義ファイルで消費したトークン |
| @メンション | @でファイル・URLを参照した際のトークン |
| ツールI/O | Read・Bash・Grep等のツール入出力 |
| thinking | 内部思考(拡張思考が有効な場合) |
| チームオーバーヘッド | サブエージェントの実行オーバーヘッド |
| ユーザーテキスト | 実際のユーザー入力 |
この内訳を見ることで「入力トークンの約40%がファイル読取結果だった」「CLAUDE.mdが想定以上の比重を占めている」といった事実を数値で把握できます。実際にこの可視化を利用してCLAUDE.mdを約30%削減し、コストを下げた事例が報告されています。
② Compaction Visualization(コンパクション可視化)
コンテキスト圧縮(コンパクション)の境界を検出し、圧縮前後のトークン変化を可視化します。「いつコンパクションが走ったか」「どの程度圧縮されたか」を把握することで、コンテキスト管理の効率化に役立てられます。
③ Tool Call Inspector(ツール呼び出し検査)
ターミナルでは「Read 3 files」としか表示されなかった操作が、claude-devtoolsでは以下のように詳細表示されます。
| ターミナル表示 | claude-devtools表示 |
|---|---|
| Read 3 files | 実際のパス・シンタックスハイライト・行番号 |
| Searched for 1 pattern | 正規表現パターン・マッチしたファイルと行 |
| Edited 2 files | 追加/削除をインラインdiffで表示 |
| コンテキストバー(3分割) | 7カテゴリ別内訳+コンパクション可視化 |
④ Team & Subagent Trees(サブエージェントツリー)
Taskツール(サブエージェント)の呼び出しを独立した実行ツリーとして展開します。6並列のうち1つだけが異常にトークンを消費していたケースや、サブエージェントが同じファイルを繰り返し読んでいたケースも、このビューで即座に発見できます。各サブエージェントのトークン量・コスト・所要時間が個別に表示されます。
⑤ Notification Triggers(アラート)
正規表現ベースのアラートを設定できます。たとえば.envファイルへのアクセスや、特定のトークン数を超えた場合に通知するデフォルトルールが用意されています。
制約:claude-devtoolsは読み取り専用です。動作中のセッションへの介入や操作はできません。あくまでログの事後分析ツールです。
OpenTelemetry連携──メトリクスで定量改善する
Claude CodeはOpenTelemetry(OTel)プロトコルによる外部監視を公式サポートしています。メトリクスとイベント(ログ)をGrafana・Datadog・Prometheusなどの既存観測基盤に送ることができます。
claude-devtoolsとの決定的な違いはリアルタイム性と継続監視です。開発中の「今のセッション」を事後分析するのがdevtools、数週間にわたるコスト推移やチーム全体の利用状況を定量的に監視するのがOTelという使い分けになります。
OpenTelemetryの詳細設定についてはClaude Code OpenTelemetry連携ガイドを参照してください。ここでは可視化という観点で要点を整理します。
有効化の基本設定
export CLAUDE_CODE_ENABLE_TELEMETRY=1 export OTEL_METRICS_EXPORTER=otlp export OTEL_LOGS_EXPORTER=otlp export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
取得できるメトリクス一覧
| メトリクス名 | 説明 | 主な属性 |
|---|---|---|
claude_code.token.usage |
トークン使用数 | type(input/output/cacheRead/cacheCreation), model |
claude_code.cost.usage |
セッションコスト(USD) | model |
claude_code.session.count |
セッション開始回数 | — |
claude_code.lines_of_code.count |
変更コード行数 | type(added/removed) |
claude_code.commit.count |
gitコミット数 | — |
claude_code.active_time.total |
アクティブ使用時間(秒) | type(user/cli) |
claude_code.code_edit_tool.decision |
ツール許可/拒否の判断数 | tool_name, decision, language |
取得できるイベント一覧
| イベント名 | タイミング | 主なフィールド |
|---|---|---|
claude_code.tool_result |
ツール実行完了時 | tool_name, success, duration_ms, error |
claude_code.api_request |
APIリクエスト毎 | model, cost_usd, duration_ms, input_tokens, output_tokens |
claude_code.user_prompt |
プロンプト送信時 | prompt_length(内容は別途有効化が必要) |
claude_code.api_error |
APIエラー時 | error, status_code, attempt |
重要な制約:公式のOTel連携はトレース(Span)を出力しません。メトリクスとログ(イベント)のみです。Jaegerなどでウォーターフォール表示したい場合は、JSOLログを独自解析してSpanに変換する追加実装が必要になります。
主要バックエンドとの接続
export CLAUDE_CODE_ENABLE_TELEMETRY=1 export OTEL_METRICS_EXPORTER=otlp export OTEL_LOGS_EXPORTER=otlp export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp-gateway-prod-eu-north-0.grafana.net/otlp" export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic [YOUR_BASE64_TOKEN]"
export CLAUDE_CODE_ENABLE_TELEMETRY=1 export OTEL_METRICS_EXPORTER=prometheus # Claude Codeがlocalhost上にPrometheusエンドポイントを公開する
VictoriaMetrics利用時の注意
VictoriaMetricsはデルタ時系列データをサイレントにドロップします。以下を追加してください。
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative
チームIDの付与(マルチチーム環境)
複数のチームで共有の観測基盤を使う場合、リソース属性でチームを識別できます。
export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"
JSOLログを独自解析する──トレースの自作
公式OTelではトレースが出ないため、より深い分析が必要な場合はJSONLログの直接解析が有効です。
~/.claude/projects/配下に、プロジェクトパスから生成したディレクトリ名(非英数字を-に置換)があり、その中にセッションごとの.jsonlファイルが保存されています。
~/.claude/ ├── projects/ │ └── -Users-me-myproject/ # CWDのパス(記号→"-"変換) │ ├── <session-uuid>.jsonl # セッションログ │ └── sessions-index.json # メタデータ └── settings.json
JSONLの各行にはtype(user/assistant/system)、timestamp、usage(input_tokens等)、message.content(tool_useとtool_resultを含む配列)が含まれています。
このJSONLをDuckDBやPythonで集計することで、「セッション内の130回のツール呼び出しのうちBashが90回、サブエージェント待機が20回だった」「待機は回数が少ないのに総実行時間で支配的だった」といった分析が可能になります。
-- tool_nameごとの呼び出し回数を集計
SELECT
json_extract_string(content_item, "$.name") AS tool_name,
COUNT(*) AS call_count
FROM (
SELECT unnest(
json_extract(message, "$.content")::JSON[]
) AS content_item
FROM read_json_auto("~/.claude/projects/**/*.jsonl")
WHERE type = "assistant"
)
WHERE json_extract_string(content_item, "$.type") = "tool_use"
GROUP BY tool_name
ORDER BY call_count DESC;
cmux──複数セッションを「待つだけ」から「管理する」へ
Claude Codeを並列で複数動かすケースが増えるにつれ、「どのセッションが詰まっているか」「どれが入力待ちになっているか」の把握が課題になります。ここでcmuxが登場します。
ただし「cmux」という名前のツールが2種類存在します。用途が全く異なるため区別して把握してください。
manaflow/cmux──セッション観測に特化したターミナル
対象: macOSのみ
manaflow/cmuxはGhosttyをベースにしたネイティブターミナルアプリです。複数のClaudeセッションを同時実行する際、「どのセッションが注意を必要としているか」をサイドバーで一覧管理できます。
| 機能 | 説明 |
|---|---|
| 縦型タブ(サイドバー) | 各ワークスペースのgitブランチ・PRステータス・最新通知テキストを表示 |
| 注意通知 | ペインが入力待ちになると青い枠とタブのハイライトで通知 |
| cmux notifyコマンド | 任意のコマンドからサイドバーにメッセージを送信 |
| 内蔵ブラウザ | ターミナル内でWebページを開いて要素検査・フォーム入力も可能 |
brew tap manaflow-ai/cmux brew install --cask cmux
craigsc/cmux──gitワークツリーのライフサイクル管理
対象: 全OS
craigsc/cmuxはgitワークツリーのライフサイクルを管理するシェルスクリプトです。複数のClaudeエージェントを同一リポジトリで並行動作させる際、ブランチの競合を防ぐためにワークツリーを活用します。
gitワークツリーについてはClaude Code worktreeガイドも参照してください。
curl -fsSL https://github.com/craigsc/cmux/releases/latest/download/install.sh | sh
# 新しいワークツリーを作成してClaudeを起動 cmux new feature/my-feature # 既存のワークツリーで作業を再開 cmux start feature/my-feature # アクティブなワークツリーの一覧表示 cmux ls # メインブランチへのマージ cmux merge feature/my-feature # ワークツリーとブランチを削除 cmux rm feature/my-feature
注意:craigsc/cmuxを使う場合は.gitignoreに.worktrees/を追加する必要があります。
claude-devtoolsの活用パターン
claude-devtoolsで何が見えるかを具体的なシナリオで整理します。
シナリオ①:「簡単な修正のはずが50万トークン超になった」
Context Reconstruction(コンテキスト内訳)ビューを開くと、ツールI/Oカテゴリが全体の60%以上を占めていることに気づきます。Read・Grep・Bashの実行結果がコンテキストを圧迫していた場合、Claude Codeに「このファイルはすでに確認済み。再度読み込まないで」といった指示をCLAUDE.mdに追加することで次回から削減できます。
シナリオ②:「6並列のサブエージェントが終わらない」
Subagent Treesビューを開くと、6つのサブエージェントのうち1つがトークン消費数で突出していることが分かります。そのブランチをドリルダウンすると、同じファイルを繰り返し読み込んでいるツール呼び出しのパターンが見つかります。ループの原因が「ファイルの変更が検知できない」であれば、Hooksで変更通知を明示的に渡す設計が有効です。
シナリオ③:「CLAUDE.mdが重すぎる」
CLAUDE.mdカテゴリのトークン比率が全体の30%を超えている場合、内容の見直しが必要です。実際にCLAUDE.mdのトークンを30%削減してコストが下がった実例があります。コンパクションビューと合わせて、「CLAUDE.mdを読んだ直後にコンパクションが走っている」パターンも確認できます。
Notification Triggersの設定例
claude-devtoolsのアラート機能を使うと、問題のあるパターンを自動検知できます。
| アラート条件 | 正規表現例 | 用途 |
|---|---|---|
| .envファイルへのアクセス | \.env$ |
機密ファイルの読み取りを検知 |
| 同一ファイルの繰り返し読み取り | Read.*same_file.*Read.*same_file |
ループの検知 |
| 大量のBash実行 | カウントベースのトリガー | 無限ループの早期発見 |
SSH Remote Sessions機能
claude-devtoolsはSSH経由でリモートマシンのClaude Codeセッションも同じUIで検査できます。クラウド上のVMや開発サーバーで動かしているセッションを、ローカルのclaude-devtoolsから確認する使い方が可能です。
# 環境変数でリモートのCLAUDE_ROOTを指定 CLAUDE_ROOT=user@remote-host:/home/user/.claude claude-devtools
OpenTelemetryダッシュボードの構築
OTelを有効化してGrafanaと接続したあとの、実用的なダッシュボードの作り方を整理します。
よく使うGrafanaパネル:
| パネル | メトリクス | 目的 |
|---|---|---|
| 日別コスト | claude_code.cost.usageをsum/day |
コストの異常値検知 |
| モデル別トークン | claude_code.token.usageをmodel別に分解 |
モデル使用状況の把握 |
| 入力キャッシュヒット率 | cacheRead / (input + cacheRead) | キャッシュ効率の改善指標 |
| ツール成功率 | claude_code.tool_resultのsuccess=true比率 |
ツール実行エラーの傾向把握 |
| アクティブ時間 | claude_code.active_time.total |
利用時間の把握 |
キャッシュヒット率の重要性
cacheRead(キャッシュ読み取り)はinputトークンより大幅に安価です。CLAUDE.mdやシステムプロンプトが繰り返し送られる構成では、キャッシュヒット率を最大化することがコスト削減の近道になります。OTelのclaude_code.token.usageのtype属性をcacheRead/input別に可視化することで、改善余地が見えてきます。
JSONLログの詳細解析──DuckDBで深掘りする
claude-devtoolsとOTel以外に、DuckDBを使ったJSONL直接解析も強力な選択肢です。DuckDBはJSONファイルをそのままSQLで集計できるため、特別なインストールが不要で高速に分析できます。
# インストール
pip install duckdb
# セッション別コスト集計
python3 -c "
import duckdb
conn = duckdb.connect()
result = conn.execute("""
SELECT
json_extract_string(message, '$.model') AS model,
SUM(CAST(json_extract(message, '$.usage.input_tokens') AS INTEGER)) AS input_tokens,
SUM(CAST(json_extract(message, '$.usage.output_tokens') AS INTEGER)) AS output_tokens
FROM read_json_auto('$HOME/.claude/projects/**/*.jsonl')
WHERE type = 'assistant'
AND json_extract(message, '$.usage') IS NOT NULL
GROUP BY model
ORDER BY input_tokens DESC
""").fetchall()
for row in result:
print(row)
"
SELECT
json_extract_string(item.value, "$.name") AS tool_name,
COUNT(*) AS call_count,
AVG(LENGTH(json_extract_string(item.value, "$.input")::TEXT)) AS avg_input_size
FROM read_json_auto("~/.claude/projects/**/*.jsonl"),
LATERAL UNNEST(
json_extract(message, "$.content")::JSON[]
) AS item(value)
WHERE type = "assistant"
AND json_extract_string(item.value, "$.type") = "tool_use"
GROUP BY tool_name
ORDER BY call_count DESC;
このクエリでツール別の呼び出し回数と平均入力サイズが分かります。「Readツールの平均入力サイズが突出して大きい」なら不要なファイル全体読み取りが問題、「Bashが圧倒的に多い」ならコマンド実行の最適化が効果的です。
その他のコスト・トークン分析ツール
claude-devtools・OTel・cmux以外にも、用途に特化した分析ツールが充実しています。
| ツール | 特徴 | 使い方 |
|---|---|---|
| ccusage | GitHubスター12,000超。日別/月別/セッション別/5時間ブロック別集計、モデル別内訳、JSONエクスポート | npx ccusage@latest |
| Claude-Code-Usage-Monitor | リアルタイム監視、ML予測(P90)、残り時間予測、Pro/Max5/Max20プラン対応 | uv tool install claude-monitor |
| claude-code-log | Python CLI、JSONL→HTML/Markdown変換、TUI付き | pip install claude-code-log |
| ccost | Node.js不要の単一バイナリ、多通貨対応 | GitHubから直接入手 |
コスト管理の詳細な方法についてはClaude Codeコスト管理ガイドも参照してください。
状況別の選択ガイド
どのツールを選ぶかは「何を知りたいか」によって変わります。
| 状況 | 推奨ツール | 理由 |
|---|---|---|
| 「なぜトークンがこんなに消費されたか調べたい」 | claude-devtools | 7カテゴリ内訳でCLAUDE.md・ツールI/Oの比重を可視化 |
| 「サブエージェントのどれが詰まっているか知りたい」 | claude-devtools | 実行ツリー表示でトークン・時間の偏りを発見 |
| 「チーム全体のコスト推移をGrafanaで管理したい」 | OpenTelemetry | 継続的なメトリクス送信と既存基盤との統合 |
| 「個人でもリアルタイムのコスト監視がしたい」 | ccusage / claude-monitor | 軽量・ゼロ設定で使える専用ツール |
| 「macで複数セッションを並列で動かしている」 | manaflow/cmux | どのセッションが入力待ちかをサイドバーで把握 |
| 「並列エージェントのブランチ競合を防ぎたい」 | craigsc/cmux | ワークツリー単位でエージェントを分離 |
個人の開発環境ではclaude-devtools + ccusageの組み合わせが最もコスト・設定の手間のバランスが良いです。チーム開発ではOpenTelemetryを基盤に置き、devtoolsを個別セッションのデバッグ補助として使う形が効果的です。
よくある質問
OTEL_LOG_USER_PROMPTS=1を設定することでプロンプト内容もclaude_code.user_promptイベントに含まれるようになります。ただし業務内容が含まれる場合は外部サービスへの送信リスクを考慮してください。ツールの引数もOTEL_LOG_TOOL_DETAILS=1で有効化できます。PostToolUseフックでツール使用ログを独自フォーマットで記録し、それをclaude-devtoolsとは別のビューワーで確認する構成が可能です。OTelのclaude_code.tool_resultイベントと併用することで、ツールの成功率・実行時間の異常を検知する監視システムも構築できます。Hooksの詳細はClaude Code Hooksガイドを参照してください。~/.claude/ディレクトリを読むだけで、外部へのネットワーク通信は発生しません。API呼び出しも不要なため、機密性の高いプロジェクトでも安心して使えます。まとめ
Claude Codeのブラックボックス問題に対応するツールは、用途によって明確に分かれます。
claude-devtoolsはローカルログを7カテゴリに分解し、トークンの使われ方を可視化します。「なぜこのコストになったか」「どのサブエージェントが詰まっていたか」を事後に分析する用途に最適です。導入コストが低く(Homebrew 1コマンド)、外部通信なしで始められます。
OpenTelemetry連携はGrafanaやDatadogなどの既存観測基盤にメトリクスを送り、継続的な定量改善を支援します。チームでの利用やコスト管理の自動化には欠かせません。ただしトレース出力は非対応な点に注意が必要です。
cmuxは複数セッションの並列運用を支援します。macOS向けのmanaflow/cmuxはどのセッションが入力待ちかを可視化し、全OS対応のcraigsc/cmuxはワークツリーを使ったブランチ競合を防ぎます。
まずはclaude-devtoolsを入れて自分のトークン内訳を確認することをおすすめします。多くの場合、CLAUDE.mdやファイル読み取りが想定以上の比重を占めていることに気づくはずです。その改善だけで、コストと速度の両方を改善できます。
サブエージェントの活用についてはClaude Code サブエージェントガイド、全体的なClaude Codeの使い方はClaude Code完全ガイドも参照してください。

