ブログ一覧

障害検知のトリアージから対応まで AI エージェントに任せる設計手法例

監視のアラートが鳴るたびに、直前に自分が触ったコードから疑って読みに行っていました。原因が分かるまで手が止まり、無関係な箇所を読んでいたこともあります。そこで、アラートのトリアージ(一次判定)から対応までを AI エージェントに任せ、判定の順番と使える道具を固定しました。2026年6月1日から8月31日までの13週間で、監視の起票は14件、人の本番操作は0件です。

ここでの本番は2つあります。1つは自作の投稿 bot(Slack を起点に X へ投稿するサービス)で、AWS Lambda 上で15分おきに定期実行します。もう1つは8サイトが共有する D1(Cloudflare のデータベース)です。アラートはどちらも Issue として起票され、エージェントがそれを読んで判定します。

判定の順番を固定する

エージェントが自由に原因を探すと、人がやっていたのと同じ遠回りをします。順番は次の4段階に固定しています。

  1. 変更の否定: その時刻の前後に本番デプロイがあったかを確認する
  2. 比率と実数の分離: 「〇倍」という比率だけで騒がず、分母(起動回数やリクエスト数)が動いていないかを先に見る
  3. 外部要因の確認: クローラや旧 URL へのリダイレクト、定期実行のタイミングの一致など、コードより外側を先に疑う
  4. 追加調査の判定: 上位3つで説明できれば対処不要として閉じ、できなければ初めてエージェントがログとコードを読む

判定の道具は読み取り専用に絞る

判定に使える道具は4つで、いずれも書き込み権限を持ちません。

  • デプロイ履歴と git log
  • 当日の作業記録
  • 読み取り専用の権限で見る CloudWatch Logs Insights(AWS のログ検索)
  • 監視の起票履歴

原因が分かる前の段階で本番に触れる手段を、判定する側に持たせないための境界です。修正が必要と判定した場合は、エージェントが PR を出します。merge で自動デプロイされるため、人が本番に手を入れる場面はありません。

13週間の実績

起票14件の内訳は、エージェントが PR で修正したものが8件、判定の結果対処不要だったものが5件、監視のベースラインの見直しが1件です。

修正が必要だった例: Lambda が想定外の入力で落ちた

Lambda のエラー監視が初めて鳴り、判定は次の順に進みました。

  1. 変更の否定: その日の前後に本番へのデプロイは無く、最後のデプロイは1か月前
  2. 比率と実数: 初回のアラームで比較対象が無いため該当なし
  3. 外部要因: 本文の無い GET リクエストが Function URL に届いた記録
  4. 追加調査の判定: 必要。修正の PR へ

Function URL は Lambda に直接割り当てる HTTPS エンドポイントで、認証を挟まなければ誰でも叩けます。Slack からの入力を受ける Bolt(Slack の公式 SDK)がそのリクエストを JSON として読もうとして失敗し、落ちていました。

エージェントは Bolt の手前に、Slack の署名ヘッダが無いか本文が空なら400を返す層を足す PR を出しました。

対処不要だった例: D1 の読み取りが5.1倍になった

8サイトのうち1つで、1起動あたりの読み取りがベースラインの35行に対して180行になりました。

  1. 変更の否定: 対象サイトの本番 Worker は9月2日から未更新でコミットも無く、コード変更の可能性はここで消滅
  2. 比率と実数: 支配的なクエリの1回あたりの読み取りは239行でベースライン計測時と同じ。変わったのは回数で、3時間の窓で起動が10回、663回、1,635回と増加
  3. 外部要因: 増えた起動の大半が旧画像 URL へのリダイレクト経路を経由
  4. 追加調査の判定: 不要

読み取り行数の監視そのものはCloudflare D1 の読み取りが 1 日 2,100 万行になった原因に書きました。判定の途中で、リダイレクトのたびに media テーブルを全件走査している非効率も見つかっています。アクセス増の原因は外部要因なので監視の対応は閉じ、非効率は別の Issue として扱っています。

関連

この記事をシェア