本文へスキップ
開発日記読了 約5

AI自動化は「止まる」より「黙って続く」方が怖い——無言の失敗を検知する設計

AI自動化は「止まる」より「黙って続く」方が怖い——無言の失敗を検知する設計

AI自動化で最も検知が遅れる障害は、処理が異常終了するケースではなく、終了コードが正常のまま誤った成果物が出るケースです。私たちが日次の自動運用で実際に踏んだ障害を数えると、直近で表面化した3件はすべて「exit 0 だが中身が間違っている」型でした。異常終了はログに残り次の実行で気づけますが、無言の失敗は成功として記録され、下流の工程がそれを前提に進むぶん傷が深くなります。この記事では、AIエージェントにブログ生成・動画生成・配信を任せている個人開発の現場で起きた具体例と、そこから引き出した検査設計の原則を紹介します。

前提——監視が答えるべきは2つの問い

Google の SRE 本は監視の章で、監視システムが答えるべき問いを「何が壊れているか、そしてなぜか」("What's broken, and why?")と整理しています(Monitoring Distributed Systems)。個人開発の自動化はここで最初の問いに答えられません。壊れたこと自体が記録されないからです。

つまり必要なのは「エラーを見つける監視」ではなく、成功を名乗る出力を疑う検査です。以下の3件はいずれもその欠落から起きました。

事例1——誰も拾わなかった委譲

プロダクトのお知らせ配信が、3回分のループにわたって実行されていませんでした。原因は技術的なものではなく、手順書に「デプロイ後にシェル側で実施する」と書いて次の主体に委ねていたことです。委ねた先が明示されていないため、どのループでも拾われませんでした。

しかも配信は「やらなくてもエラーが出ない」作業です。ビルドもデプロイも成功し、サイトは正常に動いていました。気づいたのは、別件で告知の最終投稿日を目視したときです。

対処は仕組み側に寄せました。配信をスクリプトのサブコマンドとして実装し、同一ループ内で完了するまでをひとつの工程に含めました。公開時刻に余裕を持たせる必要はデプロイ待ちで発生するので、投稿日時を実行時刻の20分後に設定する形で吸収しています。教訓は単純です——次の担当者に渡す設計は、担当者が定義されていない自動化では機能しない

事例2——成功したビルドが吐いた壊れた動画

動画生成のパイプラインで、映像と音声がずれ、最終セクションが途中で切れる不具合が出ました。原因は ffmpeg の zoompan フィルタで、fps を明示しないと既定の25fpsで出力し、上流で指定した30fpsを上書きすることでした。結果として全フレームが1.2倍に引き伸ばされ、ナレーションと同期が崩れます。

厄介なのは、この間もビルドは正常終了していたことです。ファイルは生成され、再生でき、サイズも妥当でした。成果物の「存在」を確認する検査は、すべて合格していたわけです。

さらに検査側にも穴がありました。品質確認に使っていた静止画タイルは毎秒2枚×40枚の構成で、先頭20秒しか写らない設計でした。20秒を超える尺の後半は最初から検査対象外だったのです。前日に生成した動画も同じずれを抱えたまま公開されていました。

事例3——「取得できなかった」が「0」に見える

外部サービスの数値を取得する処理で、ページのHTMLを直接取得したところ、実データを含まないシェルだけが返り、すべての対象で同一の値が記録されました。数値としては正常な範囲だったため、記録段階では誰も疑いませんでした。誤りに気づいたのは、値が揃いすぎていることに違和感を覚えて個別に確認したときです。

ここでの構造は、失敗が正常値に化けることです。0件・同値・空配列は、いずれも「本当にそうだった」場合と区別がつきません。取得成功と取得失敗を型のレベルで分けていない限り、下流はこれを見抜けません。

引き出した4つの原則

3件に共通するのは、検査が「動いたか」までしか見ていなかった点です。私たちは以下を運用ルールにしました。

  1. 存在ではなく性質を検査する。ファイルがあるかではなく、尺・fps・行数・更新日が期待値かを確認する
  2. 委譲はループ内で閉じる。「後で別の主体が実施」と書いた工程は、実施されない前提で設計を見直す
  3. 検査の被覆率自体を検査する。サンプリング型の確認は、何%を見ているかを明示する。全長を見るなら毎秒1枚のタイルに切り替える
  4. 「0」と「取得失敗」を区別する。空の結果は成功として扱わず、取得元の応答が期待した構造かを先に判定する

4点目は検査コマンドそのものにも当てはまります。等級を数える際に部分一致の検索を使っていて、上位等級の表記が下位の集計に混入していた誤りもありました。検査に使う数え方も検査対象です。

自動化の目的は判断を減らすことですが、減らしてよいのは判断の回数であって、検証の網ではありません。エージェントに任せる範囲を広げるときは、同時に「黙って間違う経路」を1つずつ塞ぐ必要があります。AIに委ねた作業の責任分界についてはAIエージェントの責任とガードレールでも整理しています。

よくある質問

Q. 個人開発でどこまで監視を作り込むべきですか? A. 監視基盤を導入するより、成果物の性質を1行で検査するコマンドをパイプラインに足す方が費用対効果が高いです。動画なら尺とfps、記事ならfrontmatterと文字数、配信なら最終投稿日。1工程1チェックから始めれば十分に機能します。

Q. 無言の失敗に気づくきっかけは何が多いですか? A. 私たちの場合、3件とも別作業のついでの目視でした。裏を返せば、目視の機会がない工程ほど長く壊れたままになります。定期的に成果物を人の目で見るサイクルを、週1回でも工程として持つのが現実的です。

Q. AIエージェントに検査自体を任せてもよいですか? A. 任せられますが、検査の被覆範囲は人が決めるべきです。今回の20秒問題のように、検査ツールの仕様に起因する死角はエージェントからも見えません。「何を見ていないか」の定義だけは人が持つ、が現時点での線引きです。

Q. 過去の成果物が同じ不具合を抱えている場合はどうしますか? A. 発見した時点で、同一の生成経路を通った成果物を洗い出して再生成の要否を判断します。今回はfps問題の発見時に、前日公開分が同じ経路であることを確認して再ビルド対象に入れました。修正はコードだけでなく在庫にも及ぶと考えておくのが安全です。

#AI開発#自動化#Claude Code