はじめに
AI にコードを書かせるようになって、作るのは速くなりました。次に困るのが、動かした後です。外部ライブラリに脆弱性(攻撃に使われうる弱点)が見つかる、本番でエラーが出る。放っておくと、気づく・調べる・直すが全部人の手に残ります。
この記事は、そうした動かした後の業務を自動化して効率を上げる例として、脆弱性の監視から通知、そして修正までを AI エージェントに任せる形を紹介します。
全体の流れ
人がやるのは、破壊的な変更(メジャーアップデートなど)のときに作られる PR をレビューすることだけです。誰にレビューを頼むかまで、通知の指示に含めています。
破壊的な変更とは
ライブラリを更新したとき、それを利用するアプリのコードも変更しなければ動かなくなる変更のことです。メジャーアップデートでは、このような変更が含まれることがあります。
例えば、次のような変更です。
-
Next.js 14 から 15
cookies()、headers()などの Request API や、ページへ渡されるparamsが非同期になりました。利用箇所によってはawaitを追加する必要があります。 -
React 18 から 19
ReactDOM.renderが削除されたため、createRootを使用する実装へ変更する必要があります。
このような更新は、ライブラリのバージョンを上げるだけでは完了しません。アプリへの影響を確認し、必要に応じてコードを修正するため、AI が直接 push せず、人がレビューする PR として作成します。
1. 監視
- 毎朝の決まった時刻に、GitHub Actions(GitHub の自動実行の仕組み)が検査ツール trivy でリポジトリ全体を調べます。深刻度が CRITICAL と HIGH のものを拾い、その中でも CVSS(危険度の点数)がしきい値以上のものだけを次の通知に回します。
- 0 件の朝は何も起きません。人が定期的に確認しに行く必要はありません。
監視対象を絞る理由
すべての検出結果を通知すると、対応不要な通知に重要な問題が埋もれてしまいます。そこで、深刻度と CVSS の 2 段で絞ります。以下の数値は説明用の例で、実際の実行時刻やしきい値は社内の運用に合わせています。
- Trivy の深刻度が
HIGHまたはCRITICAL - CVSS スコアがしきい値(例: 7.0)以上
Trivy では --severity HIGH,CRITICAL のように、表示する深刻度を指定できます。
GitHub Actions の設定例
ワークフローの構造は次のとおりです。仕組みを説明するための抜粋で、通知先などの機密情報は除き、実行時刻やしきい値などの設定値は例に置き換えています。
on:
schedule:
# 例: 日本時間 8:00 = UTC 23:00
- cron: '0 23 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run Trivy filesystem scan
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
format: 'json'
output: 'trivy-results.json'
- name: Notify Discord if high CVSS vulnerabilities found
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
run: .github/scripts/notify-discord.sh trivy-results.json
通知スクリプトでは、しきい値以上の CVSS だけを抜き出し、0 件なら何も送らずに終わります。
CVSS_THRESHOLD=7.0 # 例
# CVSS が閾値以上の脆弱性だけを抜き出す
vulns=$(jq -r --argjson threshold "$CVSS_THRESHOLD" -f "$SCRIPT_DIR/extract-vulns.jq" "$TRIVY_JSON")
vuln_count=$(printf '%s\n' "$vulns" | jq 'length')
if [[ "$vuln_count" -eq 0 ]]; then
echo "No vulnerabilities with CVSS >= $CVSS_THRESHOLD found."
exit 0
fi
# サマリ(AI 宛の指示つき)と全件の Markdown を Discord の Webhook へ 1 回で送る
http_code=$(curl -s --show-error -o "$response_body" -w "%{http_code}" \
--max-time 30 \
--retry 2 --retry-all-errors \
-X POST "$DISCORD_WEBHOOK_URL" \
--form-string "payload_json=$payload" \
-F "files[0]=@${md_file};filename=trivy-vulnerabilities.md;type=text/markdown")
# extract-vulns.jq(抜粋): CVSS v3 の最大値が閾値以上のものだけ残す
.Results[]? | .Vulnerabilities[]?
| select(.CVSS != null)
| ([.CVSS | to_entries[].value.V3Score // empty] | max // 0) as $score
| select($score >= $threshold)
2. 通知
見つかった脆弱性は社内チャットツール(Discord など)に届くのですが、ここに一つ仕掛けがあります。通知の本文が、人への報告ではなく AI への作業依頼になっていることです。先頭で AI エージェントをメンション(呼び出し)し、そのまま指示を書いた形で送られます。
@(AI エージェント)
既に対応中の PR が無いか確認してください。無ければ修正して(統合ブランチ)へ直接 push してください。
メジャーアップデートなど破壊的な変更を伴う場合は、PR を作成し、保守メンバーの一覧で「(プロジェクト名)」の担当グループを確認して、そのグループのメンバーから 1 名を無作為に選んでレビューを依頼してください
Trivy Scan Alert: (リポジトリ名) — CVSS 7.0 以上の脆弱性 1 件
この文は、通知スクリプトが組み立てています。通知を送る場所(チャットツールの Webhook の URL)とプロジェクト名を設定しておくだけで、毎朝この形で届きます。レビュアーの決め方も、この指示の中に書いてあります。担当者名を固定する設定と、保守メンバーの一覧からそのプロジェクトの担当グループを見て 1 名を無作為に選ばせる設定の 2 通りがあり、今は固定する設定を使っているリポジトリが多いです。
本番のエラーも同じチャットツールに届きます。Sentry(エラー監視のサービス)が、致命的なもの・直ったはずなのに再発したもの・短時間に連発したものだけを、深刻度別のチャンネルへ流します。こちらは通知までで、エラーの修正はこの仕組みには含めていません。
3. 修正
通知を受け取るのは、チャットツール上の bot として常時動いている AI エージェントです。中身はオープンソースのエージェント基盤(Hermes Agent)で、次のように動きます。
- このエージェントは、メンションされた投稿にだけ反応し、その投稿からスレッドを作って作業します。今回の通知は Discord の Webhook から投稿されるため、Webhook の投稿も受け付ける設定にしています。
- GitHub には専用の GitHub App として GitHub にアクセスし、リポジトリを clone して、ライブラリを上げて push します。
- 指示どおり、既に対応中の PR があれば重複しません。破壊的な変更が要るときだけ PR を作り、指示されたレビュアーに依頼する形です。
安全のために
AI に直接 push させる形なので、次の 3 つを決めています。
- 専用アカウントで入る。 bot は人のアカウントを借りず、専用の GitHub App として GitHub にアクセスします。権限はリポジトリ単位で必要な操作だけに絞れ、履歴にも bot の名前で残るので、人の変更と区別できます。
- 呼ばれた時だけ動く。 メンションされた投稿にだけ反応し、それ以外のチャットには手を出しません。
- 検証の結果を残す。 bot が PR を作る時は、動かした検査(型チェック・ビルド・テスト)の結果を本文に書きます。失敗した項目もそのまま書くので、人は結果を読んで判断できます。直接 push した場合は、push 後に開発環境への配置が自動で走るので、ビルドの失敗はそこで分かります(多くのリポジトリでは失敗をチャットにも通知しています)。
まとめると、何を自動化したのか
▲ 左から監視、通知、修正。
人がやっていた気づく・調べる・直すを、次の 3 つに置き換えました。
- 気づくのは検査の仕組み。 毎朝の検査が、危ないものがある日だけ知らせる。
- 頼むのは通知そのもの。 届いた文面がそのまま AI への作業依頼になる。
- 直すのは AI エージェント。 人の手が要るのは、破壊的な変更のレビューだけ。
おわりに
監視・通知・修正のうち、修正には特に人の手作業が残ります。そこを AI エージェントに渡すと、人の仕事は AI が作った PR を読んで決めることだけになります。

