浮世絵壁紙の新しい素材を、向きと寸法の組み合わせごとに八つの派生セットへ展開していた夜のことです。個人開発で運用している壁紙アプリの素材づくりなので、手が足りない分はセットごとに子エージェントを一本ずつ立て、親に束ねさせて走らせておりました。
七本は順調でした。縦長のセットを受け持った一本だけが、原寸を取り違えて小さな元画像を引き伸ばしていたのです。ログを追いながら、私の手はそこで止まりました——この一本だけを止めたくて、残りの七本はこのまま走らせておきたかったのです。
最初にお伝えしたいのは、その夜に困ったのは「止め方」ではなく、止めたあとに残る出力の扱いだったということです。ツールごとに止まる範囲を見比べたうえで、私がいまどう置き場所を分けているかを書き残します。
「止める」で止まる範囲は、ツールごとに違います
私の手元では、Antigravity の Manager 画面に子エージェントが一枚ずつのカードとして並び、止めたい子のカードだけを止められます。CLI 1.2.9 からは @ に続けて子の名前を書くと、その子だけにメッセージを渡せるようになりました。縦長の一本に「拡大せず原寸のまま」と言い直すのに、親を止める必要はなかったのです。
一方で、同じことを他のツールでやろうとすると、止まる範囲が変わります。Claude Code では、Stop を押すと関係のない子まで止まるという報告が Issue #82617 に上がっており、一時エラーの 529 で子が途中終了し、親が再構成に入るという報告も Issue #82605 にあります。Gemini CLI は、並列の子を協調させる仕組みそのものが Issue #19430 で要望されている段階です。
| ツール | 一本だけ止める操作 | 止めた子に言い直す | 私の把握(2026-09 時点) |
|---|---|---|---|
| Antigravity IDE / CLI | カード単位で止める | CLI 1.2.9 の @ で子へ直接 | 手元で運用中 |
| Claude Code | Stop が無関係な子にも及ぶと報告 | 親を経由 | #82617・#82605 は未解決 |
| Gemini CLI | 並列協調が要望段階 | — | #19430 を継続確認 |
表を作って気づいたのは、どのツールを選んでも変わらない一点でした。止めた子が途中まで書いたファイルは、止めたあともそこに残るのです。そして親の統合工程は、それが途中のものかどうかを知りません。
止めた一本の出力が、残りの七本に混ざっていました
その夜の失敗は、八本の子がすべて同じ out/ に書いていたことでした。縦長の一本を止めた時点で、引き伸ばされた画像が十数枚、正しいセットの隣に並んでいました。親は「八セット分のファイルが揃った」と判断し、配信用の一覧に載せる直前まで進んでいたのです。
気づいたのは、翌朝ステージングの一覧を開いたときでした。縦長だけ、寸法の桁が違っていました。
いま思えば、止める操作の問題ではありませんでした。止めた子の仕事を、まとめて捨てられる単位で置いていなかったのです。子を止める手段はツールが持っています。けれど、止めた子の出力を残りから切り離す単位は、ツールは用意してくれません。
子を止めるのはツールの仕事、止めた子をまとめて捨てられる単位を用意するのは私の仕事です。 この線引きを引いてから、どのツールで走らせても翌朝の景色が変わらなくなりました。
子ごとの置き場所と、最後に書く一行
置き場所の分け方は単純です。子一本につきディレクトリを一つ与え、子は自分の検査を通ったあとで、そのディレクトリの中に DONE という空ファイルを最後に書きます。親は DONE があるディレクトリだけを統合します。止めた子は DONE を書けないまま終わるので、途中の出力が混ざることはありません。
各子への指示には、次の三行だけを固定で入れています。
出力は out/<set 名>/ の中だけに書くこと。
全ファイルを書き終えたら、寸法と枚数を自分で確認すること。
確認が通ったら、最後に out/<set 名>/DONE を空で作ること(確認が通らなければ作らない)。親が統合に使うスクリプトは、この DONE だけを見ます。ここで解いているのは「止めた子と、まだ走っている子と、終わった子を、親がファイルの状態だけで区別する」という問題です。
#!/usr/bin/env bash
# merge_done_sets.sh — DONE が置かれたセットだけを配信用ディレクトリへ集める
set -euo pipefail
OUT_ROOT="${1:-out}" # 子エージェントの出力ルート
DIST="${2:-dist}" # 統合先
mkdir -p "$DIST"
merged=0; skipped=0
for set_dir in "$OUT_ROOT"/*/; do
name="$(basename "$set_dir")"
if [ ! -f "$set_dir/DONE" ]; then
# 止めた子・まだ走っている子はここに落ちる。触らずに数えるだけ
echo "skip $name (DONE なし)"; skipped=$((skipped+1)); continue
fi
# DONE より新しいファイルがあれば、DONE のあとに何かが書かれた印。混ぜない
if find "$set_dir" -type f -newer "$set_dir/DONE" ! -name DONE | grep -q .; then
echo "skip $name (DONE 以後に更新あり)"; skipped=$((skipped+1)); continue
fi
mkdir -p "$DIST/$name"
rsync -a --exclude DONE "$set_dir" "$DIST/$name/"
echo "merge $name"; merged=$((merged+1))
done
echo "merged=$merged skipped=$skipped"
# skipped が 0 でなければ、親の次の工程(配信一覧の生成)は走らせない
[ "$skipped" -eq 0 ]DONE を最後に書かせているのは、子が途中で止まる瞬間がいつ来ても、その前に DONE が存在しないようにするためです。-newer の一行は、DONE を書いたあとに子が何かを書き足した場合——言い直しを受けて作業を続けた場合がこれに当たります——を弾くために足しました。最後の [ "$skipped" -eq 0 ] で、一本でも欠けていれば親の次の工程へ進まないようにしています。
止めた縦長の一本は、私自身が rm -rf out/portrait と一行打つだけで捨てられます。捨てる単位が最初からディレクトリなので、隣のセットを巻き込む心配がありません。
無人で走らせるとき、止まらない子が親を待たせます
ここまでは私が画面の前にいる夜の話でした。無人で走らせるときは、事情が一つ増えます。
CLI 1.2.9 では、headless の -p 実行が背景の作業を --print-timeout まで待つようになりました(上限は 30 分です)。つまり、一本の子が止まらないまま黙っていると、親はその上限まで待ちます。画面の前にいればカードを止めればよいのですが、無人ではその手がありません。
そこで各子の指示に、時間の予算を一行足しています。「開始から N 分を過ぎたら、DONE を作らずに終えること」です。DONE が無ければ上の統合スクリプトが弾いてくれるので、時間切れの子は自然に「捨てる側」に落ちます。タイムアウトの扱いが版によって変わった経緯は、Antigravity CLI 1.1.28 で print-timeout 超過が成功終了になりました — 無人実行の判定を見直すに書き残してあります。
子が終わらない原因が親側の未承認にあるときは、止める前に確かめる場所が別にあります。その順番はサブエージェントが完了せず止まるとき、親側の未承認アーティファクトを先に確認するのとおりです。止めた子の作業を捨てずに再開したい場面では、Antigravity のエージェントを途中で止めるとき:作業を捨てずに中断・再開する手順の手順を、ディレクトリ単位でそのまま使えます。
まず出力ディレクトリを分けるところから
ツールごとの「止まる範囲」は、これからも版が上がるたびに変わっていくのだと思います。一方で、子ごとに置き場所を分けて最後に DONE を書かせる形は、どのツールに乗り換えても持ち越せました。三つのツールのあいだを取り持っているのは、結局この小さな約束事なのです。
まずは、いま並列で走らせている子エージェントの出力先を、子ごとのディレクトリに分けるところから始めていただければと思います。DONE を書かせるのは、その次で構いません。
私も最初はディレクトリを分けるだけでした。止めた一本を rm -rf の一行で捨てられた朝に、肩の荷が下りたのをいまも覚えています。