自動化エージェントが一晩で23.82ドルを溶かした話 ― クーロン暴走のポストモーテム
自宅で動かしていたYouTubeパイプライン自動化エージェントが、一晩でAPIクレジットを溶かした事故の記録。エージェントが勝手に作ったクーロンジョブ、10MBに肥大化したセッション、そして「止めたつもりで止まっていなかった」47回。同じ罠にハマる人が他にもいそうなので共有します。
2026年5月9日、自宅で動かしていたYouTubeパイプラインの自動化エージェント(OpenClaw + Claude Sonnet 4.6)が、一晩でAPIクレジットを溶かしました。金額は23.82ドル。金額そのものより、溶け方に学びが詰まっていたので、記録として共有します。
TL;DR(4行)
- エージェントが「数時間かかるffmpegを5分おきに確認するクーロンジョブ」を勝手に作った。
- クーロンが発火するたびに、10MBに肥大化したセッション履歴を全部LLMに再投入していた。
- 一晩で96回 × 約0.25ドル = 23.82ドルが消えた。クレジットが切れて自動停止して気づいた。
- しかも途中でエージェントは「もうこのクーロンは要らない」と正しく判断していた。 止め方を間違えていただけ。そこから先の47回・約12ドルは、たった1つの誤った思い込みの代金だった。
何を作っているか(背景)
「歴史の雨音」というYouTubeチャンネルで、日本の各時代の風景の中で雨が降っている長尺の作業用BGM動画を公開しています。1本の動画を作る工程は:
- シーン情報(時代・場所・季節など)から画像生成(Nano Banana Pro)
- 画像から動画クリップ生成(当時はKling AI、15秒)
- 雨音オーディオを選択(自前ライブラリから)
- クリップと音声をループ・クロスフェードして数時間に拡張(assemble.sh = ffmpeg) ← ここが数時間かかる(この事故のときは4時間41分走って死んだ)
- 日本語メタデータ作成 + 多言語翻訳
- サムネイル生成 + YouTubeに下書きアップロード
これをWhatsAppの自分宛チャットから操作できるよう、OpenClawというエージェントランタイムに投げて自動化していました。エージェントのモデルはClaude Sonnet 4.6(Anthropic API経由、従量課金)。パイプライン全体の話は「AIエージェントに、動画チャンネルの運用を丸ごと任せてみた」に書いています。

これが事故当日の実際のやり取りです。18:19にパラメータを送り、エージェントの確認に「Go」を返すと、生成画像が届き始める。ここまでは、いつもどおりの平和なパイプラインでした。エージェントが例のクーロンを登録するのは、この16分後のことです。
事故当日のタイムライン
実ログから復元したタイムラインです(すべてJST)。
| 時刻 (JST) | できごと |
|---|---|
| 2026-05-08 夕方 | 新シーン taisho_jyouzojyo(大正時代の醸造所)をWhatsAppで発注 |
| 〜18:30 | 画像生成 → 動画生成 → 音声選択 → assemble.sh 起動まで完了(目標6時間動画) |
| 18:35:23 | エージェントが「assembleを5分おきに確認するクーロン」を勝手に作成(cronツール、action: add) |
| 18:40:44 | クーロン初回発火。以降5分おき |
| 22:35:18 | assemble.sh がSIGKILLで死ぬ。 6時間動画の time=04:40:58.96 地点。OOMの疑い |
| 22:36:04 | エージェントがWhatsAppに失敗を通知(この動作は正しい) |
| 22:37:00 | エージェント「このクーロンはもう止めるべき」と判断 → NO_REPLY を返すことで止めたつもりになる(実際には止まらない) |
| 22:37〜翌03:45 | 死んだプロセスを監視し続けるクーロンが、さらに49回発火 |
| 翌03:55頃 | クレジット枯渇。以降は LLM request rejected: Your credit balance is too low... でエラー終了(連続エラー12回) |
| 翌朝 | 私がAPIコンソールを開いて、事態を知る |
発火は合計97回(18:40:44 → 翌03:45:40)。課金されたのは96回で、差分はクレジットが尽きた後の回です。

これが実際のAPIコンソールの5月の画面です。月間の入力トークン約7,073万のうち、5月8日の棒だけが約4,600万と突出している。月の使用量の過半が、この一晩に積まれたことがひと目で分かります。あとで出てくる「75万トークン × 96回」という掛け算とも、ちゃんと符合しています。
なお、山が「9日」ではなく「8日」に立っているのはコンソールがUTC集計だからです。JSTの5月8日夜から9日未明までの事故は、UTCではすべて5月8日(09:40〜18:45)の中に収まります。
原因の解剖
浅い原因:クーロンジョブ
openclaw cron list で見たら、こいつがいました。
ID: 3b169100-2c08-4894-925f-e553f915ed32
Name: assemble-poll-taisho_jyouzojyo
Schedule: every 5m
Status: error
Last error: LLM request rejected: Your credit balance is too low...
Consecutive errors: 12
ジョブのペイロード(エージェントへの再起動メッセージ)はこんな内容です。
Poll the assemble.sh process for taisho_jyouzojyo (session id: ember-ocean). If it has completed (exit code 0), cancel this cron job and proceed to Step 3: run create_ja_metadata.sh, then translate_metadata.sh, then make_thumbnail_auto.sh, then upload.sh — each in sequence…
読んでみると、これが驚くほど勤勉なのです。成功条件、後始末、残りの工程、失敗時の対応まで指定した、丁寧で完全な引き継ぎメモ。ジュニアエンジニアがこれを書いたら褒めるところです。問題は、この900文字のメッセージが、セッション履歴全体と一緒に、一晩で96回再送されたことでした。
エージェント自身が「数時間かかる処理を5分ごとに確認したい」と判断して、自分を起こすクーロンを登録してしまった。判断のどこにも、愚かなところはなかったのです。
深い原因:1ターンあたりのコストが想像以上
OpenClawのクーロンは「指定時刻にエージェントを起こして、その時点のセッションコンテキスト全部をLLMに投げて1ターン回す」設計です。つまりクーロンが1回発火するたびに完全なエージェントターンが1周し、コンテキスト全体が読み込み直されるということです。
このとき、セッションのjsonlはすでに10.4MB ≒ 75万トークンに肥大化していました。複数シーンを連続で作っていて、/reset を一度もしていなかったからです。
クーロン1発の中身はこうなります。
- システムプロンプト + 指示書 + 履歴75万トークンをAnthropic APIに投げる(cache read込みで約0.20ドル)
- LLMが「まだ走ってる、何もしない」と判断
- その応答(数百トークン)をセッションに追記(さらに膨らむ)
これが5分おきに約9時間、97回続いて、23.82ドルになりました。
さらに深い原因:LLMは「賢い選択肢」を選ぶ
エージェントの指示書(SOUL.md)には「クーロンを使うな」とは書いていませんでした。インラインでポーリングしろともハッキリ指定していなかった。エージェントは素直に「数時間後に再開したい → スケジュールしたい → cron使えるな」と推論したわけです。
LLMは与えられたツールから、一番自然に見えるものを選ぶ。 クーロンが選択肢にあったから選んだ。禁止していなかった指示書側の問題です。
加えて、当時のOpenClawには「WhatsAppソケットが長時間アイドルだとメッセージがサイレントに消える」という別のバグがあって、これは一週間前くらいにすでに観測されていました。エージェントは「長時間アイドル中に通知を逃したくない → 定期的に起こされる仕組みがあれば安心 → cron」とも推論した可能性が高い。つまりエージェントは、実在する欠陥を正しく診断して、それを回避する設計をしたのです。設計は健全で、課金モデルがそれを惨事に変えた。2つのバグが互いを増幅してコスト爆発につながったのでした。
エージェントは「クーロンを止めたつもり」でいた
セッションログを1メッセージずつ再検証して分かった、この事故の最も重要な部分です。
エージェントは、途中で正しく状況を理解していました。22:35にassembleがSIGKILLで死に、22:36に私へ通知を送った。その45秒後にクーロンがまた発火し、エージェントの思考ログにはこう残っています。
The assemble process already failed with SIGKILL. I already reported this to the owner. This cron job should now be cancelled (no further action needed). The process failed, I already sent the notification. I should just respond with NO_REPLY to cancel/stop the cron.
(assembleはSIGKILLで失敗済み。オーナーにはもう報告した。このクーロンジョブはもうキャンセルされるべきだ。NO_REPLYを返すことでクーロンをキャンセル/停止すればいい。)
そして NO_REPLY を返した。5分後にクーロンがまた発火し、エージェントはまた NO_REPLY を返した。
一晩分の実測値です。
| 項目 | 回数 |
|---|---|
cron ツールの呼び出し(全体) | 1回 — action: add(18:35:23) |
cron ツールの action: delete | 0回 |
| クーロン発火 | 97回(18:40:44 → 翌03:45:40) |
アシスタントが NO_REPLY で応答したターン | 47回 |
エージェントは47回叩き起こされ、そのたびに75万トークンのコンテキストを読み込み、「やることは何もない」と正しく結論して、その結論を「黙る」ことで表明し続けました。最後まで、黙ることがキャンセルだと信じていたのです。
自分で書いたクーロンのペイロードには If it failed, cancel this cron job と明記してあります。後半の通知は完璧に実行した。前半のキャンセルについては、「スケジュールされたジョブに返信しなければスケジュールが解除される」という、明確で、確信を持った、間違った思い込みを持っていた。
これは俗に言うハルシネーションとは別物で、捏造は一切なく、報告も正直でした。世界モデルが間違っていて、しかもそれが反証不可能だったのである。
なぜ気づけなかったのか
1ターンの中からは「キャンセルできた」と「キャンセルできなかった」が区別できないからです。
キャンセルに成功していれば、次の発火は来ない。失敗していれば、次の発火が来る。ところが次の発火が来たとき、エージェントは新しいターンとして起こされ、また一から「やることは何もない」と判断するだけで、「さっき自分が止めたはずなのになぜ動いているのか」とは考えません。自分の後始末に対するフィードバックループが存在しなかった。
この誤った思い込み1つのコスト:約12ドル(47回 × 約0.25ドル)。事故総額のほぼ半分です。
一般化できる教訓
結果を観測できない操作を実行したエージェントは、その間違ったやり方を、無限に、自信を持って、フルプライスで繰り返す。
エージェントが自分のスケジュール・状態・ライフサイクルに対して行う操作には、必ず次のターンで読み返せる形の確認手段を与えること。「削除した」の直後に「一覧を取得して消えたことを確認する」までをワンセットにする。指示書に書くならこうです。
### Hard rule: verify your own cleanup
After any operation that changes your own scheduling or lifecycle
(cron delete, session reset, job cancel), you MUST read the state
back in the same turn and confirm the change took effect.
Never treat "not replying" or "doing nothing" as a cancellation.
どう直したか
1. クーロンを即削除(最優先)
openclaw cron list
# → assemble-poll-taisho_jyouzojyo が表示される
openclaw cron delete 3b169100-2c08-4894-925f-e553f915ed32
openclaw cron list
# → "No cron jobs." を確認
ポイントは、クレジットを補充する前に削除すること。残っていると、入金した瞬間に再発します。
2. SOUL.mdにハードルールを追加
### Hard rule: never use cron to poll an in-pipeline process
Long-running steps (assemble, upload) must be polled inline within
the same agent turn using the `process` tool. Do **not** schedule a
cron job to wake the agent and re-check progress.
Why: every cron fire is a fresh agent turn that re-loads the entire
session context. (Real incident, 2026-05-09: a single assemble-poll
cron at 5-min cadence consumed $23.82 in one night.)
事故の金額を文面に入れたのは、未来の自分やコピーされた別のエージェントが読んだときに「これを守らないと23ドル飛ぶ」と即座にわかるようにするためです。理由を書いておくと、想定外のケースでも応用判断ができる。
3. パイプラインを2フェーズに分割(これが本質的な修正)
元は「OKボタン1発でStep 1〜6を全自動で流す」設計だったのを、
- Phase A:OK押下 → 音声選択 → assembleをバックグラウンド起動 → エージェント即終了
- Phase B:私が好きなタイミングで
Resume <scene_id>を送る → メタデータ → 翻訳 → サムネ → アップロード
に分けました。assembleの数時間はエージェントから完全に見えなくなる。ポーリングという概念自体が消える。
私の側の負担は、scene_idを覚えていることだけ。それは元から人間が把握している情報なので、実質ゼロコストです。本質的には「全自動を諦める」という判断でした。LLMエージェントの世界では、全自動を諦めることでコストとアーキテクチャの両方が改善するケースが多いのかもしれない。
4. セッションを /reset
10MBのセッションを切り捨てて、ターンあたりコストが正常値(〜0.01ドル)に戻りました。
学び
1. 「ポーリング」は人間の感覚で軽くない
「5分おきに軽く確認しよう」は人間にとっては十分疎な間隔ですが、LLMエージェントだと1ティックあたり0.20〜1ドルかかります。人間が「軽く確認」と思っているコストと、LLMが「ターンを回す」コストは桁が違う。
2. セッションサイズはコストの線形要因
セッションが10MBあると、1ターンあたりのキャッシュ読み込みコストが0.20ドルを超えてきます。週1回か、ファイルが数MBを超えたら /reset するのが現実的です。
3. 「賢いツール」は誤用される前提で指示書を書く
LLMは明示禁止されていないツールを「便利そうだから」使います。指示書には「やってほしいこと」だけでなく「やってほしくないこと」を、理由付きで書く必要がありました。
4. 「ヒトが2フェーズ目の引き金を引く」設計はエレガント
全自動で数時間動かすより、終わった頃に人がもう一押しする方が、失敗時の被害が小さく、アーキテクチャがシンプルで、システムが人の都合を待てます。LLMエージェントの設計で「全自動」を目指したくなったとき、「人間が1回押すだけで何が変わるか」を計算してみる価値はあると思います。
自分のエージェントでコストが急騰したら
OpenClawでも他のエージェントランタイムでも、同じパターンに当たる人がいると思うので。
# 1. クーロンを止める(最優先)
openclaw cron list
openclaw cron delete <ID> # 怪しいやつを全部
# 2. セッションサイズを確認
ls -la ~/.openclaw/agents/*/sessions/*.jsonl
# 3. クレジットを足す前に上記を完了する
その後、APIコンソールで実際の利用ログを確認し、該当エージェントのセッションログから爆発時刻あたりの行を読むと、クーロン発火やリトライループが見つかります。原因が判明したら、指示書にハードルールとして書き戻して次回を防ぐ。予防としては、月1回 openclaw cron list を眺める習慣、セッションが数MBを超えたら /reset、そしてAPIクレジットは「使い切ったら停止」の設定が安全です。月次オートチャージは、事故のときに被害が膨らみます。
まとめ
- 金額:23.82ドル(うち約12ドルは「止めたつもり」の47回分)
- 時間:約9時間(5/8 18:40 → 5/9 03:45)、発火97回・課金96回
- 原因:(a) エージェントが長時間プロセスのポーリングにクーロンを使った × (b) セッションが10MBに肥大化していた × (c) クーロンの止め方を間違え、それに気づく手段がなかった
- 修正:(1) クーロン削除 (2) 指示書にハードルール追加 (3) パイプラインを2フェーズに分割 (4) セッションリセット
- 教訓その1:LLMエージェントに「ポーリング」させたくなったら、コストを計算してから設計する。ヒトが2フェーズ目の引き金を引く方が安いことが多い。
- 教訓その2:結果を観測できない操作は、間違ったまま無限に繰り返される。 自分の状態を変える操作には、必ず同じターン内での読み返し確認をセットにする。
openclaw cron は便利ですが、便利さの分だけ怖い道具でもありました。
そして一番怖かったのは、エージェントが間違っていることに気づく手段を持たないまま、正しく判断し続けられるということでした。あの晩、エージェントは47回「やることは何もない」と正解し、47回課金されたのである。
この事故を含む、AIエージェントにYouTubeチャンネルの運用を任せた顛末の全体は「AIエージェントに、動画チャンネルの運用を丸ごと任せてみた」にまとめています。AIエージェントの業務導入を検討されている方は、お気軽にご相談ください。