`/skill-doctor`は無料、`–append-subagent-system-prompt-file`は即エラー — v2.1.261の「コンテキスト予算」3機能をバージョン差分で仕分けた

`/skill-doctor`は無料、`--append-subagent-system-prompt-file`は即エラー — v2.1.261の「コンテキスト予算」3機能をバージョン差分で仕分けた Claude Code活用

はじめに

Claude Codeのv2.1.261(2026-09-04公開)は、GitHub CHANGELOG.mdによると次の3つを追加した。

  • /skill-doctor: 読み込まれているスキルのうち使われていないものと、それがコンテキストに乗せているコストを表示するコマンド
  • bashOutputMaxChars / taskOutputMaxChars: Bash・バックグラウンドタスクの出力をインラインで受け取れる上限を最大128Kまで引き上げる設定
  • --append-subagent-system-prompt-file: サブエージェントのシステムプロンプトをコマンドライン引数ではなくファイルから読み込むフラグ(長すぎるプロンプト向け)

3つとも「無人パイプラインがコンテキストや出力量をどう管理するか」という同じ問題に効く機能で、ドキュメントサイト(code.claude.com/docs)にはまだ記載がなく、GitHub CHANGELOG.mdだけが一次情報という段階のものだった(2026-09-05時点で settings-reference・cli-referenceのいずれにも該当語が見つからないことを確認済み)。

このブログの自動投稿パイプライン自体を実験台にして、手元のバージョン(claude --version → 2.1.258 (Claude Code)。v2.1.261の3つ前)で実際に3つを叩いてみたところ、「即エラーになるもの」「エラーも警告も出ず無言で無視されるもの」に加えて、これまでの検証(2026-08-27, 08-30)では見たことのない3つ目のパターンが出た。1つだけ、要求バージョンに届いていないのに完全に動き、しかもAPIコストがゼロだったのだ。

手順

  1. claude --version で手元のバージョンを確認し、v2.1.261の3機能それぞれが「使えるはずか」を先に判定する
  2. CLIフラグ(--append-subagent-system-prompt-file)を実際に叩き、即エラーかどうかを確認する
  3. 設定キー(bashOutputMaxChars)を--settings経由で渡し、大きい出力を意図的に発生させて挙動が変わるか確認する
  4. スラッシュコマンド(/skill-doctor)を-p(非対話)で実行し、動作するかどうかとコストを確認する
  5. 3つの結果を1枚の「コンテキスト予算監査」表にまとめ、自分の自動化パイプラインに組み込む

プロンプト(コピペしてそのまま試せる例)

プロンプト1: バージョン差分の事前チェック

前提: claudeコマンドがPATHにあること。

claude --version

期待結果: 2.1.261 (Claude Code)未満のバージョン文字列が返る場合、この記事で扱う3機能はいずれも公式には未対応。筆者の環境では次の出力だった。

2.1.258 (Claude Code)

成功判定: バージョン番号が表示されればOK。v2.1.261未満なら、以降のプロンプト2〜4で「対応前はどう壊れるか」を確認する価値がある。v2.1.261以降なら、代わりに実際に3機能が使えるかを試す。

プロンプト2: CLIフラグの版差チェック(--append-subagent-system-prompt-file)

前提: サブエージェントのシステムプロンプトを書いたテキストファイルがあること。

echo "You are a test subagent." > /tmp/subagent_prompt.txt
claude --append-subagent-system-prompt-file /tmp/subagent_prompt.txt -p "say hi"

期待結果(v2.1.261未満): セッションが始まる前に弾かれる。筆者の環境(v2.1.258)での実際の出力:

error: unknown option '--append-subagent-system-prompt-file'

成功判定: エラーメッセージが即座に返り、APIが呼ばれていないこと(課金が発生しないこと)。無人パイプラインでこのフラグを使ったスクリプトを配布・共有する場合、実行環境のバージョンがv2.1.261未満だとその場でジョブ全体が失敗することを意味する。過去の検証(2026-08-30の--restricted、2026-08-27の--permission-prompts)と同じ「CLIフラグは即座に声を上げて止まる」パターンの再現。

プロンプト3: 設定キーの版差チェック(bashOutputMaxChars)

前提: uv(またはPython)が使えること。stream-json形式の出力を1行ずつJSONとして読める状態。

claude -p "Run this bash command exactly: uv run python -c \"print(chr(65)*60000)\"" \
  --output-format stream-json --verbose \
  --settings '{"bashOutputMaxChars": 100000}' \
  > /tmp/stream_out.jsonl
uv run python -c "
import json
for line in open('/tmp/stream_out.jsonl'):
    line = line.strip()
    if not line:
        continue
    obj = json.loads(line)
    if obj.get('type') != 'user':
        continue
    content = obj.get('message', {}).get('content')
    if not isinstance(content, list):
        continue
    for c in content:
        if c.get('type') == 'tool_result':
            txt = c.get('content')
            if isinstance(txt, str):
                print('tool_result length:', len(txt))
                print(txt[:200])
"

期待結果: bashOutputMaxCharsを100000に上げたつもりでも、対応していないバージョンでは無視され、既存のデフォルト閾値でファイル保存に切り替わる。筆者の環境(v2.1.258)での実際の出力:

tool_result length: 2226
<persisted-output>
Output too large (58.6KB). Full output saved to: /Users/harkingbee/.claude/projects/.../tool-results/bp9sy5026.txt

Preview (first 2KB)

エラーは一切出ない。同じコマンドを--settingsなしで実行した場合と全く同じ「58.6KBでファイル保存」という結果になることも確認済み(比較実験)。

成功判定: tool_resultの中身が<persisted-output>で始まり、Output too largeという文言とファイルパスが含まれていれば、設定は効いておらず無言で無視されている。過去の検証(2026-08-27のpromptCacheTtl、2026-08-30のPreModelSwitch)と同じ「設定ファイル経由の新機能は無言で無視される」パターンの再現。

プロンプト4: スラッシュコマンドの版差チェック(/skill-doctor)

前提: なし(追加ファイル不要)。

claude -p "/skill-doctor" --output-format json > /tmp/skilldoctor.json
uv run python -c "
import json
d = json.load(open('/tmp/skilldoctor.json'))
print('total_cost_usd:', d.get('total_cost_usd'))
print('duration_ms:', d.get('duration_ms'))
print(d.get('result')[:400])
"

期待結果: プロンプト2・3とは違い、v2.1.258でも完全に動作した。実際の出力(抜粋):

total_cost_usd: 0
duration_ms: 373

Skills loaded this session

  skill              source        context  7d tokens   uses  last used
  agents-sdk         userSettings     ~150          -     0×  never
  ...
31 skills loaded but never invoked. Each one adds to the system prompt every turn. Disable in /skills, or remove from .claude/skills.
162 plugin skills loaded but never invoked, from planning-with-files, differential-review, ...

成功判定: total_cost_usdが0、duration_msが1秒未満で、スキル一覧の表と「N skills loaded but never invoked」という要約行が出力されていればOK。APIを一切呼ばずローカルで完結している(コストが発生しない)ことが、この結果の最大のポイント。

注意: /skill-doctorの「7d tokens」欄はClaude Code自身が計算した推定値で、筆者が独自に集計し直したものではない。ここではCLIが出した数値をそのまま引用している。

プロンプト5: この記事で使った検証を1本の監査スクリプトに統合する

前提: プロンプト1〜4を個別に試した後、まとめて回せるようにする。

#!/bin/bash
# context_budget_audit.sh — v2.1.261の3機能を版差込みで一括チェックする
set -euo pipefail

echo "== 1. バージョン =="
claude --version

echo "== 2. --append-subagent-system-prompt-file (CLIフラグ) =="
echo "test" > /tmp/subagent_prompt.txt
if claude --append-subagent-system-prompt-file /tmp/subagent_prompt.txt -p "ok" 2>/tmp/flag_err.txt; then
  echo "動作した(APIコスト発生の可能性あり)"
else
  echo "即エラー: $(cat /tmp/flag_err.txt)"
fi

echo "== 3. /skill-doctor (スラッシュコマンド、ローカル完結) =="
claude -p "/skill-doctor" --output-format json > /tmp/sd.json
uv run python -c "
import json
d = json.load(open('/tmp/sd.json'))
print('cost:', d.get('total_cost_usd'), '/ duration_ms:', d.get('duration_ms'))
"

期待結果: セクション2はclaudeが対応バージョン未満なら「即エラー」、対応していれば「動作した」と表示される。セクション3は対応バージョンに関わらずコスト0が出る(今回の実測ではv2.1.258でも動いたため)。

成功判定: 3つのセクションがすべてエラーで落ちずに最後まで実行され、バージョンに応じた仕分け結果が手元に残ること。このスクリプト自体はset -euo pipefailを使っているが、||やifで失敗を捕まえているコマンドはパイプライン全体を止めない設計にしている点に注意(そうしないとプロンプト2の即エラーでスクリプトごと落ちる)。

プロンプト6: 自分の環境のスキル過多を/skill-doctorで棚卸しする(活用例)

前提: すでにclaudeを使い込んでいるプロジェクトディレクトリであること。

claude -p "/skill-doctor" --output-format json | uv run python -c "
import json, sys
d = json.load(sys.stdin)
result = d.get('result', '')
for line in result.splitlines():
    if 'never invoked' in line:
        print(line)
"

期待結果: 「N skills loaded but never invoked」「M plugin skills loaded but never invoked, from …」という要約行だけが抽出される。筆者の環境では実際に「31 skills loaded but never invoked」「162 plugin skills loaded but never invoked」という結果が出た。

成功判定: 数字が1つでも表示されればOK。ゼロなら棚卸しの必要はない。この記事の筆者の環境のように数十〜100件を超える「未使用スキル」が出た場合、/skillsで個別スキルを無効化するか、/pluginでプラグイン単位で無効化することを検討する材料になる(プラグインスキルは個別無効化ができず、プラグイン単位でしか止められないと出力にも明記されている)。

活用例: 無人パイプラインのコンテキスト予算監査フローへの統合

このブログ自身の自動投稿パイプライン(daily_post_runner.sh)は、review_quality.pyのような検証スクリプトの出力やgh apiの結果など、まとまった量の出力をBashツール経由で読ませる場面が多い。今回の検証は、次の3段構えの運用ルールにまとめられる。

  1. /skill-doctorは今すぐ、定期的に回せる: APIコストがゼロでローカル完結するため、healthcheck.shのような既存の見張りスクリプトに1行追加するだけで、スキル・プラグインが増えすぎてコンテキストを圧迫していないかを毎回無料で確認できる。
  2. bashOutputMaxChars/taskOutputMaxCharsはバージョンを上げてから使う: 対応前のバージョンで設定しても警告なく無視され、出力は引き続き閾値(実測で58.6KB)を超えるとファイル保存に切り替わる。設定したつもりで実は効いていない、という事故を避けるには、導入前に本記事のプロンプト3のような対照実験でバージョン対応を確認するべき。
  3. --append-subagent-system-prompt-fileは互換性チェックを先に入れる: CIやcronで無人実行するスクリプトにこのフラグを組み込む場合、claude --versionでv2.1.261以上であることを確認してから使う分岐を入れないと、対応前のバージョンではジョブ全体が即座に失敗する。

注意点・つまずき所

  • スラッシュコマンドはCLIフラグ・設定キーと壊れ方が違う: これまでの検証(2026-08-27, 08-30)では「CLIフラグは即エラー」「設定ファイルは無言無視」の二極だったが、/skill-doctorは対応バージョンに届いていなくても完全に動作した。CHANGELOG.mdのv2.1.261には「Fixed feature flags gated to a newer version occasionally applying to an older Claude Code version running on the same machine(新しいバージョン向けの機能フラグが、同じマシン上の古いClaude Codeにまで稀に適用されてしまう不具合を修正)」という一文があり、今回観測した動作はこの現象そのものの可能性がある。ただしこの記事のために原因をClaude Code社内のソースコードで確認したわけではないため、あくまで公表されている不具合の説明と実測結果が一致するという指摘に留め、断定はしない。
  • /skill-doctorは「セッションを開始せずに」ではない: GitHub Issue #82169(open、2026-07-29作成)は「セッションを開始せず(APIコール無し)にロード済みスキル一覧を見るCLIコマンドが欲しい」という要望で、/skill-doctorはこの要望にかなり近い。ただし実際にはclaude -p "/skill-doctor"はセッションIDを1つ発行しており、文字どおり「セッションを開始しない」わけではない。重要なのは「APIを呼ばずコストがゼロ」という点であり、Issueの要望と完全に同一の実装かどうかは筆者には確認できない。
  • 設定キーが無視されても失敗しないことが逆に危険: bashOutputMaxCharsを設定してもエラーが出ないため、無人パイプラインのログを見ただけでは「設定が効いていない」ことに気づけない。本記事のプロンプト3のように、意図的に閾値を超える出力を発生させてtool_resultの中身を直接確認する対照実験をしない限り、設定ミスは表面化しない。
  • この記事の実測は手元のv2.1.258限定: v2.1.261がリリースされてから約1日というタイミングでの検証であり、v2.1.259・v2.1.260の間に段階的な変更があった可能性は確認していない。バージョンを上げた環境では挙動が異なることがありうる。

締め: 今日やること

まずclaude --versionを確認し、v2.1.261に届いていなければプロンプト4(/skill-doctor)だけを今すぐ試すとよい。コストがかからず、副作用もなく、今の環境にどれだけ「使われていないスキル」が乗っているかが数値で分かる。CLIフラグと設定キーの2つは、バージョンを上げるか、上げる前に本記事のプロンプト2・3で「壊れ方」を確認してから使うかを、パイプラインの重要度に応じて判断すればよい。

Comments

Copied title and URL