手元の Mac や小さなサーバーで、AI エージェントに毎日いくつもの集計やレポートを無人で作らせている方向けの構築ログです。同時に動かす本数と「どこまで待つか」の上限を、1 本の所要時間と本数から見積もる方法が分かり、自分の環境で止まりにくい設定を選べるようになります。
この記事で分かること
- 6 本を同時 5 本・待ち上限 12 時間で回したとき、なぜ 6 本目だけが止まったのか
- 総時間を「波の数 × 1 本の時間」で見積もる簡易モデルと、同時数・再試行ごとの試算表
- 同時 6 本・待ち上限 20 時間に変えて解決すること、解決しないこと
- 翌日の実行と重なったときに何が起き、どう取り戻すか
ざっくり言うと:止まったのは 6 本目だけで、原因は順番待ち
筆者はこのサイトの運用で、毎朝 6 本の記事の下書きを AI に作らせています。2026-11-06 の実行は約 14.6 時間かかり、6 本目だけが待ち上限の 12 時間で止められました。
原因は、同時に動かせるのが 5 本で、途中で外れた記事を予備に差し替えたぶん、順番待ちが延びたことです。そこで同時に動かす本数を 6 本に、待ち上限を 20 時間に変えました。
ただし、波を塊で数える簡易モデルの上では、同時 6 本で短くなるのは「差し替えが 1 本も出ない日」だけでした。差し替えが出る日に 6 本目を止めないのは、主に 20 時間の上限のほうです。
実際は、外れた記事の枠が空けば予備がすぐ入るので、差し替えのある日も短くなる余地があります。どこまで短くなるかは、本番の実行で測ります。
構成:launchd から 6 本の Workflow まで
まず、毎日の実行がどの部品でつながっているかを整理します。図 1 のとおり、4 つの部品が順に呼び出す形です。
| 部品 | 役割 | この記事で関係する設定 |
|---|---|---|
| launchd(macOS の定期実行の仕組み) | 毎日 06:30 に入口スクリプトを起動する | 起動時刻 |
| 入口スクリプト | ロックを取り、作業用フォルダを最新に合わせる | ロック中なら何もせず終わる |
| claude -p(Claude Code を人の操作なしで動かす起動方法) | Workflow を裏で動かし、終わるまで待つ | 待ち上限 |
| Workflow(複数の担当を順に動かす台本) | 6 本の記事を並行して作る | 同時に動かす本数 |
claude -p は、権限の確認が必要な操作を断る dontAsk モード(事前に許可したツールだけを使うモード)で動かしています。公式ドキュメントでは、このモードは CI(コードを自動チェックする仕組み)やスクリプト向けと説明されています(Claude Code: Permission modes)。
何が起きたか:約 14.6 時間の実行と、止まった 6 本目
2026-11-06 の実行は 06:30:05 に始まり、claude -p の結果判定が出たのは 21:08:28 でした。筆者がこの 2 つの時刻から計算すると約 14.6 時間です(作業記録の本文では約 14.5 時間と丸めて書いていました)。
実行ログには「最後の応答から 12 時間たっても裏の処理が動いているので止める」という趣旨の記録が残っていました。判定は「一部失敗」で、6 本のうち 1 本が完成しなかった扱いです。
1 本ごとの時間を読み取る
各記事の正確な開始・終了の記録は残っていませんでした。そこで、作業フォルダに残るファイルの更新時刻から読み取りました。開始は調査結果を置く sources フォルダ、終了は最後の成果物(PR の本文ファイル。PR はプルリクエストの略で、変更を取り込む前に確認を頼む申請のこと)の更新時刻です。
フォルダの更新時刻は「作業が始まった瞬間」そのものではありません。下の表と図 2 は、誤差が数十分ある概算として読んでください。
| 記事(略称) | 開始 | 終了 | 06:30 から開始(時間) | 06:30 から終了(時間) | 所要(時間) |
|---|---|---|---|---|---|
| 副業ルール | 08:02 | 13:23 | 1.53 | 6.88 | 5.35 |
| GitHub トークン | 07:22 | 13:46 | 0.87 | 7.27 | 6.40 |
| SQL レビュー | 07:22 | 16:09 | 0.87 | 9.65 | 8.78 |
| 表の検証 | 08:06 | 16:16 | 1.6 | 9.77 | 8.17 |
| 損益分岐(予備) | 12:22 | 16:00 | 5.87 | 9.5 | 3.63 |
| 自動公開(予備・6 本目)※ | 14:54 | 23:28 | 8.4 | 16.97 | 8.57 |
※ 6 本目の終了 23:28 は、claude -p が止まった 21:08 より後です。止められた後に再開した分を含むため、通常の 1 本の所要時間としては扱いません。
図 2 のとおり、再開分を含む 6 本目を除くと、1 本の所要は約 3.6〜8.8 時間でした。最初に始めたうちの 2 本は途中で外れ、予備の 2 本に差し替わっています。外れた 2 本は終了の記録がないため、表と図には載せていません。
6 本目は、ほかの担当が枠を空けるのを待ってから始まりました。そのため、始まった時点ですでに 06:30 から 8 時間以上たっていました。
6 本目が止められた時刻と、再開した時刻は保存されたログでは確認できませんでした。確認できたのは、claude -p の判定が出た 21:08 より後の 23:28 に、最後のファイルが更新されたことだけです。
もう 1 つ、読み取りで説明できない点が残りました。08:06 までに 6 個のフォルダが更新されており、「同時 5 本」とそのまま読むと 1 個多いのです。フォルダの更新時刻は開始の目安にすぎないので、この記事では無理に説明せず、ずれとして残します。
待っていた時間の大半は AI の呼び出しではない
実行結果の記録では、AI の API(外部のプログラムから AI を呼び出す窓口)に使った時間の合計は 7,719,032 ミリ秒でした。筆者が時間に直すと約 2.1 時間で、壁時計の約 14.6 時間の 15% ほどです。
つまり、長くかかった理由は「AI の返答が遅い」ことだけではありません。順番待ちや、担当がコマンドを動かす時間が大半を占めていたと考えられます。
簡易モデル:総時間 ≒ 波の数 × 1 本の時間
いつ終わるかを見積もるために、次の簡易モデルを使いました。
波の数 = ceil((本数 + 再試行の本数) ÷ 同時数)
総時間 ≒ 波の数 × 1 本の時間
- ceil は「小数点以下を切り上げる」計算です。6 本を同時 5 本で回すと 6 ÷ 5 = 1.2 なので、2 波になります。
- 再試行の本数は、途中で外れて予備に差し替えた本数です。差し替えた本は空いた枠に後から入るので、本数が増えたのと同じに扱います。
- 実際は枠が空いたらすぐ次が入るため、波は時間的に重なります。このモデルは上限側の粗い見積もりです。
2026-11-06 に当てはめると、本数 6・再試行 2・同時 5 なので 8 ÷ 5 = 1.6、切り上げて 2 波です。1 本を 8 時間とすると 16 時間になります。実際の 6 本目は、claude -p が止まった約 14.6 時間の時点でまだ動いていました。これは、2 波・16 時間という見積もりと矛盾しません。
試算表:12 時間・20 時間を超える組み合わせ
次に、同時数を 4〜6 本、1 本の時間を 4・6・8 時間、再試行を 0〜2 本に変えて計算しました。1 本の時間を 4〜8 時間にしたのは、実測の約 3.6〜8.8 時間を挟むためです。本数は 6 本で固定しています。
| 同時数 | 再試行 | 波の数 | 1 本 4 時間 | 1 本 6 時間 | 1 本 8 時間 |
|---|---|---|---|---|---|
| 4 本 | 0 本 | 2 | 8 | 12 | 16 |
| 4 本 | 1 本 | 2 | 8 | 12 | 16 |
| 4 本 | 2 本 | 2 | 8 | 12 | 16 |
| 5 本 | 0 本 | 2 | 8 | 12 | 16 |
| 5 本 | 1 本 | 2 | 8 | 12 | 16 |
| 5 本 | 2 本 | 2 | 8 | 12 | 16 |
| 6 本 | 0 本 | 1 | 4 | 6 | 8 |
| 6 本 | 1 本 | 2 | 8 | 12 | 16 |
| 6 本 | 2 本 | 2 | 8 | 12 | 16 |
(単位は時間。筆者が上の式で計算)
この表は 06:30 から数えた総時間です。待ち上限は最後の応答から数える可能性があるため、上限の 12 時間・20 時間との比較は目安として読んでください。
表と図 3 から分かることは 3 つです。
- 1 波で終わるのは「同時 6 本・再試行 0 本」の組み合わせだけです。
- 1 本 8 時間なら、2 波になる組み合わせはすべて 16 時間で、12 時間を超えます。1 本 6 時間でも 12 時間ちょうどで、余裕がありません。
- 20 時間を超える組み合わせは、この範囲にはありません。
簡易モデルの上では、同時 6 本は「差し替えがない日」を短くする変更です。差し替えが 1 本でも出る日は 2 波に戻るので、6 本目を止めないのは 20 時間の上限のほうです。
ただし実際は、枠が空けば予備がすぐ入るので、差し替えのある日も短くなる余地があります。どこまで短くなるかは本番で測ります。
直したこと:同時 6 本、待ち上限 20 時間、書き方の決まり
この試算を踏まえて、次の 3 つを変えました。
| 変更 | 変更前 | 変更後 | ねらい |
|---|---|---|---|
| 同時に動かす本数 | 5 本 | 1 日の本数(6 本) | 差し替えのない日に 1 波で終わらせる |
| claude -p の待ち上限 | 12 時間 | 20 時間 | 差し替えが出て 2 波になっても止めない |
| 担当のファイルの書き方 | 決まりなし | Write・Edit ツールで書く | 書き込みの拒否によるやり直しを減らす |
3 つ目は、同じ日に見つかった別の遅れの原因です。担当がシェルの書き方(リダイレクトやヒアドキュメント)で、作業用リポジトリの外に下書きを書こうとして 9 回拒否されていました。
dontAsk モードでは、確認が必要になる操作は断られます(Claude Code: Permission modes)。そこで、7 種類の担当すべてに「ファイルはツールで書く」決まりを加えました。
待ち上限の設定のしかた
待ち上限は環境変数(プログラムに外から渡す設定値)で変えます。公式ドキュメントによると、既定は 10 分で、0 にすると上限なしで待ちます(Claude Code: Run Claude Code programmatically)。値はミリ秒で書くので、20 時間なら 20 × 60 × 60 × 1000 = 72,000,000 です。
# 20 時間 = 72,000,000 ミリ秒
export CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=72000000
上限は「待つ時間」で、終了時刻の保証ではない
公式ドキュメントでは、claude -p は最後の応答のあと、裏で動く処理を待ちます。待つ対象には、裏のコマンド、サブエージェント(AI が作業の一部を任せるために呼び出す別の AI 担当)、Workflow などが含まれます(Claude Code: Run Claude Code programmatically、2026-11-07 時点の記述)。
そして、会話そのものが始めた裏のコマンドが動いている場合を除き、待ちが既定で 10 分続くと、まだ動いている処理を止めて途中の結果を捨てます。筆者の環境では、最初にこの 10 分で止まり、12 時間に延ばした経緯があります。延ばす前の初回は、下書きを 1 本も作らずに約 12 分で終わっていました。
ここで大事なのは、上限が「待つ時間」を決めるもので、「何時に終わるか」を保証するものではないことです。作業記録では「06:30 + 20 時間 = 翌 02:30」と見積もりました。しかし実際には、入口スクリプトの前後の処理も時間を使います。
さらに、数え始めの時点にも不確かさが残りました。2026-11-06 のログは「最後の応答から 12 時間」という書き方でした。
起動から 12 時間なら 18:30 に止まるはずですが、判定が出たのは 21:08 です。上限を起動から数えるのか、最後の応答から数えるのかは、公式ドキュメントからは確認できませんでした。
翌日と重なるとどうなるか:ロックで飛ばされ、手で取り戻す
上限を 20 時間にすると、遅い日は翌日の 06:30 に近づきます。図 4 は、前の日の実行が翌朝まで続いた場合の流れです。
入口スクリプトは、最初に OS のファイルロック(同じ処理を 2 つ同時に動かさないための札)を取ります。すでにロック中なら、終了コード(プログラムが終わるときに返す、結果を表す番号)75 で何もせずに終わり、その記録を残します。2 日目の分はこうして飛ばされるので、1 日目が終わった後に日付を指定して手で実行し直します。
起動の仕組みにも注意点があります。Apple のドキュメントによると、launchd の StartCalendarInterval(指定時刻に起動する設定)は、その時刻に Mac がスリープしていれば復帰したときに動きます(Apple: Scheduling Timed Jobs)。一方、電源が切れていれば次の指定時刻まで動きません。
なお、翌日の分と実際に重なった例は、2026-11-06 の記録にはありません。ここはロックの仕組みと Apple の仕様から整理した流れです。
確認済み・未確認の表
この変更は、記事を書いた時点で本番の効果を確かめていません。何を確かめ、何がまだかを分けて書きます。
| 変更 | 試験で確かめたこと | 本番でまだ確かめていないこと |
|---|---|---|
| 同時 6 本 | 6 本が同時に動くことを自動テストで確認。テスト一式 7 ファイル 69 件が合格 | 6 本を同時に動かしたとき、1 本あたりが遅くならないか |
| 待ち上限 20 時間 | 設定値を書き換えたこと。シェルスクリプトの静的検査(shellcheck)で指摘 0 件 | 12 時間を超えても止まらずに待つか。翌日と重ならずに終わるか |
| Write・Edit で書く決まり | 7 種類の担当の指示に加えたこと | 書き込みの拒否が実際に減るか |
本番の確認は、2026-11-07 06:30 の定期実行で行う予定です。この記事を書いた時点では、その結果を確認できていません。
つまずきやすい点
上限を上げても、遅い担当の詰まりは残る
待ち上限を上げると「止められる」ことは防げます。しかし、1 本が遅いこと自体は直りません。筆者の環境では、2026-10-28 に 14 本を回したとき、性能の高いモデルの担当に処理が集中して詰まったことがありました。
同時数を増やすと、同じ担当に一度に多くの依頼が集まります。そのため、同時 6 本にした今回も「1 本あたりが遅くならないか」は本番で見る必要があります。
総時間を「全体の時間 ÷ 本数」で割らない
並行して動かしているので、14.6 時間 ÷ 6 本 = 約 2.4 時間を「1 本の時間」とするのは誤りです。実測では、1 本は約 3.6〜8.8 時間かかっていました。割り算で見積もると 1 本の時間を短く見てしまい、上限も短く設定してしまいます。
書き込みの拒否は、静かに時間を食う
9 回の拒否は、それぞれでは処理が止まるわけではありません。担当が別の書き方でやり直すので、失敗に見えにくいのです。ところが、やり直しの分だけ 1 本の時間が延び、順番待ちの後ろの記事に響きます。
無人で動かす場合は、拒否の回数を結果の記録に残し、毎日見ることをおすすめします。
まとめ
- 総時間は「ceil((本数 + 再試行) ÷ 同時数) × 1 本の時間」で見積もれます。1 本の時間は全体を本数で割らず、1 本ごとの開始と終了から測ります。
- 簡易モデルの上では、同時数を本数と同じにして 1 波に収まるのは差し替えが出ない日だけです。差し替えが出る日に止めないためには、待ち上限を 2 波分の時間より長くしておきます(実際は予備がすぐ入るので、短くなる余地があります)。
- 待ち上限は「待つ時間」で、終了時刻の保証ではありません。翌日の起動と重なったときの扱い(ロックと手での取り戻し)を先に決めておきます。
自分の環境で定期実行の本数や上限を見積もり直したい方、AI に任せる範囲の決め方を相談したい方は、お問い合わせからご連絡ください。AI が作った集計の SQL の確認に不安がある場合は、BigQuery SQL レビューパックも用意しています。
参考にした一次情報
- Claude Code: Run Claude Code programmatically(headless)(2026-11-07 確認。待ち上限の既定 10 分と CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS、待つ対象)
- Claude Code: CLI reference(2026-11-07 確認。claude -p の起動方法)
- Claude Code: Permission modes(2026-11-07 確認。dontAsk モード)
- Apple: Scheduling Timed Jobs(Daemons and Services Programming Guide)(2026-11-07 確認。StartCalendarInterval とスリープ・電源断の扱い)
- 筆者がこのサイトの運用で試した記録(2026-11-04〜2026-11-06 の作業記録、実行ログ、作業フォルダのファイル更新時刻)