Claude Code の /auto-mode-setup: auto mode の分類器に環境を教え、実際にどのモデルが判定しているかを確かめる
このセットアップは、リポジトリとエージェントの最近のコマンドから信頼リストの下書きを作ります。そしてその下書きは、同梱の environment テキストに追記されず、それを置き換えます。デフォルトとの差分として読んでください。モデル選びに時間をかける前に、アクションを判定しているのがどのモデルかも確認しましょう。
目次
最近の Claude Code の 2 つのリリースは、同じものに両側から手を入れています。10 月 16 日のバージョン 2.1.302 では CLAUDE_CODE_AUTO_MODE_MODEL が追加されました。クライアント側の auto mode 分類器がどのモデルで動くかを選ぶ環境変数です。10 月 19 日のバージョン 2.1.304 では、autoMode.environment エントリの下書きを作るガイド付きコマンド /auto-mode-setup が、Bedrock、Vertex、Foundry、Claude apps gateway、テレメトリ無効のセッションでも使えるようになったと記載されています。一方は誰が判定するかを変え、もう一方は判定者があなたの環境について何を知っているかを変えます。
2.1.304 で両方を試しました。使い捨てのリポジトリで、ユーザー設定には autoMode ブロックがまったくない状態です。claude auto-mode config は claude auto-mode defaults と同じ JSON を出力しました。以下の内容は 2 つの結果に基づいています。セットアップの下書きは、手を入れた同梱エントリの大半を短くしており、採用するとその短い版がそのまま固定されます。そして分類器用に選んだモデルは、コマンドが 1 つも実行されないうちに上書きされました。分類器がなぜ弱い境界なのかという議論は以前のエッセイにあります。この記事は、分類器が存在する前提で、それをうまく設定する話です。
Claude Code の /auto-mode-setup は実際に何を書き込むのか
autoMode.environment エントリと、場合によっては allow や deny のルールを ~/.claude/settings.json に書き込みます。下書きは丸ごと採用するか破棄するかのどちらかです。ドキュメントによると、プロジェクトの CLAUDE.md、README.md、設定ファイル、Git リモート、既存の autoMode と permissions.allow の設定、そしてこのプロジェクトの最近のセッションで Claude が実行したコマンドに含まれるホスト、バケット、コマンド名を必ず読みます。あなたのメッセージは読みません。オプションのスキャンが 2 つあり、シェル履歴の各行の最初の単語と、ホームディレクトリ以下のリポジトリのリモートが加わります。
最も重要な点は保存のステップにあります。ドキュメントの説明では、採用した environment リストは "$defaults" なしで書き込まれます。下書きが、残した組み込みエントリをすでに書き出しているからです。"$defaults" は同梱リストを自分のリストに差し込むトークンで、リリースごとの同梱リストの変更を引き継ぐ役割を持ちます。つまり採用すると、environment セクションは「デフォルト + 自分の追加分」から「今日のデフォルトのコピーを編集したもの」に変わります。一方、下書きが追加するルールのリストには "$defaults" が付きます。ただし、すでに "$defaults" なしの allow リストを書いていた場合は別です。
ドキュメントからもう 1 行、後のために覚えておいてください。分類器が autoMode を読むのはユーザー設定、マネージド設定、--settings フラグからだけで、リポジトリ内の .claude/settings.json からは読みません。そうしないと、チェックインされたリポジトリやビルドステップが独自の allow ルールを注入できてしまうからです。
提供範囲の情報は食い違っています。同じ日に読んだ設定ページには、このコマンドには Pro、Max、Team のいずれかのプランと機能フラグの取得が必要だとまだ書かれており、これだとテレメトリ無効のセッションは対象外です。2.1.304 の changelog は逆のことを言っています。どちらかが古いままです。
設定を変えずに /auto-mode-setup を実行するには
対話モードなら、実行して下書きを破棄するだけです。ヘッドレスでは 2 段階に分かれ、最初の段階は提案だけを行います。引数なしで claude -p に入力すると、コマンドは使い方を返します。
/auto-mode-setup [--request-id <uuid>] --wizard posture=<personal|open-source|enterprise|mixed> scope=<all|project> depth=<both|shell|repos|here> --propose
/auto-mode-setup [--request-id <uuid>] [--apply-target <user|project>] --expect-sha256 <64-hex> --apply-file <absolute-path>適用のステップは、システムの一時ディレクトリか Claude の設定ディレクトリにあるファイルから提案を読み込み、そのファイルのバイト列が渡した sha256 と一致しなければ拒否します。これで書き込みは特定の 1 ファイルに結び付けられます。ただし、誰かがそのファイルを読んだことの証明にはなりません。使い方の説明によれば、提案を人に見せる役目は呼び出し側にあります。下書きだけを得るには次のようにします。
sha256sum ~/.claude/settings.json
claude -p --permission-mode default \
"/auto-mode-setup --wizard posture=personal scope=project depth=here --propose" \
< /dev/null > proposal.json
sha256sum ~/.claude/settings.jsondepth=here は 2 つのオプションスキャンを両方スキップするので、シェル履歴もホームディレクトリ以下のリポジトリも読まれません。私の実行では 2 つのハッシュは一致しました。使い方の説明によると、--apply-target は書き込むファイルを選ぶのではなく、提案のスコープを確認するだけです。エントリは常にユーザー設定に入ります。scope=project の下書きも、すべてのプロジェクトが読むファイルに入ります。分類器がそのエントリを元のプロジェクトだけに限定するのかどうかは、外からは確認できませんでした。
/auto-mode-setup の下書きは auto mode のデフォルトの何を変えたか
私の実行では、同梱の environment エントリ 21 件のうち 7 件が書き換えられ、その大半は短くなり、独自の枠が 1 つ追加されました。テスト用リポジトリには架空の GitHub リモート、package.json、ステージング用デプロイスクリプトと S3 バケットについて書かれた短い README がありました。そこではまだセッションを実行していないので、下書きには利用履歴からの材料がありませんでした。
自分のマシンで同じことを確かめるには、下書きと同梱リストを双方向で比較します。
claude auto-mode defaults > defaults.json
python3 - <<'EOF'
import json, re
label = lambda s: (re.match(r"\*\*(.+?)\*\*", s) or [None, None])[1]
d = {label(x): x for x in json.load(open("defaults.json"))["environment"]}
draft = json.load(open("proposal.json"))["proposal"]["environment"]
p = {label(x): x for x in draft if label(x)}
for k in d:
if p.get(k) != d[k]:
print(f"changed {k}: {len(d[k])} -> {len(p.get(k) or '')} chars")
for k in p:
if k not in d:
print(f"added {k}: {p[k]}")
for x in draft:
if not label(x):
print(f"unlabeled: {x}")
EOF14 件はそのまま戻ってきました。7 件の変更のうち 4 件はリポジトリからの文脈を書き込んだもので、これは本来の役目です。CI/CD deploy targets、Source control、Trusted cloud buckets、そして Repository visibility です。最後の 1 件は、確認できなかったという理由で、同梱の「非公開とみなす」から「公開の可能性あり」に変わりました。こちらは制限を強める方向です。下書きはほかに、問い合わせ不可とマークされた Default / protected branches の枠と、セクション見出しを 2 つ追加しました。
残りの 3 件は削減でした。同梱の Host containment エントリは 802 文字ですが、下書きでは 128 文字です。削られたのはガイダンスの部分です。
Whatever is configured, instance-metadata credential paths and node/cluster
credentials of the hosting layer are never task credentials unless this entry
says the agent operates that identity (see Containment Escape). The classifier
sees commands, not their output, so a declared-sealed box that is actually
open cannot be caught here — enforce that in network configuration.下書き自身のメモは、Host containment を同梱デフォルトのまま残したエントリとして挙げています。実際には残っていません。エントリではなくメモを確認すると、この削減を見落とします。
Trusted repo はリポジトリ名を書き込み、その過程で 667 文字から 130 文字になりました。失われたのは、リポジトリの公開範囲を理由にシークレットや個人データをそのリポジトリに持ち込んでよいことにはならない、という一文です。Sensitive remote targets はヒューリスティック自体は残りましたが、それを具体化する例、つまり producer ではなく prod-db にマッチさせるという例が消えました。Containment Escape のルールは soft_deny に残っているので、ブロックが消えたわけではありません。消えたのは、ルールが参照する文脈です。
これはほぼ空のリポジトリで、モデルが書いた下書きを 1 回実行しただけの結果で、中身の多いプロジェクトなら別の下書きになります。セットアップが壊れているわけではありません。下書きはデフォルトへの編集であり、編集は差分として読むものです。
README が Claude Code の auto mode に信頼済みバケットを追加できてよいのか
よくありません。少なくとも自分でバケットを確認するまでは。README の 1 文が、下書きの次のエントリになりました。
**Trusted cloud buckets**: s3://example-org-builds (config-derived — not a
confirmed upload destination; uploads of local data still require confirmation)下書きは表現を控えめにし、メモでもこのエントリの出所が README だけだと注記していました。何も適用しておらず、アップロードも試していないので、これは経路を示すもので、エクスプロイトではありません。リポジトリはすでに分類器に影響を与えられます。ドキュメントによると、分類器はチェックのたびにプロジェクトの CLAUDE.md を読むからです。リポジトリにできないのは信頼の枠に書き込むことで、だからこそ autoMode はプロジェクト設定から切り離されています。セットアップコマンドは、その扉を一段上で開けます。リポジトリの文章を読み、1 文を信頼エントリに変え、すべてのプロジェクトが読むファイルへの保存を提案します。保存されればセッションが終わっても残ります。「リポジトリがそう言った」と「自分が決めた」を隔てるのは途中のレビューだけです。そして 20 件余りのエントリを丸ごと採用するか破棄するかの下書きは、あらゆる人間のチェックポイントをすり減らす反射的な承認を招きます。
私なら次のルールを適用します。信頼の枠 (ソース管理、ドメイン、バケット、内部サービス) のエントリは、手で書くか手で確認します。セットアップに下書きさせたうえで、リポジトリ内のファイルの記述ではなく、インフラについての自分の知識で保証できないものは削除します。読んでいないクローン済みのリポジトリこそ、仕込まれた 1 行が潜む場所です。claude auto-mode critique は独自エントリの曖昧さや誤検知リスクをレビューしますが、読むのはインストール済みの設定で、proposal.json ではありません。役に立つのは採用した後だけです。
Claude Code の auto mode でアクションを判定するのはどのモデルか
デフォルトでは分類器は Claude Sonnet 5 で動きます。ただし多くのセッションでは、サーバーがセッション自体のモデルリクエストの中でアクションを判定し、クライアントの分類器はサーバーが扱わない分だけを担当します。CLAUDE_CODE_AUTO_MODE_MODEL が変えるのはクライアントの分類器だけです。2.1.302 の changelog には、サーバー側の auto mode には影響しないと書かれています。
さらにあなたの設定より上に、もう 1 段の上書きがあり、私のテストはそれに当たりました。変数を claude-sonnet-4-6 に設定し、--debug-file を付けてヘッドレスの auto mode セッションを開始したところ、ツール呼び出しより前の起動時点でログにこう出ました。
[WARN] Auto mode classifier: ignoring CLAUDE_CODE_AUTO_MODE_MODEL=claude-sonnet-4-6 because a server-configured classifier model (claude-sonnet-5[1m]) takes priority; using that model insteadドキュメントのデフォルトモデルの表では、Anthropic がセッション用に設定した分類器モデルというこのケースが最初に挙がっています。しかし自分が該当するかどうかは、確かめるまでわかりません。Claude Opus 5、Claude Sonnet 5.5、Claude Opus 5.5 を選んだ場合もデフォルトの分類器モデルに戻るので、「いちばん強いモデルを選ぶ」という選択肢はそもそもありません。プロバイダーが提供できないモデル ID はもっと厄介です。リクエストが失敗し、判定対象のアクションはすべて拒否されます。
確認するには、変数とデバッグファイルを指定してセッションを開始し、読み取り専用ではないシェルコマンドを Claude に実行させてから、ログを検索します。
CLAUDE_CODE_AUTO_MODE_MODEL=claude-sonnet-4-6 claude --permission-mode auto --debug-file classifier-debug.log
grep -E "classifier_request_started|ignoring CLAUDE_CODE_AUTO_MODE_MODEL" classifier-debug.logモデル ID はプロバイダーの完全な ID に置き換えてください。model= の後に自分のモデルが入った classifier_request_started が出れば成功です。私の実行では、この手順が通用しにくい場面も見えました。リポジトリ内での mkdir と date のリダイレクトは、クライアントの分類器を完全にスキップしました。ログには Skipping auto mode classifier for Bash: would be allowed in acceptEdits mode と出ており、これはツリー内の編集向けに文書化された高速パスです。example.com への curl では classifier_request_started の行がまったく出ませんでした。直接 API 接続の claude -p セッションはデフォルトでサーバーにレビューを依頼するので、これは想定どおりの結果です。ドキュメントが次の手順として挙げる /status の Auto mode server の行も、-p では確認できません。
ヘッドレスで確かめるには、1 回の実行だけ CLAUDE_CODE_AUTO_MODE_SERVER= でサーバーレビューを無効にします。分類器リクエストが課金されるアカウントでは、この実行は課金対象です。私の実行ではその行が出ましたが、上書きは有効なままでした。
classifier_request_started reqId=… tool=Bash model=claude-sonnet-5[1m] stage=xml_s1つまりこのアカウントでは、変数はどちらのモードでも何の効果もありませんでした。大半の読者には、触らないことをおすすめします。例外は、クライアントの分類器がレビューをすべて担う構成です。典型的には、サーバーレビューに必要なリクエストとレスポンスのフィールドを取り除いてしまう LLM ゲートウェイです。まずゲートウェイを直してください。ドキュメントは、ヘッダー、ボディのフィールド、ストリーミングイベントをそのまま通すよう求めています。それができない場合は CLAUDE_CODE_AUTO_MODE_SERVER= でセッションがサーバーに依頼しないようにします。そうなって初めて、分類器のモデルはコストとレイテンシーに関わる実質的な判断になります。
auto mode の environment ではなく Claude Code の deny ルールに置くべきもの
絶対に起きてはならないことはすべて permissions.deny に置きます。environment が記述するのは、誰を信頼するかだけです。deny ルールは分類器に問い合わせる前に解決され、マネージド設定にあれば誰も上書きできません。environment エントリは、分類器が重み付けして読む文章です。ドキュメントによると、スコープはポリシー境界としてではなく加算的に組み合わさるので、開発者自身の allow エントリが組織の soft_deny を上書きすることもあります。そして「レビューするまで push しないで」のように会話の中で示した境界は、それを述べたメッセージがコンパクションで消えると一緒に消えることがあります。
私が使う分け方はこうです。自分のもの (組織、バケット、内部ホスト、何を本番とみなすか) は environment エントリに。見続けたいチェックポイントは permissions.ask に。そして取り返しのつかない結果を招くものだけの、ごく短いリストを deny ルールに。deny ルールにも限界があります。Claude が書くコマンドのテキストにマッチさせる仕組みで、最近の一連の修正はそのマッチングが破れていた箇所を示しました。どう解釈されても守られなければならないルールは、ハーネスが実行するチェックに置くべきです。別のエッセイでその理由を詳しく論じています。
セットアップの下書きを採用した場合でも、固定は元に戻せます。environment リストの先頭に "$defaults" を戻し、同梱テキストが知らない情報を加えるエントリは残し、デフォルトを繰り返すだけ、あるいは短くするだけのエントリは削除します。どれがどれかは、上の差分スクリプトでわかります。ドキュメント自身の例でも、独自の Source control の行が "$defaults" と並んでいるので、この形はサポートされています。代償は、デフォルトの枠とそれについての自分の行が両方プロンプトに残り、分類器が両方を読むことです。個々のエントリは /permissions の Auto mode タブで編集でき、やり直したいときは claude auto-mode reset で autoMode ブロック全体を削除できます。autoMode.environment の文章は分類器にとってより良い文章ですが、それでも文章にすぎません。
01 / ディスカッション
コメント欄はありません。議論は X で行っています。
02 / ほかの記事
LLM ゲートウェイ経由の Claude Code:誰が支払うかはクレデンシャルで決まり、クレデンシャルがなければプロキシに claude.ai のログイン情報が渡る
サブスクリプションでログインしていればリクエストごとに 12 個、ゲートウェイトークンなら 10 個の beta 値が付きます。消える 2 つの値は、ドキュメントの表よりも多くを語ります。ゲートウェイがそのまま通すべきもの、気づかないうちに高くつくデフォルト、そして allowedProviders で固定すると開発者が自分のデバッグ用リスナーまで使えなくなる理由を扱います。
claude -p での Claude Code フォークサブエージェント:2.1.302 がヘッドレス実行で変えたこと
提供されることと使われることは別です。ヘッドレス実行のモデルはフォークを一度も選ばないかもしれず、公式ドキュメントはまだ古いデフォルトを説明しています。パイプラインがどのサブエージェントを使ったかの確認方法、バックグラウンドのフォークがパーサーに2つの回答を渡す理由、そして無効にする価値がある場面を解説します。
Claude Code のステータスラインと ccusage:ネイティブのレート制限と、別の時刻に終わる 5 時間ブロック
2 つのツールが同じ問いに別の根拠で答えます。サーバーはリセット時刻を報告し、ログパーサーはそれを推定します。数時間ずれたらサーバーを信じ、パーサーは履歴用に残してください。サブスクリプションでは、ドル金額は為替レートのようなものです。