取り組みの背景 — なぜ「品質の自動化」が今こそ必要なのか
個人開発者や小規模チームにとって、プロダクションのエラー対応は想像以上に時間を奪います。深夜のアラート、翌朝に発覚するバグ、スタックトレースを読み解いて原因を特定し、修正して、テストして、デプロイするまでの一連のサイクル——これをすべて人力でこなすのは、アプリの規模が大きくなるほど現実的ではなくなってきます。
Antigravity を AI エージェントとして活用することで、このサイクルの大部分を自動化できます。ここではSentry(エラー追跡)と GitHub Actions(CI/CD)を組み合わせた 3層品質自動化パイプライン の構築手順を、実際のコードを交えながら詳しく解説します。
この記事の対象読者は、以下の方々です。
- Antigravity を使った自動化をさらに発展させたい中〜上級開発者
- プロダクションの品質保証を人力から自動化に移行したいエンジニア
- MTTR(Mean Time To Resolve)を短縮して開発リソースを本来の機能開発に集中させたい方
なお、Antigravity × Vitest でのユニットテスト自動生成については Antigravity × Vitest:AIエージェントでユニットテストを自動生成する実践ガイド で詳しく解説していますので、あわせてご参照ください。
パイプライン全体アーキテクチャ
今回構築するパイプラインは、以下の3つのレイヤーで構成されます。
Layer 1: 検出(Detection)
Sentry がプロダクション上のエラー・パフォーマンス劣化をリアルタイムに捕捉します。閾値を超えたイベントは Webhook 経由で次のレイヤーへ転送されます。
Layer 2: 分析(Analysis)
GitHub Actions ワークフローが Sentry のイベントを受け取り、Antigravity CLI を呼び出します。Antigravity エージェントはスタックトレース、関連コード、直近のコミット差分を横断的に分析し、根本原因と修正案を生成します。
Layer 3: 修復(Remediation)
Antigravity エージェントが生成した修正コードを含む Pull Request が自動作成されます。PR にはエラーの概要、原因分析、修正内容の説明、テストコードが自動付記されます。
Sentry (Error/Alert)
↓
Webhook → GitHub Actions Trigger
↓
Antigravity CLI (Analysis Agent)
├─ スタックトレース解析
├─ 関連コード抽出(git blame + Antigravity context)
└─ 修正コード生成
↓
GitHub PR (自動作成)
├─ 修正コード diff
├─ テストコード追加
└─ 原因分析レポート
Step 1: Sentry のセットアップと Webhook 設定
まず Sentry プロジェクトを設定し、GitHub Actions をトリガーする Webhook を構成します。
1-1. Sentry SDK のインストール
Next.js プロジェクトを例に説明します。
npm install @sentry/nextjs
npx @sentry/wizard@latest -i nextjssentry.client.config.ts を設定します:
// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
// プロダクション環境でのエラー率アラート
integrations: [
Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false,
}),
],
// エラーバジェット管理: 本番は 0.1(10%サンプリング)
replaysSessionSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
replaysOnErrorSampleRate: 1.0,
});1-2. Sentry Alert ルールの設定
Sentry ダッシュボードで Alerts → Create Alert Rule を開き、以下のルールを設定します:
- Trigger:
Number of errors in 5 minutes > 5 - Action:
Send a notification via webhook - Webhook URL:
https://api.github.com/repos/{owner}/{repo}/dispatches
ただし、GitHub の repository_dispatch エンドポイントは認証が必要です。後述する GitHub Actions 側の設定と組み合わせて使います。
1-3. Sentry → GitHub Actions ブリッジの構築
直接 repository_dispatch を叩く代わりに、シンプルなサーバーレス関数(Cloudflare Worker)をブリッジとして挟む方法が安定します:
// cloudflare-worker: sentry-to-github-bridge.js
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const body = await request.json();
// Sentry の Webhook 検証
const sentrySignature = request.headers.get("sentry-hook-signature");
if (!verifySentrySignature(body, sentrySignature, env.SENTRY_WEBHOOK_SECRET)) {
return new Response("Unauthorized", { status: 401 });
}
// GitHub repository_dispatch をトリガー
const githubResponse = await fetch(
`https://api.github.com/repos/${env.GITHUB_OWNER}/${env.GITHUB_REPO}/dispatches`,
{
method: "POST",
headers: {
Authorization: `token ${env.GITHUB_TOKEN}`,
Accept: "application/vnd.github.v3+json",
"Content-Type": "application/json",
},
body: JSON.stringify({
event_type: "sentry-error-alert",
client_payload: {
issue_id: body.data?.issue?.id,
issue_url: body.data?.issue?.web_url,
title: body.data?.issue?.title,
culprit: body.data?.issue?.culprit,
stack_trace: body.data?.issue?.exception?.values?.[0]?.stacktrace,
level: body.data?.issue?.level,
},
}),
}
);
return new Response(JSON.stringify({ status: "dispatched" }), {
headers: { "Content-Type": "application/json" },
});
},
};
function verifySentrySignature(body, signature, secret) {
// HMAC-SHA256 検証(簡略版)
return !!signature; // 本番では実際の検証を実装
}Step 2: GitHub Actions ワークフローの構築
Sentry からのトリガーを受け取り、Antigravity エージェントを呼び出す GitHub Actions ワークフローを作成します。
# .github/workflows/ai-quality-fix.yml
name: AI Quality Auto-Fix
on:
repository_dispatch:
types: [sentry-error-alert]
permissions:
contents: write
pull-requests: write
jobs:
analyze-and-fix:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 50 # 直近50コミットの差分分析に必要
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Install Antigravity CLI
run: npm install -g @antigravity/cli
- name: Extract error context
id: error-context
run: |
echo "ISSUE_ID=${{ github.event.client_payload.issue_id }}" >> $GITHUB_ENV
echo "ISSUE_TITLE=${{ github.event.client_payload.title }}" >> $GITHUB_ENV
echo "CULPRIT=${{ github.event.client_payload.culprit }}" >> $GITHUB_ENV
# スタックトレースをファイルに保存
echo '${{ toJson(github.event.client_payload.stack_trace) }}' > /tmp/stack_trace.json
- name: Fetch related Sentry data
run: |
# Sentry API から詳細なエラー情報を取得
curl -s "https://sentry.io/api/0/issues/${{ github.event.client_payload.issue_id }}/" \
-H "Authorization: Bearer ${{ secrets.SENTRY_AUTH_TOKEN }}" \
> /tmp/sentry_issue.json
# イベント詳細(最新のオカレンス)を取得
curl -s "https://sentry.io/api/0/issues/${{ github.event.client_payload.issue_id }}/events/latest/" \
-H "Authorization: Bearer ${{ secrets.SENTRY_AUTH_TOKEN }}" \
> /tmp/sentry_event.json
- name: Run Antigravity Analysis Agent
env:
ANTIGRAVITY_API_KEY: ${{ secrets.ANTIGRAVITY_API_KEY }}
run: |
# Antigravity エージェントにエラー分析タスクを実行させる
antigravity run --non-interactive \
--model gemini-3.1-pro \
--max-turns 20 \
--output /tmp/analysis_result.json \
"以下のプロダクションエラーを分析し、修正コードを生成してください。
エラータイトル: $(cat /tmp/sentry_issue.json | jq -r '.title')
エラー箇所: $(cat /tmp/sentry_issue.json | jq -r '.culprit')
スタックトレース:
$(cat /tmp/sentry_event.json | jq -r '.entries[] | select(.type==\"exception\") | .data.values[0].stacktrace.frames[] | \"\(.filename):\(.lineNo) in \(.function)\"' | head -20)
タスク:
1. エラーの根本原因を特定する
2. 修正コードを生成する(既存のテストが通ること)
3. 再発防止のためのテストケースを1〜2件追加する
4. 修正の説明を日本語で50文字以内にまとめる
修正後は git diff を出力し、/tmp/fix_diff.patch として保存すること。"
- name: Apply fix and create PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="ai-fix/sentry-${{ github.event.client_payload.issue_id }}-$(date +%Y%m%d%H%M)"
git checkout -b "$BRANCH_NAME"
# Antigravity が生成したパッチを適用
if [ -f /tmp/fix_diff.patch ]; then
git apply /tmp/fix_diff.patch || echo "パッチ適用失敗 — 手動確認が必要"
fi
git add -A
git commit -m "fix: auto-fix for Sentry issue #${{ github.event.client_payload.issue_id }}
$(cat /tmp/analysis_result.json | jq -r '.summary // "Sentry エラーの自動修正"')
Sentry Issue: ${{ github.event.client_payload.issue_url }}"
git push origin "$BRANCH_NAME"
# PR を作成
gh pr create \
--title "🤖 AI Fix: ${{ github.event.client_payload.title }}" \
--body "## 概要
Sentry で検出されたエラーを Antigravity AI エージェントが自動解析し、修正 PR を生成しました。
## エラー情報
- **Issue URL**: ${{ github.event.client_payload.issue_url }}
- **Level**: ${{ github.event.client_payload.level }}
- **Culprit**: ${{ github.event.client_payload.culprit }}
## AI 分析結果
$(cat /tmp/analysis_result.json | jq -r '.analysis // "分析結果なし"')
## 修正内容
$(cat /tmp/analysis_result.json | jq -r '.fix_description // "修正説明なし"')
## ⚠️ レビュー注意事項
このPRはAIが自動生成しました。マージ前に以下を確認してください:
- [ ] 修正ロジックが正しいか
- [ ] 追加テストが適切か
- [ ] 副作用がないか
🤖 Generated by Antigravity Quality Auto-Fix Pipeline" \
--base main \
--head "$BRANCH_NAME"このワークフローにより、Sentry でアラートが発火した瞬間から数分以内に、修正候補の PR が自動的に生成されます。
Step 3: Antigravity エージェントの品質分析プロンプト最適化
Antigravity に渡すプロンプトの品質が、自動修復の精度に直結します。上記の基本形から、さらに精度を高めるためのプロンプトエンジニアリングを解説します。
コンテキスト強化:AGENTS.md への品質ポリシー記述
AGENTS.md にプロジェクトの品質ポリシーを記述しておくことで、Antigravity エージェントはより文脈に沿った修正を行えます。
# AGENTS.md(品質自動化ポリシーセクション)
## Error Handling Policy
When fixing production errors:
1. **Root cause first**: Always identify WHY the error occurred, not just WHERE.
2. **Defensive coding**: Add null checks, type guards, and boundary validation.
3. **Test coverage**: Every bug fix must include a regression test.
4. **No silent failures**: Replace `catch (e) {}` with proper error logging.
5. **Sentry reporting**: Use `Sentry.captureException(error, { extra: context })` for non-fatal errors.
## Code Quality Standards
- TypeScript strict mode is enforced (`tsconfig.json: strict: true`)
- All async functions must handle rejection (`try/catch` or `.catch()`)
- API responses must validate with Zod schemas before use
- Database queries must use parameterized statements (no string concatenation)エラーカテゴリ別の分析プロンプト
エラーの種類によって分析プロンプトを動的に変えると、精度が向上します:
# analyze-error.sh
#!/bin/bash
ERROR_LEVEL="${1:-error}"
ERROR_CULPRIT="${2}"
STACK_TRACE="${3}"
case "$ERROR_LEVEL" in
"fatal")
URGENCY="最優先(プロダクションダウン相当)"
FOCUS="即時修正可能なコード変更に集中。アーキテクチャ変更は提案のみ"
;;
"error")
URGENCY="高優先度"
FOCUS="根本原因の修正とテスト追加"
;;
"warning")
URGENCY="中優先度"
FOCUS="パフォーマンス改善または潜在的バグの予防的修正"
;;
esac
antigravity run --non-interactive \
--model gemini-3.1-pro \
"緊急度: ${URGENCY}
エラー箇所: ${ERROR_CULPRIT}
スタックトレース:
${STACK_TRACE}
分析方針: ${FOCUS}
出力形式:
{
\"root_cause\": \"根本原因(1〜2文)\",
\"affected_files\": [\"ファイルパス\"],
\"fix_strategy\": \"修正方針(3〜5文)\",
\"code_changes\": [{ \"file\": \"\", \"before\": \"\", \"after\": \"\" }],
\"test_additions\": [{ \"file\": \"\", \"test_code\": \"\" }],
\"risk_level\": \"low|medium|high\"
}"Step 4: パフォーマンス監視との統合
エラーだけでなく、パフォーマンス劣化も自動検出・分析できます。Sentry の Performance Monitoring と組み合わせます。
Web Vitals の自動計測と閾値アラート
// src/lib/monitoring.ts
import * as Sentry from "@sentry/nextjs";
// Web Vitals を Sentry に送信
export function reportWebVitals(metric: NextWebVitalsMetric) {
const { name, value, id } = metric;
Sentry.addBreadcrumb({
category: "web-vitals",
message: `${name}: ${Math.round(value)}`,
level: "info",
data: { id, value: Math.round(value) },
});
// 閾値超過時はトランザクションとして記録
const thresholds: Record<string, number> = {
LCP: 2500, // 2.5秒超でwarning
FID: 100, // 100ms超
CLS: 0.1, // 0.1超
TTFB: 800, // 800ms超
FCP: 1800, // 1.8秒超
};
if (thresholds[name] && value > thresholds[name]) {
Sentry.captureMessage(`Performance degradation: ${name} = ${value}ms`, {
level: "warning",
tags: { metric: name, page: window.location.pathname },
extra: { threshold: thresholds[name], actual: value },
});
}
}Antigravity によるパフォーマンス原因分析
パフォーマンスアラートに対しては、エラー修正とは異なる分析プロンプトを使います:
antigravity run --non-interactive \
--model gemini-3.1-pro \
"以下のパフォーマンス劣化を分析してください。
ページ: ${AFFECTED_PAGE}
メトリクス: ${METRIC_NAME} = ${METRIC_VALUE}ms(閾値: ${THRESHOLD}ms)
計測期間: ${START_TIME} 〜 ${END_TIME}
分析対象:
- 該当ページのコンポーネント(src/app/${PAGE_PATH}/page.tsx)
- 直近72時間のコミット差分(git log --oneline -20 で確認)
- バンドルサイズの変化(next build --debug の出力)
出力:
1. パフォーマンス劣化の原因(推定)
2. 改善コード案(具体的なコード変更)
3. 改善後の期待値(推定 ms 削減量)"Step 5: 自動テスト回帰検知との統合
CI でのテスト失敗を Antigravity が自動分析し、修正 PR を生成する仕組みも追加します。
# .github/workflows/test-failure-auto-fix.yml
name: Auto-Fix Test Failures
on:
workflow_run:
workflows: ["CI Tests"]
types: [completed]
jobs:
analyze-failure:
if: github.event.workflow_run.conclusion == 'failure'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download test results
uses: actions/download-artifact@v4
with:
name: test-results
path: /tmp/test-results
- name: Analyze with Antigravity
env:
ANTIGRAVITY_API_KEY: ${{ secrets.ANTIGRAVITY_API_KEY }}
run: |
FAILED_TESTS=$(cat /tmp/test-results/junit.xml | python3 -c "
import sys, xml.etree.ElementTree as ET
tree = ET.parse(sys.stdin)
failures = []
for tc in tree.findall('.//testcase[failure]'):
failures.append(f\"{tc.get('classname')}.{tc.get('name')}: {tc.find('failure').text[:200]}\")
print('\n'.join(failures[:10]))
")
antigravity run --non-interactive \
--model gemini-3.1-pro \
"以下のテストが CI で失敗しました。修正してください。
失敗テスト:
${FAILED_TESTS}
直近のコミット: $(git log --oneline -5)
作業:
1. 各テスト失敗の原因を特定
2. ソースコードを修正(テストを削除しないこと)
3. 修正後に git diff を /tmp/test_fix.patch として保存"Step 6: ダッシュボードと通知の整備
パイプラインの稼働状況を可視化し、チームへの通知を設定します。
Slack 通知の追加
# GitHub Actions ステップに追加
- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1.26.0
with:
payload: |
{
"text": "${{ job.status == 'success' && '✅' || '❌' }} AI Auto-Fix: ${{ github.event.client_payload.title }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*${{ job.status == 'success' && '✅ 修正PR生成完了' || '❌ 自動修正失敗' }}*\n\nSentry Issue: ${{ github.event.client_payload.issue_url }}\n\n${{ job.status == 'success' && 'PRをレビューして承認してください' || '手動対応が必要です' }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK品質メトリクスのトラッキング
週次でパイプラインの効果を計測するスクリプトです:
#!/bin/bash
# scripts/quality-metrics.sh
echo "=== Quality Auto-Fix Pipeline Metrics ==="
echo "Period: Last 7 days"
echo ""
# 自動生成PRの数
AUTO_PRS=$(gh pr list --label "ai-auto-fix" --state all --json createdAt \
--jq "[.[] | select(.createdAt > \"$(date -d '7 days ago' --iso-8601)\")]| length" 2>/dev/null || echo "N/A")
echo "Auto-generated PRs: ${AUTO_PRS}"
# マージ率
MERGED=$(gh pr list --label "ai-auto-fix" --state merged --json mergedAt \
--jq "[.[] | select(.mergedAt > \"$(date -d '7 days ago' --iso-8601)\")]| length" 2>/dev/null || echo "N/A")
echo "Merged PRs: ${MERGED}"
# 平均マージ時間(MTTR の代替指標)
echo "Merge rate: $(echo "scale=0; $MERGED * 100 / ($AUTO_PRS + 1)" | bc)%"よくある問題と対処法
Antigravity がスタックトレースから正しいファイルを特定できない
Source Map が有効になっていない可能性があります。next.config.ts で以下を設定してください:
const nextConfig: NextConfig = {
productionBrowserSourceMaps: true, // Sentry がミニファイ前のコードを参照可能に
};Sentry 側でも Project Settings → Source Maps から artifacts のアップロードを設定します。
自動生成 PR のマージ率が低い
Antigravity に渡すコンテキストが不足している場合に起こります。AGENTS.md の品質ポリシーを詳細化するか、Antigravity の --max-turns を増やして分析を深めます。また、本番環境と開発環境の環境差異が原因の場合は、.env.example に説明コメントを追加し、Antigravity にコンテキストとして渡す工夫が有効です。
GitHub Actions の実行コストが高い
Sentry のアラートルールをチューニングして、ノイズを削減します。Number of errors > 5 in 5 minutes などの条件を厳しくするか、同一 Issue の重複発火を防ぐために resolved イベントが来るまで再トリガーしないロジックを加えます。
まとめ
ここではAntigravity × Sentry × GitHub Actions を組み合わせた3層品質自動化パイプラインを構築しました。
構築したパイプラインの主要コンポーネントを整理します。
- 検出レイヤー: Sentry による本番エラー・パフォーマンス劣化のリアルタイム捕捉
- 分析レイヤー: Antigravity CLI による根本原因分析と修正コード生成
- 修復レイヤー: GitHub Actions による自動 PR 作成とチームへの通知
このパイプラインを稼働させることで、プロダクション障害の MTTR を大幅に短縮し、開発者が本来注力すべき機能開発に集中できる環境を整えることができます。
デバッグワークフローの基礎については、Antigravity AI デバッグ活用ガイド — インテリジェントなバグ検出と修正ワークフロー も参考にしてください。
品質自動化