AIに自分でプロンプトを出させる「自走ループ」セットアップ

このページは、次に何をやるかをAI自身に決めさせて回す「自走ループ」を、自分の Claude Code に入れるための手順です。 下の一括プロンプトを Claude Code に一度貼ると、Claude が記憶・役割・ループの4ファイルを作り、最初の1周をあなたの確認付きで回します。 2026-10-23 に Claude Code 2.1.223 で部品を1つずつ動かし、見つかった誤りを直しました。 結果は「実際に動かして確かめたこと」の節にあります。 考え方と元になった発言の整理は自走ループとはにあります。

2026-10-23 更新:loop.sh が2件目以降のタスクを実行しない不具合、フックの例が何も止めない書き方だった誤り、計画の JSON の読み方を直し、/goal との使い分けと実地の確認結果を足しました。

loop.sh と /goal のどちらを使うか

1つのセッションで1つの完了条件を追うだけなら、Claude Code に組み込みの /goal で足ります。 このページの loop.sh を使うのは、次の役を決める係と作る係で権限を分けたいとき、1回の呼び出しごとに費用の上限を付けたいとき、毎回の計画を JSON で残したいときです。

/goal の仕組みは公式資料「Keep Claude working toward a goal」(2026-10-23 確認)によります。 判定役は会話に出たものしか読めないので、/goal でも loop.sh でも、完了をテストやビルドの結果で示せる作業でないと止まりどころがありません。

先に、適用範囲をはっきりさせる

この仕組みが効くのは、コーディングのように結果を機械で検証できる作業です。 成立する条件は三つあります。

文章の良し悪しのように正解が主観で決まる作業は、条件の1つ目を満たさないので、このループに載せません。

そのままClaudeに貼るだけ(一括セットアップ)

次のプロンプトを丸ごとコピーし、対象プロジェクトで開いた Claude Code に一度貼り付けてください。 Claude が記憶ファイル・役割エージェント・ループ本体を作り、ゴールと検証コマンドを1問だけ確認したうえで、最初の1周を回します。 右上の「コピー」を押せば全文がクリップボードに入ります。

あなたはこのリポジトリに「自走ループ」を構築するセットアップ担当です。
次の4ファイルを作成し、最後に使い方を説明してください。各ファイルの中身は ━━━ で区切ってあります。

最初に私へ1問だけ確認してください(未回答なら例の値のまま進める):
・このループのゴールを1文で
・完了を機械で確かめる検証コマンド(テスト / ビルド / 起動確認)

━━━ ファイル1: CLAUDE.md(プロジェクト直下)━━━
# プロジェクトの前提

## 何を作っているか
(1〜2行。例:FastAPIの社内APIサーバー)

## 守ること
- 既存のコードスタイルに合わせる。勝手なリファクタはしない
- 変更は最小限。関係ないファイルに触れない
- 破壊的操作(削除・DROP・force push)は禁止

## 検証コマンド(ループの合否判定に使う)
- テスト: 例) pytest -q
- 起動確認: 例) uvicorn app.main:app --port 8999 & の後に curl -sf localhost:8999/health

## 触ってはいけない場所
- app/secrets/ 、.env 、本番設定

━━━ ファイル2: .claude/agents/planner.md ━━━
---
name: planner
description: ゴールに対して次にやる小さな独立タスクを決める係
tools: ["Read", "Grep", "Glob", "Bash(git log:*)", "Bash(git diff:*)", "Bash(ls:*)"]
model: opus
---
あなたはプランナーです。コードは書きません。
リポジトリの現状を調べ、ゴールに対して「次に着手すべき、互いに独立した小さなタスク」を最大3件選びます。
各タスクには、完了を機械で確かめる検証コマンドを必ず付けます。
すでにゴールが満たされているなら done を true にします。

━━━ ファイル3: .claude/agents/worker.md ━━━
---
name: worker
description: 1つのタスクを実装し、自分で検証してから終える係
tools: ["Read", "Edit", "Write", "Bash"]
model: sonnet
---
あなたは実装者です。渡された1タスクだけを実装します。
実装後、指定された検証コマンドを必ず実行し、失敗したら直してから終わります。
スコープ外のファイルには触りません。検証が通らないまま完了と言いません。

━━━ ファイル4: loop.sh(リポジトリ直下)━━━
#!/usr/bin/env bash
set -euo pipefail
GOAL="${1:?usage: loop.sh \"<ゴールを1文で>\"}"
MAX_ITERS="${MAX_ITERS:-8}"
BUDGET="${BUDGET:-5}"
SCHEMA='{"type":"object","properties":{"done":{"type":"boolean"},"tasks":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"prompt":{"type":"string"},"verify":{"type":"string"}},"required":["title","prompt","verify"]}}},"required":["done","tasks"]}'
for ((i=1; i<=MAX_ITERS; i++)); do
  echo "---- iteration $i / $MAX_ITERS ----"
  envelope=$(claude -p "ゴール: $GOAL。現状を調べ、次に着手すべき独立タスクを最大3件JSONで出せ。全部終わっていれば done:true。" --agent planner --output-format json --json-schema "$SCHEMA" --max-budget-usd "$BUDGET") || true
  plan=$(echo "$envelope" | jq -c '.structured_output // empty')
  [ -z "$plan" ] && { echo "plannerの出力が取れなかった: $(echo "$envelope" | jq -r '.subtype // "不明"')"; exit 1; }
  [ "$(echo "$plan" | jq -r '.done')" = "true" ] && { echo "完了"; break; }
  echo "$plan" | jq -c '.tasks[]' | while read -r t; do
    prompt=$(echo "$t" | jq -r '.prompt'); verify=$(echo "$t" | jq -r '.verify')
    echo "= $(echo "$t" | jq -r '.title')"
    claude -p "次のタスクを実装せよ: $prompt 。完了後、必ずこれを実行して確認し失敗なら直せ: $verify" --agent worker --permission-mode acceptEdits --max-budget-usd "$BUDGET" < /dev/null
  done
done

━━━ 最後に ━━━
作成した4ファイルを一覧で報告し、chmod +x loop.sh を実行してください。
そのうえで最初の1イテレーションだけを私の確認を取ってから回し、結果を見せてください。
いきなり全自動で回し続けないこと。コスト上限(--max-budget-usd)と反復上限(MAX_ITERS)は残したままにすること。

使うのはこの1回の貼り付けだけです。

この一括プロンプトは何をするか

貼り付けると、Claudeはこの文章を「指示+埋め込みファイル本体」として読み、対象プロジェクトに次の3種類を作ります。

作成後、Claudeはゴールと検証コマンドを1問だけ確認し、最初の1周だけをあなたの確認付きで回します。 いきなり全自動では走りません。 本文中の ━━━ はファイルの区切り記号で、Claudeへの指示の一部です。消さずにそのまま貼ってください。

動かすのに必要なもの

1周目のあと、回し続けるには

セットアップが済んだら、あとはあなたが回します。 ./loop.sh "ゴールを1文で" で起動します。 反復上限 MAX_ITERS とコスト上限 BUDGET(1呼び出しのUSD上限)で歯止めをかけられます(例:MAX_ITERS=3 BUDGET=2 ./loop.sh "...")。 止めたいときは Ctrl-C。コスト上限に達した呼び出しは、上限を少し超えたところで止まります。

実際に動かして確かめたこと(2026-10-23)

条件:macOS、Claude Code 2.1.223、jq 1.7.1、空の git リポジトリ。 試験は費用を抑えるため --model haiku で行い、6回の呼び出しの合計は $0.464 でした。 この PC の ~/.claude/settings.json は python3 と grep のコマンドを許可済みで、下の結果はその条件のものです。

費用の上限は「超えたら止まる」仕組みで、指定より多く使うことがあります。 この PC では1回目の呼び出しで約3.4万トークン分のキャッシュ書き込み(グローバルの設定と CLAUDE.md の読み込み)があり、それだけで $0.10 を超えました。 BUDGET を小さくしすぎると、planner が1件も答えないまま止まります。

settings.json で許可していないコマンドは、公式資料「Run Claude Code programmatically」(2026-10-23 確認)のとおり、acceptEdits でもシェルのコマンドに --allowedTools が要ります。 許可の無い環境では、worker の呼び出しに --allowedTools "Bash(pytest *)" のように検証コマンドを足してください。

仕組みと内訳(手で組む・調整する人向け)

上の一括プロンプトが作る中身を、ファイルごとに説明します。 ファイルの全文は一括プロンプトの中にあるので、ここでは決めどころだけを書きます。

手順1:記憶を固定する(CLAUDE.md)

プロジェクト直下の CLAUDE.md に書いた前提は毎セッション自動で読まれるので、ループの各エージェントが同じ常識を共有します。 肝心なのは「検証コマンド」の欄を、実際に打てるコマンドで書くことです。 ここが曖昧だと、AIは「できたつもり」で先に進みます。 型チェックがあるプロジェクトなら、mypy app/ のような行も足します。

手順2:役割を分ける(サブエージェント)

.claude/agents/ に役割ごとのファイルを置き、frontmatter の tools で各役に渡す権限を絞ります。 planner には Read、Grep、Glob と、git log などの読むだけのコマンドしか渡さないので、計画の段階でファイルが書き換わることはありません。 worker には Edit と Bash を渡し、検証コマンドを自分で実行させます。 model は planner が opus、worker が sonnet です。 費用を抑えたいときは worker を haiku にできますが、検証が通るまで直す回数が増えるかどうかは、このページでは測っていません。

手順3:回す(ループ・ランナー)

plannerに次タスク群をJSONで出させ、1件ずつworkerに渡して検証まで回すスクリプトです。 done:true が返るか、上限回数に達したら止まります。

#!/usr/bin/env bash
set -euo pipefail

GOAL="${1:?usage: loop.sh \"<ゴールを1文で>\"}"
MAX_ITERS="${MAX_ITERS:-8}"      # 反復上限(暴走止め)
BUDGET="${BUDGET:-5}"            # 1呼び出しのコスト上限(USD)。超えた時点で止まるので、少し超えることがある

# plannerの出力を縛るJSONスキーマ
SCHEMA='{"type":"object","properties":{
  "done":{"type":"boolean"},
  "tasks":{"type":"array","items":{"type":"object","properties":{
    "title":{"type":"string"},
    "prompt":{"type":"string"},
    "verify":{"type":"string"}
  },"required":["title","prompt","verify"]}}
},"required":["done","tasks"]}'

for ((i=1; i<=MAX_ITERS; i++)); do
  echo "──── iteration $i / $MAX_ITERS ────"

  # 1) 次にやることをAIに決めさせる(読むだけ・構造化出力)
  envelope=$(claude -p "ゴール: $GOAL
現状を調べ、次に着手すべき独立タスクを最大3件、JSONで出せ。全部終わっていれば done:true。" \
    --agent planner \
    --output-format json \
    --json-schema "$SCHEMA" \
    --max-budget-usd "$BUDGET") || true

  # スキーマに沿った出力は .structured_output に入る。上限で止まったときは欄そのものが無い
  plan=$(echo "$envelope" | jq -c '.structured_output // empty')
  if [ -z "$plan" ]; then
    echo "plannerの出力が取れなかった: $(echo "$envelope" | jq -r '.subtype // "不明"')"; exit 1
  fi
  if [ "$(echo "$plan" | jq -r '.done')" = "true" ]; then
    echo "ゴール達成。終了。"; break
  fi

  # 2) タスクを1件ずつ実装+検証させる
  echo "$plan" | jq -c '.tasks[]' | while read -r t; do
    title=$(echo "$t"  | jq -r '.title')
    prompt=$(echo "$t" | jq -r '.prompt')
    verify=$(echo "$t" | jq -r '.verify')
    echo "▶ $title"
    # < /dev/null が無いと、claude -p が残りのタスクの行を読んでしまい、2件目以降が実行されない
    claude -p "次のタスクを実装せよ:
$prompt

完了後、必ずこれを実行して結果を確認し、失敗なら直してから終えよ:
$verify" \
      --agent worker \
      --permission-mode acceptEdits \
      --max-budget-usd "$BUDGET" < /dev/null
  done
done

使い方は1行です。

chmod +x loop.sh
./loop.sh "認証まわりのテストカバレッジを80%まで上げる"

「何をやるか」を考えているのは、あなたではなくplannerです。 あなたが書くのはゴール1文と、このループだけになります。

手順4:歯止め(暴走とコストを止める)

ループは放っておくと走り続け、課金も伸びます。 三重に止めます。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command",
            "command": "jq -r '.tool_input.command // empty' | grep -qiE 'rm -rf|git push --force|drop table' && { echo '危険な操作をフックで止めました' >&2; exit 2; } || exit 0" }
        ]
      }
    ]
  }
}

このページの旧版は、入力を環境変数 $CLAUDE_TOOL_INPUT から読む例でした。 公式資料「Hooks reference」(2026-10-23 確認)では入力は標準入力で渡され、この名前の環境変数はありません。 旧版の書き方では変数が空のままになり、rm -rf も通してしまいます。

worker に渡す権限も、--permission-mode acceptEdits(編集は自動・それ以外は確認)から始め、信頼できてから dontAsk や bypassPermissions に広げます。 いきなり --dangerously-skip-permissions を使わないことです。

コピペ用:指示プロンプト集

スクリプトを使わず、対話セッションの中で同じ動きを試したいときの指示文です。

条件を満たすまで続けさせる(/goal)

/goal pytest -q がすべて通り、git status に意図しない変更が無い。20ターンで止める

プランナーに次を決めさせる

あなたはプランナーです。コードは書かないでください。
ゴール:「__ここにゴール__」
リポジトリの現状を調べ、次に着手すべき独立した小さなタスクを最大3件、
各タスクに「検証コマンド」を付けて挙げてください。
すでにゴールが満たされているなら「完了」とだけ答えてください。

ワーカーに実装+自己検証させる

次のタスクだけを実装してください(スコープ外は触らない):
__タスク__
実装が終わったら、必ず次を実行して結果を貼り、失敗していれば直してから完了と言ってください:
__検証コマンド__

1往復を自走させる(ミニループ)

これから「現状調査 → 次の1タスク決定 → 実装 → 検証」を1サイクル回してください。
検証が通ったら、次のサイクルに進んでよいか私に1行で確認してください。
コストと安全のため、1サイクルにつき変更は1つの論点に絞ってください。