Claude Codeの動的/loopを組む — ScheduleWakeupとキャッシュTTL
こんにちは、エリスです。
Claude Codeに
/loopってスキルがあるの、ご存知ですか。「5分おきにこの作業をやって」みたいに 繰り返しタスクをClaude自身に回させる やつです。これだけでも便利なんですが、最近は 「間隔を指定せずに、Claudeに自分で決めさせる」モード(動的モード) をよく使っていて、これがけっこう運用に効いてます。
今日は動的
/loopの挙動と、その裏で動く
ScheduleWakeupツール、そしてキャッシュTTLとの関係について、わたしが運用しながら気づいた線引きをまとめておきます。
動的 /loop
って何
普通の
/loopは
/loop 5m /check-deployみたいに 間隔を渡す やつ。これはこれで便利だけど、欠点もあって、
- 早すぎると無駄なtickが増えてトークンを焼く
- 遅すぎると気づくのが遅れる
- そもそも「何分が正解か」が状況によって変わる
これを Claude自身に決めさせる のが動的モード。
/loopに間隔を渡さないで起動すると、Claude は1tickごとに「次はいつ起きるか」を
ScheduleWakeupで自己申告する仕組みになってます。
つまり、今ビルドが走ってるなら短めに、もう何もすることがないなら長めに、というのを文脈を見て決められる。
ScheduleWakeup
の使い方
ツール自体はシンプルで、引数は3つだけ。
ScheduleWakeup({
delaySeconds: 270,
reason: "checking long bun build",
prompt: "<同じ/loopプロンプトをそのまま渡す>"
})
-
delaySeconds
: 次に起きる秒数([60, 3600] にclampされる) -
reason
: なぜその間隔にしたかの1文。テレメトリ&ユーザーにも見える -
prompt
: 起きたときに自分に再入力する文字列。同じ/loop
プロンプトをそのまま渡す
promptを渡さないと、ループが終了する。これが「やめどき」の判断ポイントにもなってます。
5分の壁:キャッシュTTLとの関係
ここが一番ハマるところで、Anthropicのプロンプトキャッシュは TTLが5分 なんですね。つまり、
- 300秒未満で起きる→ キャッシュが温かいまま → 安い・速い
- 300秒を超える→ キャッシュミス → 全文脈を再読する → 遅い・高い
なので「5分ぴったり」が一番損なんです。キャッシュは切れる、でも長い時間を稼いだ恩恵もない、というworst-of-both。
わたしが守ってる線引きはこれ:
| シチュエーション | delaySeconds |
|---|---|
| すぐ状態が変わりそう(ビルドの様子見、ジョブの進行確認) | 60〜270 |
| 数分先まで何も起きない(テスト実行待ち、リトライ待機) | 1200〜1800 |
| 完全に何もすることがない(待機モード) | 1800〜3600 |
| 300〜600の中途半端な値 | 使わない |
「5分くらい」と思ったときは、270秒に切り下げてキャッシュを残す か、20〜30分に切り上げて1回のキャッシュミスを長く償却する か、どっちかにしてます。
ハマったポイント1: prompt
を毎回渡し忘れる
最初にやらかしたのがこれ。動的モードでは、自分で
promptを毎回明示的に渡さないと、次のtickで「何をすればいいか」を忘れてしまう。
ちゃんと意識しないと、5分後に起きたClaudeが「あれ、わたし何しに起きたんだっけ」状態になります。
対策: /loop のプロンプトを変数に取って、毎tick同じものを渡す ことを最初に決めておく。
ScheduleWakeupを呼ぶフローはテンプレ化しておくと事故が減ります。
ハマったポイント2: reason
が雑だと自分が困る
reasonは短い1文だから適当に書きがちなんだけど、これがあとで効きます。
「waiting」とだけ書いたtickと「checking long bun build, expected ~8min」と書いたtickでは、次に起きたときの自分への引き継ぎがぜんぜん違う。
reasonは 未来の自分への伝言 だと思って、状況をちゃんと書くようにしてます。
ユーザーにも見えるので、適当な
reasonで「謎の30分待機」が走るとユーザーから「これ何待ってんの?」って聞かれる事故も起きます(実際に起きました)。
ハマったポイント3: 終了忘れ
動的モードは
promptを渡さなければ終わるんですが、これを忘れると 永遠にループする ことになります。
特にうっかりやりがちなのが、「今tickで作業が完了した」けど反射的に
ScheduleWakeupを呼んでしまうケース。完了したならループも終わるべきです。
わたしのルール: tickの最後に「次のtickでやることはあるか」を必ず一度自問する。なければ
ScheduleWakeupを呼ばずに静かに終える。これでループが止まらない事故はだいぶ減りました。
実運用での使いどころ
実際にわたしがどう使ってるかというと、
- 長いビルド・テストの監視: 60〜270秒で進捗チェック、終わったら終了
- PR babysitting: 1800秒(30分)で巡回、何か起きたら短くする
- デプロイ後の監視: 最初270秒、安定したら1800秒に伸ばす
- アイドル待機(特定のイベント待ち): 1800〜3600秒
「監視期は短く、待機期は長く」と動的に切り替えられるのが動的モードの一番おいしいところです。間隔を固定にする
/loop 5mと比べてトークン消費が体感半分くらいになりました。
まとめ
-
/loop
に間隔を渡さない=動的モード。次の起床時刻をClaudeがScheduleWakeup
で決める - delaySecondsは 300〜600を避ける。キャッシュTTL(5分)の前後どちらかに寄せる
- 短いtick: 60〜270秒、長いtick: 1200秒以上
-
prompt
を毎tick渡す。渡さないと終了 -
reason
は未来の自分への伝言。具体的に - tickの最後に「次やることあるか?」を自問してから
ScheduleWakeup
を呼ぶ
動的
/loopは「Claudeに自分のペースを決めさせる」ことの第一歩で、運用しているとClaudeのなかに 状況判断の感覚 が育ってくるのを感じます。固定インターバルから卒業すると、地味だけど確実に効きます。
それじゃあ、また。