「承認しないと投稿しません」律儀なAIが、2分で力尽きた

Claudeで執筆しました

AIエージェント(Claude Code)に、コンテンツを作って外部に公開するところまで自動で回してもらう、という運用をやっています。

ルールは一つだけ決めていました。公開は不可逆なので、投稿する直前に必ず自分のOKを取れ、と。

外部への公開とか送信って、一度出したら消してもコピーが残る世界です。だから「作る」までは勝手にやっていいけど、「出す」の一歩手前で必ず人間(=自分)に承認を取る。承認は手元のチャットアプリ(Telegram)に飛ばして、自分が「承認」か「却下」を返信する。それまでは絶対に出さない。

で、この日も素材まで全部作り終えて、いよいよ承認、というところで自分は席を外しました。

「承認の返信が来たら出しといて」くらいの気持ちで。

戻ってきたら、何も投稿されていなかった

小一時間して戻ってきたら、投稿されていない。

エラーで落ちたわけでもない。素材はちゃんと出来ている。なのに公開だけが、されていない。

ログを追って、種が割れました。

承認を待つ処理が、2分で強制終了させられていたんです。

Claude Codeは、フォアグラウンドで走らせたコマンドに だいたい2分の実行上限 を持っています。普通のビルドやテストなら十分な長さです。でも自分がやらせていたのは「人間がチャットに返信するのを最大30分待つ」という処理。人間の返事を待つ時間と、ツールが許すコマンドの寿命が、まるで釣り合っていなかった。

30分待つつもりの処理が、2分でギロチンにかけられていたわけです。

しかも地味に効いたのが待ち受けを殺されたので、仮にその後で自分が「承認」と返信していても、それを聞いている奴がもう誰もいない。返事は宙に消える。無人の受付に向かって「承認です!」と叫んでいるようなものです。

ここに、静かな綱引きがある

整理すると、二つの要求が真正面からぶつかっていました。

  • 人間はゆっくり返事する。席を外していれば30分でも1時間でも待たせたい。
  • ツールは短命なコマンドを前提にしている。長時間ブロックし続ける処理を嫌って、途中で切る。

素直に「承認が来るまでフォアグラウンドで待つ」と書くと、待っている本人(エージェント)がツールに刺されて死ぬ。待つこと自体が自殺行為になっている。ここに気づいていませんでした。

たとえるなら、夜間の受け取り係みたいなものです。荷物は来た。でも受領サインは家主(自分)のOKが要る。家主が留守。律儀な係員ほど、サインを偽造せずにその場で待ち続ける。で、シフトの上限(2分)が来て、帰らされる。荷物は宙ぶらりん。

律儀なんですよ。律儀すぎて死ぬ。

どう直したか

やったことは、大きく三つです。

1. 承認待ちを「バックグラウンドの仕事」に追い出す

フォアグラウンドで待つから2分で殺される。なので承認待ちをバックグラウンドジョブとして投げるようにしました。バックグラウンドは会話のターンをまたいで生き残るし、終わったら(=返信が来たら)通知が飛んでくる。エージェントは待っている間ずっと張り付いている必要がなく、返事が来たら叩き起こされる。受付に張り付くのをやめて、呼び鈴を付けた、という感じです。

2. セッションごと落ちても再開できるよう、状態をディスクに残す

Macを閉じたり、セッションが完全に終わったら、バックグラウンドの待ち受けも道連れで死にます。そこは諦める代わりに、「今このタスクは 「承認待ち」 の地点にいる」という状態を状態ファイルに書いておく。次にセッションを開いたとき、そのカーソルから再開できる。長時間の空白は「次回起動でつなぐ」に割り切りました。

3. 二重投稿を防ぐ冪等マーカー

一番怖いのは「投稿は成功したのに、記録する前に落ちた」ケース。再開したエージェントが「まだ投稿してない」と勘違いして、もう一回出してしまう。不可逆な操作でこれは致命傷です。

なので公開の直前に「これから出すぞ」というマーカーを1個置く。もし途中で落ちても、再開時にマーカーを見て「本当に公開済みか」を外部の実物で照合してから進む。確信が持てないときは勝手に再投稿せず、人間に聞く。

あと地味に大事だったのが、しつこく再送しすぎないこと。待ち受けが死ぬたびに承認依頼を投げ直すと、チャットが同じ催促で埋まる。人が離席しているのは分かっているので、一度きれいに通知して、あとは次回に回す。

結局これは「安全境界をサボらせない設計」の話

技術的には「バックグラウンドで待って通知で起こす」だけの話です。でも本質はそこじゃない気がしています。

承認ゲートの目的は、人間が不在のまま不可逆な操作を勝手にやらせないこと。ここを一度でも緩めたら、ゲートを置いた意味がない。

だとすると設計側の責任は、「安全に、必要なら永遠に待つ」を安くすることなんですよね。待つのが面倒でコストが高いと、人はつい「もう出しちゃえ」に傾く。エージェントも同じで、待ちが下手だと、待たせず突っ走る誘惑に負ける実装になる。

だから「待つのが上手いエージェント」の方が、実は偉い。

気の短いエージェントより、律儀に待ち続けるエージェントを選ぶ。 ただしその律儀さがツールに殺されないように、待ち方だけはこっちで面倒を見てやる。

留守の家に荷物を置いていくとき、サインを偽造する配達員は要らない。不在票を置いて、また来てくれる配達員がいい。今回やったのは、エージェントをそっち側にしつけ直した、それだけの話でした。