昼休みの前に、コーディングエージェントを 3 つ並列で走らせたとします。それぞれ timeout 1800 で包んでおいたので、30 分あれば終わるはずでした。ところが戻ってくると、1 つがまだ動いています。テストが落ち、ラッパーがリトライし、リトライ後にまたチェックが走り、新しいプロセスが起動するたびに 30 分がまるごと与えられていたからです。どこも壊れてはいません。制限がプロセス単位でかかっていて、本当に区切りたかった「実行全体」には効いていなかっただけです。
Ctrl-C にも似た抜け穴があります。オーケストレーション用のスクリプトがエージェント CLI をそれぞれ別のプロセスグループで起動している場合(1 つのエージェントが落ちても他を巻き込まないので、普通はそうしたいはずです)、スクリプトを止めてもそのグループまでシグナルは届きません。エージェントは誰も見ていないところでファイルを編集し、トークンを使い続けます。
実行予算がカバーすべき範囲
エージェントの実行は、1 つずつ見れば短いステップの連なりです。
- セットアップ(依存関係のインストール、MCP サーバーの起動)
- エージェント本体の作業
- チェック失敗後のリトライ
- テストスイートなどの検証コマンド
- 途中で止まったセッションの再開
どれか 1 つにタイムアウトを付けても、合計時間は区切れません。区切れるのは、セッション開始時に一度だけ記録し、その後のすべてのステップが自分の時計を始める代わりに参照する、ひとつの絶対的な期限です。
oh-my-agent での対処
私は oh-my-agent(OMA)を作っています。Claude Code や Codex などのコーディングエージェントを並列で動かすための CLI とスキル集です。v20.13 で、この問題に対処するためセッション単位の実行予算を追加しました。.agents/oma-config.yaml で一度だけ設定します。
session:
execution:
timeout_seconds: 1800
コマンドごとに指定することもできます。
oma agent parallel tasks.yaml --timeout-seconds 1800
oma agent resume <session-id> --deadline 2026-11-01T18:00:00+11:00
spawn、parallel、review、resume、begin、verify はいずれも --timeout-seconds か --deadline を受け付けます。期限はセッションごとに 1 つで、.agents/state/executions/ に保存されます。設定ファイル、親プロセス、保存済みセッションがそれぞれ期限を持っている場合は、最も早いものが採用されます。リトライや再開はこの期限を読むだけで、後ろにずらすことはできません。OMA が起動する子 CLI には OMA_EXECUTION_DEADLINE で期限が引き継がれるので、エージェントのタスク内でネストして呼ばれた oma agent spawn も同じ予算の中に収まります。
期限を過ぎるかキャンセルすると、OMA はそのセッションで新しい作業を受け付けなくなります。新しいエージェント、リトライ、レビュー、検証はどれも始まりません。そのうえで、自分が起動したプロセスグループに SIGTERM を送り、短い猶予の後に SIGKILL で終了させます。終了コードはタイムアウトなら 124(GNU timeout と同じ)、Ctrl-C でキャンセルした場合は 130 で、停止理由はセッションに記録されます。
プロセスが終了したことを確認できなかった場合、OMA は所有記録を残したまま、生き残ったプロセスとして報告します。後片付けが済んだことにはしません。oma cleanup --dry-run で停止対象を一覧でき、記録と同一性が一致するプロセスにしか手を出さないため、たまたま同じ PID を再利用した無関係なプロセスを止めてしまうことはありません。
停止しても何も削除されません。ログ、結果、worktree、キャッシュはそのまま残るので、時間切れになる前に各エージェントがどこまで進めたかを確認できます。
制限事項
- 対象は OMA が自分の CLI 経由で起動したエージェントです。Claude Code 内部のネイティブなサブエージェントや、自分で起動したシェルジョブは、それぞれのホスト側のキャンセル手段が必要です。
- 区切れるのは経過時間だけです。CPU、メモリ、ディスクの上限はホストやコンテナ側の対応次第です。
- 別機能のトークン上限(
session.quota_cap)は実行中の子プロセスを中断しません。動いている子を実際に止めるのは時間予算のほうです。 - 環境変数を手で設定しても、それを読まないプログラムに期限が適用されるわけではありません。
試してみる
OMA は私が作っているツールです。長時間のエージェント実行を今どう区切っているか、この仕組みで足りない点はどこか、ぜひ聞かせてください。
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/first-fluke/oh-my-agent/main/cli/install.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/first-fluke/oh-my-agent/main/cli/install.ps1 | iex
原文(英語): https://dev.to/gracefullight/why-your-coding-agents-timeout-resets-every-time-it-retries-gka