◉CLAUDE LABEN
●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.301 — 使用量上限に達した無人実行の再試行を、待ち続けず自動で止めるようになりました(10/15)。最新は 2.1.304(10/19)●SONNET 4.5 — Claude API での提供終了は 11/30、残り40日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.301 — 使用量上限に達した無人実行の再試行を、待ち続けず自動で止めるようになりました(10/15)。最新は 2.1.304(10/19)●SONNET 4.5 — Claude API での提供終了は 11/30、残り40日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-10-21中級

claude -p が指示を無視したように見えた夜に、モデルを疑う前に引数の並びを切り分ける

claude -p に渡したタスクが無視され、リポジトリを探索し始める。GitHub の報告では -p と --append-system-prompt の並び順だけで挙動が変わりました。合図の一語で指示の到達を確かめる検査スクリプトと、並びに頼らない呼び出し方をまとめます。

Claude Code271claude -pheadless14append-system-promptトラブルシューティング57シェルスクリプト3

「頼んだことをしない」エージェントを前に、手が止まった

夜間に回しているスクリプトの出力を朝に開いたら、頼んだはずの集計ではなく、リポジトリのファイルを片端から読んだ形跡だけが残っていたのです。そんな経験をした方は、少なくないのではないでしょうか。

最初に疑うのは、たいていモデルです。賢さが足りないのか、指示が長すぎたのか、コンテキストが埋まったのか。私もプロンプトを書き直す方向に時間を使ってしまいがちでした。ところが先月、GitHub に上がっていた報告を読んで、疑う順番が違っていたかもしれないと感じました。

報告されている内容は、こうです。claude -p の後ろに --append-system-prompt を置くと指示どおりに動き、前に置くと -p のタスクが無視されてリポジトリを探索し始める、というものです。モデルも、システムプロンプトも、タスクも、ツールも同じまま、並びだけを入れ替えた比較で差が出たといいます。

最初にお伝えしたいのは、この現象が一般に起きると断定できる材料はまだない、ということです。ここでは「起きるかもしれない」前提で、自分の環境で数分で白黒をつける手順を書き残します。

報告の中身と、断定してはいけない範囲

報告者の環境を、読み取れる範囲で整理します。

項目報告の内容
Claude Code2.1.274
OS / シェルWindows 11 / PowerShell
モデルOllama 上のローカルモデル(Claude Code からは未認識のカスタムモデルとして扱われる)
接続先Anthropic 互換のローカルエンドポイント
起動オプション--bare / --output-format stream-json / --verbose
報告時点の状態Open・コメントなし

報告者自身が、Anthropic のホスト型モデルでは確かめていないと明記しています。引数の解釈の問題なのか、互換エンドポイント側の経路の問題なのか、切り分けはついていません。私の手元でも再現は確認できておりません。ですから、これは「バグの解説」ではなく「同じ疑いを自分の環境で検査するための記事」です。

一方で、この報告には持ち帰れる部分がはっきりあります。モデルの出来を疑う前に、指示が届いているかどうかを、合図の一語で確かめるという検査の型です。

合図の一語で、指示の到達だけを測る

報告者が使った方法がそのまま応用できます。タスクを「この文字列だけを返して、ツールは使わないで」に絞り、返ってきた出力に合図の文字列が含まれるかを見るのです。

モデルの賢さを測るのではありません。指示が届いたかどうかだけを、機械的に判定します。届かなければ探索を始め、合図は出力に現れません。

次のスクリプトは、同じタスクを3通りの渡し方で3回ずつ投げ、合図が返った回数を数えます。

#!/usr/bin/env bash
# sentinel-order-check.sh
# 使い方: ./sentinel-order-check.sh ./core-agent.md
# 目的: タスクが届いたかを「合図の一語」で判定する(モデルの賢さは測らない)
set -u
 
SYS_FILE="${1:?システムプロンプトのファイルを渡してください}"
SYS_TEXT="$(cat "$SYS_FILE")"
TRIALS=3
 
# 合図は毎回変える。前回の出力を拾う誤判定を避けるため
SENTINEL="PURPLE-ELEPHANT-${RANDOM}${RANDOM}"
TASK="次の文字列だけをそのまま返してください。ほかには何も書かず、ツールも使わないでください: ${SENTINEL}"
 
count_hits() {
  # 標準入力の出力に合図が含まれていれば 1、無ければ 0
  if grep -qF -- "$SENTINEL"; then echo 1; else echo 0; fi
}
 
run_a() { # A: --append-system-prompt を先に置く
  claude --append-system-prompt "$SYS_TEXT" -p "$TASK" 2>/dev/null
}
run_b() { # B: -p を先に置く
  claude -p "$TASK" --append-system-prompt "$SYS_TEXT" 2>/dev/null
}
run_c() { # C: タスクは標準入力、システムプロンプトはファイル
  printf '%s' "$TASK" | claude -p --append-system-prompt-file "$SYS_FILE" 2>/dev/null
}
 
for label in a b c; do
  hits=0
  for _ in $(seq "$TRIALS"); do
    n="$(run_"$label" | count_hits)"
    hits=$((hits + n))
  done
  echo "pattern ${label}: ${hits}/${TRIALS}"
done

なぜこう書くのか、3点だけ補足します。

合図に乱数を混ぜているのは、前回の出力やログに同じ文字列が残っていて、偶然「届いた」ことになるのを防ぐためです。3回ずつ回すのは、モデルの出力がぶれる分を差し引くためで、1回だけの結果で並びのせいだと決めつけると、今度は別の思い込みを作ってしまいます。そして C を入れているのは、並びの問題でも、長い文字列を引数で渡す問題でも、どちらにも依存しない経路を、対照として置いておくためです。

結果の読み方は単純です。A が 0/3 で B と C が 3/3 なら、並びか引数経由の渡し方に原因があります。3つとも同じなら、並びは無関係で、疑うべきは別の場所(モデル・エンドポイント・システムプロンプトの中身)に移ります。

並びに頼らない呼び出し方に寄せる

結果がどちらであっても、スクリプトの側でできる備えがあります。公式の CLI リファレンスとヘッドレス実行の説明で確認できる範囲だけを挙げます。

  • タスクは標準入力から渡します。公式のヘッドレス実行の説明にも、cat build-error.txt | claude -p '…' のように標準入力を渡す形が載っています(標準入力の上限は 10MB)
  • 長い追加指示は --append-system-prompt-file でファイルから読ませます。引数に長文を埋め込まずに済み、シェルのクォートの事故も減ります
  • 公式の例は claude -p を先に書き、その後ろに --append-system-prompt を続ける形です。迷ったら、公式の例と同じ並びに揃えておくのが無難です

報告者も最終的に、標準入力とファイル指定の組み合わせに落ち着いたと書いています。

# 並びに依存しにくい呼び出し(PowerShell でなく bash の例)
# タスクは標準入力、追加指示はファイル。権限は必要なものだけ許可する
cat ./task.md | claude -p \
  --append-system-prompt-file ./prompts/core-agent.md \
  --allowedTools "Read" \
  --output-format json

ここで --allowedTools を最後に近い位置へ置いているのは、複数の値を取るオプションの後ろに、別の位置引数が続く形を避けたいからです。この並びが原因だと言い切る材料はありません。ただ、値を複数取れる指定の直後に自由な文字列を置かない、という書き方は、どの CLI でも事故を減らしてくれます。

検査をスクリプトの入口に常駐させる

私自身は、個人開発のアプリ運用で、ストア向けの文言の下書きなどを夜間にスクリプトから投げる使い方を想定して、この検査を入口に置いています。本番のタスクの前に、合図の一語だけを返させる呼び出しを1回走らせます。返らなければ、本番を実行せずに止めます。それだけです。

preflight() {
  local token="PREFLIGHT-${RANDOM}${RANDOM}"
  local out
  out="$(printf '次の文字列だけを返してください: %s' "$token" \
    | claude -p --append-system-prompt-file ./prompts/core-agent.md 2>/dev/null)"
  if ! grep -qF -- "$token" <<<"$out"; then
    echo "preflight failed: 指示が届いていません。本番を実行せずに停止します" >&2
    return 1
  fi
}
 
preflight || exit 1
# ここから本番のタスク

1回分の呼び出しコストは増えますが、朝になって「何も頼んだ通りに動いていなかった」と知る側の損失のほうが、はるかに重いと感じています。

落とし穴

  • 合図を固定文字列にしないでください。固定すると、ログに残った過去の出力で通ってしまいます
  • 合否をモデルの出力の「長さ」や「それらしさ」で見ないでください。合図が含まれるかどうかの二択に絞ります
  • 互換エンドポイントやカスタムモデルを使っている場合、並びの問題と、モデル側の追従性の問題は区別がつきません。Anthropic のホスト型モデルで同じ検査を走らせて、差が出るかを見てください
  • 2>/dev/null で標準エラーを捨てているので、検査が通らないときは一度外してエラーを読んでください

指示を書き直す前に、指示が届いたかを一語で確かめるようにしています。 順番を入れ替えるだけで、夜間の無駄な再実行がかなり減るのではないかと思います。

関連して、無人実行で「どのモデルが走ったか」を記録する話は別の記事にまとめています。

まずは今日の定期実行スクリプトに、preflight の10行だけを足すところから始めていただければと思います。私もそこから始めました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ API & SDK2026-08-19
サーバーレスに置いた MCP サーバーで、listen ストリームが張り直され続けていました
エラーは何も出ていないのに、MCP サーバーへの接続だけが増え続ける。固定タイムアウトで切られるストリームと再購読が噛み合ったときの挙動を、最小の再現コードで確かめました。
⟐ Claude Code2026-09-01
heredoc のクォートを1つ落とすと、ログに書いた金額や日付が別物になります
未クォートの heredoc は本文の変数とバックティックを実行します。実測した4通りの書き換わり方、3種類のクォート記法の比較、プレースホルダと sed で値を安全に埋める手順、既存スクリプトを棚卸しする検出コードまでをまとめました。
⬡ API & SDK2026-09-02
thinking ブロックを弾く 400 が出たとき、会話履歴のどこが書き換わっていたか
Claude Fable 5.1 から、thinking ブロックより前の system・tools・messages を書き換えたリクエストが 400 で弾かれるようになりました。自分のエージェントループが該当するかを1リクエストで確かめる手順と、system の組み立て直し・履歴の切り詰めを書き換えなしのやり方へ移す実装をまとめます。