input-token-overheads について
input-token-overheads は、Hermes Agent の入力トークンを監査・最適化するスキルです。コンテキストのオーバーヘッドや入力コストを調べる運用担当者向けに、ターンごとの負荷とセッション全体の使用量を測定し、改善後の再計測まで案内します。
主な機能
- 01ターンごとのプロンプト要素を測定
- 02セッション、cron、ツール通信を集計
- 03推定値とプロバイダー実測値を比較
- 04コスト順に主要な消費元を特定
- 05注入ファイルの切り詰めや参照切れを確認
- 06変更前後の差を再測定
活用シーン
- 01コンテキスト肥大化や入力コスト増の調査
- 02スキルやツール追加後の負荷確認
- 03cron ジョブのトークン使用量の分析
- 04最適化後の使用量変化の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ moonlight-lupin/ agent-skills --skill input-token-overheadsインストール後、Claude Code で/input-token-overheadsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/routing-fixtures.jsonscripts/audit_overheads.pyaudit.pytests/test_audit_overheads.py詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
入力トークンのオーバーヘッド
Hermes Agent インスタンスで、ターンごとの入力トークンコストが発生するすべての要因を監査します。それぞれを測定し、コスト順に並べ、最も大きな要因に対処します。
統合監査は scripts/audit_overheads.py で実行します(手順のステップ 1、1 つのコマンドで実行):構造化出力には --json、共有可能なグラフには --chart <png> を指定します。さらに、常時注入されるすべてのファイルについて、コンテキストドクター形式のチェックも行います。TRUNCATED(注入上限を超過し、毎ターン、通知なく切り詰められる)および MISSING のステータスが表示され、注意が必要なファイルがある場合は終了コード 1 になります。jzOcb/context-doctor から移植(MIT ライセンス、OpenClaw 専用。概念のみを採用し、スクリプトはネイティブ実装です)。
使用するタイミング
- ユーザーが「トークンのオーバーヘッド」「コンテキストが大きすぎる」「入力コストが高いのはなぜ」と尋ねた場合
- コンテキストの希薄化により、モデルの出力品質が低下した場合
- コストを最適化する場合 — ターンごとの入力トークンを減らすと、API の利用料金が下がります
- スキル、プラグイン、ツールを追加した後 — オーバーヘッドの差分を確認します
オーバーヘッドの内訳
各ターンで、Hermes はユーザーのメッセージより前に次のブロックをシステムプロンプトに注入します。
| ブロック | 読み込みタイミング | コストモデル |
|---|---|---|
| スキルの説明 | 毎ターン(skill-retrieval の上位 K 件) | 説明 1 件あたり約 200 文字、ターンあたり K 件 |
| メモリ(個人メモ) | 毎ターン | 固定。使用に伴い増加 |
| ユーザープロファイル | 毎ターン | 固定。好みの蓄積に伴い増加 |
| メモリプロバイダーのコンテキスト | 毎ターン(メモリプラグインが有効な場合) | 動的。デフォルトでは 5 件のメモリを呼び出します |
| ツールスキーマ(直接) | 毎ターン | 有効なツールごとの完全な JSON スキーマ |
| 遅延読み込みツールカタログ | 毎ターン(設定されている場合) | 名前と説明のみ |
| 必須スキル | 毎ターン(設定されている場合) | SKILL.md の本文全体 |
| プラットフォームの書式ルール | 毎ターン | 固定。プラットフォーム固有 |
| 動作ルール | 毎ターン | 固定のシステムプロンプトテキスト |
| スキル本文全体 | オンデマンド(skill_view) | スキルが読み込まれた場合のみ |
| 圧縮サマリー | しきい値到達後 | 古いメッセージをサマリーに置き換えます |
オンデマンド(ターンごとではありません): skill_view による完全な SKILL.md、tool_describe による遅延読み込みのツールスキーマ、skill_view(file_path=...) による参照ファイル。
健全性比率
健全性の指標はオーバーヘッド比率です。オーバーヘッドのトークン数をモデルのコンテキストウィンドウで割った値です。絶対数はコストに関係し、比率は品質に関係します。
| 比率 | 評価 | 備考 |
|---|---|---|
| < 5% | 優秀 | ウィンドウの大部分を会話に使用できます |
| 5-15% | 健全 | ツール、スキル、メモリを備えた有能なエージェントでは一般的です |
| 15-25% | 許容範囲 | 上限に近づいています。削減を検討してください。 |
| > 25% | 不健全 | 会話に使える容量を圧迫します。コストと品質のリスクがあります。 |
比率が重要な理由: 3つの研究により、コンテンツの品質とは関係なく、入力の長さがモデルの性能を低下させることが確認されています。
-
Lost in the Middle(Liu et al.、TACL 2023) — モデルの想起率はU字型の曲線を描き、コンテキストの先頭と末尾で最も高く、中間では大幅に低下します。オーバーヘッドは各ターンの先頭に置かれますが、その分、会話履歴が性能低下ゾーンに押し込まれます。arxiv.org/abs/2307.03172
-
Same Task, More Tokens(Levy et al.、ACL 2024) — 推論性能は、モデルが公称する最大値をはるかに下回る入力長でも低下します。余分なトークンが注意をそらす内容を含まないパディングであっても、性能の低下は発生します。モデルの技術上のコンテキストウィンドウは、実効コンテキストウィンドウではありません。aclanthology.org/2024.acl-long.818
-
Context Length Alone Hurts(Du et al.、EMNLP 2025) — 検索が完璧な場合、無関係なトークンを空白に置き換えた場合、または関連するトークン以外をすべてマスクした場合でも、入力の長さが増すにつれて性能は14~85%低下します。入力の長さそのものが制約になります。aclanthology.org/2025.findings-emnlp.1264
コストの累積: オーバーヘッドは毎ターン発生します。100ターンでオーバーヘッドが10kトークンなら、オーバーヘッドだけで入力トークンを1M消費します。オーバーヘッドを2kトークン削減すれば、100ターンのセッションごとに200kトークンを節約できます。
研究に基づく緩和策:
| 研究結果 | 出典 | 対策 |
|---|---|---|
| モデルはコンテキストの先頭と末尾を最もよく想起し、中間では性能が低下する | Liu et al. 2023 | オーバーヘッドは先頭に配置します(Hermes はすでにこのように動作します)。重要な会話履歴を中間に押し込まないでください。履歴が過度に圧縮されている場合は、圧縮しきい値を下げます |
| 推論性能は、公称のコンテキストウィンドウの最大値を大きく下回る時点から低下する | Levy et al. 2024 | 実効コンテキストウィンドウは、公称最大値の50~70%として扱います。実効ウィンドウではなく、公称ウィンドウの10%未満をオーバーヘッド比率の目標にします |
| 検索が完璧で注意をそらすものがなくても、入力の長さそのものが悪影響を及ぼす | Du et al. 2025 | オーバーヘッドを積極的に削減します。オーバーヘッドを1kトークン削減するごとに、コストだけでなく推論品質も向上します。この研究で示された緩和策は、問題を解く前に主要な根拠を列挙するようモデルに指示することです。これは、関連するコンテキストを要約する Hermes の圧縮に相当します |
| ツールカタログが8kから120kトークンに増えると、ツール呼び出しの性能が7~85%低下する | LongFuncEval (arxiv 2505.10570) | 有効にするツールセットの数を抑えます。常時有効なスキーマより、必要に応じて読み込む遅延読み込みツールを優先します。使用しないツールセットは無効にします |
手順
1. 各オーバーヘッドの発生源を測定する
監査スクリプトを実行して、実際の数値を取得します。
python3 -c "
import yaml, pathlib, glob, os, re
# --- Skill descriptions (skill-retrieval index) ---
files = glob.glob(os.path.expanduser('~/.hermes/skills/**/SKILL.md'), recursive=True)
total_desc = 0; count = 0; by_cat = {}
for f in files:
try:
text = pathlib.Path(f).read_text()
m = re.match(r'^---\n(.*?)\n---\n', text, re.DOTALL)
if not m: continue
fm = yaml.safe_load(m.group(1))
if not fm: continue
desc = fm.get('description', '')
if not desc: continue
cat = f.split('/skills/')[1].split('/')[0]
by_cat.setdefault(cat, [0,0]); by_cat[cat][0] += len(desc); by_cat[cat][1] += 1
total_desc += len(desc); count += 1
except Exception: pass
avg = total_desc // max(count, 1)
K = int(os.environ.get('SKILL_RETRIEVAL_TOP_K', '6'))
print(f'Skills: {count} total, {total_desc} chars in descriptions')
print(f' Top-K per turn: ~{K*avg} chars (~{K*avg//4} tokens) at K={K}')
print(f' By category (top 5):')
for cat, (sz, cnt) in sorted(by_cat.items(), key=lambda x: -x[1][0])[:5]:
print(f' {sz:>6} chars ({cnt:>2} skills) {cat}')
# --- Disabled skills (savings) ---
config_path = os.path.expanduser('~/.hermes/config.yaml')
if not os.path.exists(config_path):
print(' Config: ~/.hermes/config.yaml not found — skipping disabled/compression stats')
else:
try:
with open(config_path) as fh:
cfg = yaml.safe_load(fh)
if cfg is None:
cfg = {}
disabled = cfg.get('skills',{}).get('disabled',[]) or []
print(f' Disabled: {len(disabled)} skills (saves ~{len(disabled)*avg} chars)')
comp = cfg.get('compression',{}) or {}
print(f' Compression: threshold={comp.get(\"threshold\")}, target_ratio={comp.get(\"target_ratio\")}, protect_last={comp.get(\"protect_last_n\")}')
except Exception as e:
print(f' Config parse error: {e}')
"
メモリプロバイダーの数を確認する場合(Mnemosyne がインストールされている場合):
python3 -c "
import sqlite3, os, glob
for db in glob.glob(os.path.expanduser('~/.hermes/**/mnemosyne.db'), recursive=True):
conn = sqlite3.connect(db); c = conn.cursor()
for t in ['working_memory','episodic_memory','canonical_facts','memoria_facts']:
try:
c.execute(f'SELECT COUNT(*) FROM {t}'); print(f' {t}: {c.fetchone()[0]} rows')
except: pass
conn.close()
"
完了: スキルの説明、無効数、圧縮設定を測定しました。ツールスキーマ(#1)と動作ルール(#2)は固定コストです。モデルのシステムプロンプトから推定するか、セッション中に /tokens を確認して合計を調べてください。スクリプトで測定するのは変動する発生源(#6、#7)です。固定の発生源(#1~#5)はセッション中に確認する必要があります。
2. コスト順に並べる
すべてのソースをターンあたりのトークン数で並べ替えます。一般的な順位は次のとおりです。
- ツールスキーマ — 固定コストが最も大きくなります。有効なツールセットの数に応じて増加します。
- 行動ルール + システムプロンプト — 固定テキストです。
- 必須スキル — 必須スキルごとに、SKILL.md の本文全体が含まれます。
- メモリ + ユーザープロフィール — 静的ブロックです。
- 遅延読み込みツールカタログ — 遅延読み込み対象の各ツールの名前 + 説明です。
- スキルの説明 — スキル検索による上位 K 件の挿入です。
- メモリプロバイダーのコンテキスト — 動的な想起です。デフォルトは 5 件です。
完了条件: ソースを順位付けできていること。上位 3 つが最適化対象です。
3. コストの大きい項目に対処する
ツールスキーマ(固定コストが最大):
- 有効なツールセットを監査します。ダッシュボードで
hermes toolsを実行してください - 使用していないツールセットを無効にします(無効にするごとに、各ターンからツールスキーマが 1~3 個削除されます)
- config.yaml の
platform_toolsets.cliを使って、プロファイルごとのツールセットへのアクセスを制御します - 常時有効なツールよりも、遅延読み込みツール(必要に応じて読み込む)を優先します
メモリブロック:
- 圧縮を調整するには、
skill_view(name='hermes-compression-tuning')を読み込みます - 古くなった、または重複したメモリエントリを整理します
- メモリブロックを予算内に収めます。上限に達した場合は、新しいエントリを追加する前に、古くなったエントリをまとめて削除します
スキルの説明:
config.yamlのskills.disabledで使用していないスキルを無効にします。スキルを無効にするごとに、検索インデックスから約 200 文字分が削減されます- 説明は簡潔にします。スキル検索プラグインは説明を 200 文字で切り詰めます。200 文字を超える説明は、ルーティングの精度を高めずにトークンを浪費します
メモリプロバイダー(インストール済みの場合):
- 統合作業を実行して、作業メモリをエピソード記憶に移し、作業セットを減らします
- 古くなった事実を無効化します
- コンテキストに余裕がない場合は、想起の
limitパラメーターを小さくします
完了条件: 上位 3 つの各ソースに対して、少なくとも 1 つの最適化を適用していること。
4. 差分を確認する
手順 1 の監査スクリプトを再実行します。最適化前と最適化後のトークン推定値を比較します。
完了条件: 最適化前後の差分を報告していること。大幅な削減がない場合、残るオーバーヘッドは構造上のものであり(システムプロンプト + 行動ルール)、config を変更しない限り削減できません。
注意点
| 問題 | 原因 | 対処方法 |
|---|---|---|
| 監査スクリプトがスキル数として 0 を返す | スキルのパスが間違っているか、~/.hermes/skills/ が空です | ls ~/.hermes/skills/ でディレクトリが存在し、カテゴリ別のサブディレクトリが含まれていることを確認します。スキルがシンボリックリンクされている場合や、カスタムパスにある場合は、glob を調整します |
| ツールセットを無効にするとワークフローが壊れる | そのツールセットに依存するスキルがあります | 無効にする前に、スキルの frontmatter にある requires_toolsets を確認します |
| メモリを整理すると必要な事実が削除される | 最終使用時刻を確認せずに積極的に削除しています | 削除する前に recall_count と last_recalled を確認します |
| 圧縮が早すぎる | threshold の設定が低すぎます | コンテキストウィンドウが長い場合は値を上げます。ただし、品質の低下に注意してください |
| 圧縮が遅すぎる | threshold の設定が高すぎます | 値を下げます。ただし、圧縮サマリー自体にもトークンが必要です |
| 必須スキルのオーバーヘッドを避けられないように思える | 行動ルールで設定されています | コストを許容するか、config で必須読み込みの要件を削除します |
検証
- 監査スクリプトを再実行し、トークン推定値が減少したことを確認します
hermes tools— 必要なツールセットのみが有効であることを確認します- メモリブロック — 予算内であることを確認します
- メモリプロバイダーの件数 — 統合後に作業セットが減少したことを確認します
- 次のセッションを監視します。コンテキストを減らしても品質が低下しないことを確認します