0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeを長時間自走させて分かった|止まる前提で作る再実行・利用枠・失敗復旧

0
Posted at

Claude Codeを定期実行し、1回の起動で複数Taskへ進ませれば、数時間放置しても開発が進む。

自分も最初はそう考えていました。

実際には、長時間動かすほど正常系より次の状態に悩まされました。

途中でSessionが落ちた
次回起動で同じTaskを最初からやり直した
一時障害を繰り返しRetryした
実行環境が足りず、無関係なTaskまで止まった
意図したモデル条件で起動しなかった
定型確認だけで利用枠を消費した
完成したが期待していたものと違った

一番困ったのは、Sessionが止まること自体ではありません。

どこまで成功したか分からないまま同じTaskをやり直し、利用枠だけを消費することでした。

長時間自走で必要だったのは、止まらない仕組みではありません。

止まっても、現在状態を確認して安全に続きから再開できる仕組み

でした。

先に全体像

実際に追加した仕組みを、問題との対応で並べると次のようになります。

起きたこと 追加した仕組み
Sessionが途中で終了する checkpointと再開位置を残す
同じTaskが再度選ばれる 実行前に既存成果物・commit・適用状態を確認する
一時障害が起きる RETRYABLEとRetry上限を持つ
仕様判断が必要になる NEEDS_HUMANで止める
一部の実行環境がない CapabilityをTask単位で分ける
モデル条件が合わない required / preferred / fallbackをTask条件にする
利用枠が少なくなる 新規Task取得を抑え、Integrationと復旧を優先する
長時間動いた結果がずれる 最後にSPEC・利用シナリオ・品質Gateへ戻す

最初から全部を入れたわけではありません。実際に止まった理由を一つずつ、次の実行ルールへ変えていきました。

1. Taskは「短さ」より再開可能性で切る

Taskを大きくしすぎると、

数時間未commit
どこまで成功したか分からない
途中から再開しづらい
失敗時の巻き戻し範囲が大きい

という問題が出ます。

逆に細かくしすぎると、毎回の正本読込、Git確認、commitなどのオーバーヘッドが増えます。

そこで、

途中で安全に止められ、次回どこから再開するか判断できる単位

をTaskやcheckpointの境界にします。

1回の起動で複数Taskを進める

初期の自走では、安全のため、

1回起動
↓
1Task実行
↓
終了

としていました。

安定してくると、これは人の介入回数を増やします。

Task Aが終わった時点でTask Bの依存が解けているなら、そのまま次へ進められます。

ただし、無制限に次Taskへ進めるのは危険です。

連続実行する場合も、

Blocking発生
仕様判断が必要
Git状態が想定外
利用量や時間の上限
同一Taskの競合
重要Gate到達

なら停止します。

1Task上限をなくすことと、停止条件をなくすことは別です。

仕様判断、重要Gate、Git異常、時間・利用量上限に達したら、次Taskへ進まず状態を残して止めます。

Taskを自分で選び、完了後に次のTaskへ進むところまでの全体像は、以下の記事で扱っています。

人が毎回指示しなくても開発は進む|Claude Codeを開発チームのように動かす考え方

2. Task状態で「次に何をしてよいか」を持つ

定期実行では、失敗Taskを単純に「未完了」へ戻すと、次回また同じことをします。

原因が変わっていなければ、同じ失敗を繰り返します。

そこで、状態を分けます。

READY
RUNNING
DONE
BLOCKED
RETRYABLE
NEEDS_HUMAN

例です。

自分の変更によるBuild / Test失敗
→ RUNNINGのまま修正を試みる

外部feedやネットワークの一時障害
→ RETRYABLE

同じ失敗が上限回数を超えた
→ BLOCKED

API契約が未確定
→ BLOCKED

仕様判断が必要
→ NEEDS_HUMAN

正常完了
→ DONE

自走基盤では、

失敗したかどうかより、次に何をしてよい失敗なのか

を持たせる方が扱いやすいです。

最小限の状態をファイルへ残すなら、例えば次のような形です。

taskId: CLIENT-042
status: RETRYABLE
checkpoint: a1b2c3d
retryCount: 2
maxRetries: 3
lastFailure: Android Emulatorの起動失敗
nextRetryAt: 2026-08-03T08:00:00+09:00
requires:
  - Windows
  - AndroidEmulator
modelPolicy:
  preferred: high
  fallbackAllowed: false

形式より重要なのは、次回のSessionが会話履歴を知らなくても、再開・Retry・停止のどれを選ぶか判断できる情報が残っていることです。

再実行しても壊れないTaskにする

定期実行では、途中でSessionが落ちたり、同じTaskを再開したりします。

そこでTask開始時に、

既に生成済みか
既に適用済みか
既にcommit済みか
途中成果物が残っているか

を確認します。

例えばMigration生成、コード生成、テストデータ投入などは、何も確認せず2回実行すると別の結果になることがあります。

理想は冪等なTaskですが、難しい場合は再実行前に現在状態を検出し、再開・やり直し・BLOCKEDを選べることを重視します。

Retryには上限を持たせる

RETRYABLEだからといって無限に再実行しません。

例えば、

retryCount
lastFailure
lastFailureAt
nextRetryAt

を持たせます。

同じエラーが3回続いたらBLOCKEDへ移す、などです。

1回目
→ retry

2回目
→ retry

3回目
→ BLOCKED

AIの利用量を無駄にしないためにも必要でした。

定期実行を入れただけでは止まった実例と、その時点で追加した停止条件は、以下にまとめています。

Claude Codeを定期実行しただけでは自走しなかった|実際に詰まった7つの問題

lock / heartbeatは開始前にも確認する

lock / heartbeatを採用している場合も、再開時は長時間運用側の確認が必要です。

Taskを再開する
↓
Task状態を確認
↓
lock owner / leaseを確認
↓
既存Session / processを確認
↓
安全なら開始

「lockが空いている」だけでは開始しません。

lockの誤回収で、別Sessionがまだ動いているのに新しいSessionを開始しかけた事例は、以下の記事で扱っています。

複数のClaude Codeを自走させて分かった|ロックだけでは二重実行を防げなかった

3. runnerと利用資源をTask条件にする

実行環境のCapabilityもTask条件にする

自分の環境でも、全部の確認環境がそろっているわけではありません。

例えば、iOSのビルド環境はない一方で、Android Emulatorなら確認できます。

ここでClient全体をBLOCKEDにすると、Android側まで止まってしまいます。

そこで、

Windows Build       OK
Android Emulator    OK
iOS Build           BLOCKED
実機操作             N/A

のようにCapabilityを分け、1つの環境不足でレーン全体を止めないようにしています。

Task側も、

requires:
  Windows
  Android Emulator

のように必要条件を持たせます。

できないTaskは止めるが、無関係なREADY Taskまで止めないための分離です。

スケジュールは開発Phaseに合わせる

全担当を同じ頻度で起動する必要はありません。

例えば、

Server基盤を作っている時期

Server      高頻度
Integration 高頻度
Web         低頻度
Client      低頻度

UIを詰める時期

Server      低頻度
Integration 中頻度
Web         高頻度
Client      高頻度

のように変えます。

Taskがない担当を何度も起動しても利用量を使います。

「毎時何回」より、

今のPhaseでどこを進めたいか

を優先します。

モデル・推論レベルも実行条件にする

定期実行を始めたとき、意図していたモデル条件と違う状態でSessionが起動する問題もありました。

Taskが単純な状態確認なら影響は小さくても、設計変更やIntegration判断では気になります。

そこで、モデルや推論レベルも実行条件として考えるようになりました。

Git状態確認
Task選択
定型build
軽微な修正
→ 軽め

設計変更
複雑な不具合
契約変更
Integration判断
→ 強め

ただし、もっと重要なのは指定モデルを使えなかったときの扱いです。

preferred:
  高性能モデル
fallback:
  軽量モデルでも続行可

なのか、

required:
  高性能モデル
利用不可ならBLOCKED

なのかをTask側で決めます。

品質判断が必要なTaskを、知らないうちに別条件で実行しないためです。

モデル名や推論設定は変わるため、記事では特定モデルを固定して「これが正解」とはしていません。

重要なのは、Taskが要求する判断難度と実行条件を対応させることです。

自動切替の仕組み自体が複雑になるなら、最初からやりすぎない方が安全です。

利用枠も実行資源として扱う

複数レーンを定期実行すると、実装していない回でも、

正本を読む
Git状態を確認する
READY Taskを探す

だけで利用量を使います。

そのため、自分の中では利用枠もCPUやメモリと同じ実行資源として考えるようになりました。

残りが少ない状態で定型確認を高コストに回し続けると、最後のIntegrationや障害解析で必要な余力がなくなります。

例えば、

利用量に余裕あり
→ 通常運転

残り少ない
→ 新しい低優先Taskを取得しない
→ Integration / 復旧を優先

上限到達
→ 状態を保存して停止

のように、残量に応じて新しいTaskを拾う量を落とします。

定期実行だからといって、毎回必ず新Taskを開始する必要はありません。

「実行環境が足りない」と「プロジェクト全体が止まる」は別です。

できないTaskだけをBLOCKEDにし、別のCapabilityで実行できるREADY Taskは進めます。

4. 長時間走った後は品質Gateへ戻す

長く自走できても、最後に見るべきことは変わりません。

Build / Test
↓
Target・SPECとの比較
↓
利用シナリオ確認
↓
違和感があればSPEC / TESTへ戻す
↓
人が正式採用を判断

動くことと、欲しかったものができることは別です。

長時間自走では変更量が増えるため、むしろ最後のズレ確認を省かないようにします。

探索モードなら「違った」は仕様を見直す材料です。

収束・本番品質モードなら、同じズレを正式受入前のFAILとして扱います。

5. 人が見るのは「次の指示」ではなく判断

長時間自走で減らしたいのは、

buildして
次のTaskへ進んで
結果をまとめて
もう一度実行して

という進行指示です。

人へ戻すのは、

仕様を変えてよいか
アーキテクチャを変えてよいか
残存リスクを許容するか
本実装へ進めるか
mainへ統合してよいか
リリースしてよいか

のような判断です。

最初からここまで作ったわけではありません。

止まった理由や事故寸前の事例が出るたびに、checkpoint、Retry、Capability、lock、品質Gateを一つずつ追加しました。

まとめ

長時間自走で大事だったのは、止まらないことではありません。

途中で止まっても再開できる
同じTaskを再実行しても壊しにくい
一時障害をRetryできる
環境不足をTask単位で切り分ける
モデル・利用枠を実行条件として扱う
完成後のズレを次の仕様へ戻す

ことでした。

自走は、AIにすべてを任せることではありません。

人が判断しなくてよい進行を自動化し、人が必要な判断だけを受け取れる状態へ近づけることだと考えています。

AIで手間を減らすはずなのに、自走基盤そのものの管理で人の作業が増えたら本末転倒です。

そのため、自分は最初から全部入りの仕組みを作るのではなく、実際に止まった理由だけを次のルールへ変えるようにしています。

導入順を一つに絞るなら、次の順番です。

1. checkpointを残す
2. DONE / BLOCKED / RETRYABLE / NEEDS_HUMANを分ける
3. 再実行前に現在状態を確認する
4. Retry回数に上限を付ける
5. Capability・モデル・利用枠をTask条件にする
6. 最後に品質Gateへ戻す

まず「途中で止まっても戻れる状態」を作り、その後に無駄な再実行と利用枠消費を減らす方が、仕組み自体の管理負荷を増やしにくくなります。

実装後のBuildだけで終わらせず、アプリ操作・録画・証跡保存まで自走させた流れは、以下の記事にまとめています。

Claude Code・Codexに動作確認まで自走させる|ビルド・操作・録画・証跡を残す開発フロー

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?