Antigravity 2.0 がビルド中に実際の Chrome を立ち上げ、ボタンを押し、フォームに入力し、スクリーンショットを撮って自分でデバッグしてくれるようになってから、私は UI 周りの手戻りがかなり減りました。ただ、最初の数日で一度だけ肝を冷やした瞬間があります。自己デバッグ中のエージェントが、サインアップフォームに架空のメールアドレスを入れて登録を通してしまい、その裏で「ようこそ」メールの送信ジョブが実際に走っていたのです。
送り先が架空アドレスだったので実害はありませんでしたが、これがもし本番の共有 DB とメール基盤に向いていたら、と考えるとぞっとしました。実ブラウザ自己デバッグの価値は「本物のブラウザで本物の操作をする」点にあります。裏を返せば、向けた先が本物であるほど、本物の副作用が走るということです。以下では、その照準を「ローカルでも本番でもない、ブランチごとの使い捨てプレビュー」に固定する組み方を、私自身の失敗も交えて整理します。
なぜ localhost に向けるのが一番危ういのか
意外に思われるかもしれませんが、私の経験では一番事故りやすいのは本番ではなく localhost です。理由は単純で、多くの個人開発では localhost の開発サーバーが、共有の開発用データベースや、実在するメール送信サービスのサンドボックスではない本番キーにつながっているからです。
私が個人開発で運用しているアプリにも、サインアップ直後に AdMob の同意取得とウェルカムメールの送信が続く画面があり、まさにこの並びが自己デバッグ中に一息に走ってしまいました。自己デバッグのエージェントは、人間なら「これはテストだから送信ボタンは押さないでおこう」と忖度する場面でも、遠慮なく最後まで操作を完了させます。フォーム送信、決済フローの確定、退会処理、Webhook の発火。エージェントにとってはどれも「画面上のボタン」であり、破壊的かどうかの区別は見た目からは付きません。localhost だからと油断していると、その裏でつながっている本物の外部サービスが動きます。
だからこそ、照準を環境ごと切り替えるのが一番確実です。エージェントの行儀を細かく躾けるより、そもそも壊しても構わない場所に向けるほうが、設計としては単純で堅牢になります。
ブランチごとの使い捨てプレビューを照準にする
理想は、作業ブランチを push すると自動で立ち上がり、マージやクローズで自動的に消える一時的なプレビュー環境です。Cloudflare Pages や Vercel のプレビューデプロイがこれに当たります。この URL を自己デバッグの向き先にします。
使い捨てプレビューには三つの利点があります。第一に、データが毎回リセットされる前提なので、エージェントが何を登録し何を削除しても翌日には消えます。第二に、URL がブランチ単位で分かれるため、複数のエージェントを並行で回しても互いのデータを踏みません。第三に、本番とは別の環境変数セットを持たせられるので、そこで副作用そのものを止められます。
Antigravity 側では、エージェントに渡すタスク指示で検証対象の URL を明示し、localhost を暗黙の既定にしないことが肝心です。
# エージェントへの検証指示(抜粋)
検証は必ず次の環境で行ってください。
- 対象 URL: $PREVIEW_URL(例: https://feat-consent-flow.example-preview.pages.dev)
- localhost や本番ドメインには一切アクセスしないこと
- サインアップ・課金・退会など状態を変える操作は、
対象 URL 上でのみ実行してよい「localhost を使わない」を明文化するだけで、エージェントが手近な開発サーバーに勝手に接続する事故がぐっと減ります。禁止事項の書き方は、本番に触れる前にエージェントの操作を空振りさせる副作用ゼロのドライラン層の設計でも触れているので、あわせて読むと組み立てやすいはずです。
プレビュー環境の側で副作用を無害化する
照準を移しても、プレビュー環境がメールを実際に送ったり課金を確定したりしては意味がありません。ここが実務で一番大事なところで、副作用はエージェントを躾けて止めるのではなく、環境変数で根元から無害化します。
具体的には、プレビュー環境にだけ立てるフラグを見て、外向きの副作用をすべて安全な代替に差し替えます。次はメール送信を握りつぶし、決済をテストモードに固定する薄いガードの例です。
// lib/side-effect-guard.ts
// プレビュー環境では外向きの副作用を無害化する
const isPreview = process.env.SELF_DEBUG_ENV === "preview";
export async function sendEmail(to: string, body: string) {
if (isPreview) {
// 実送信せず、記録だけ残す。エージェントの証跡には「送ろうとした」事実が残る
console.log(`[preview] email suppressed -> ${to}`);
return { suppressed: true };
}
return realMailer.send(to, body);
}
export function paymentApiKey(): string {
// 本番キーはプレビューに絶対に載せない。テストキーだけを渡す
if (isPreview) return process.env.STRIPE_TEST_KEY!;
return process.env.STRIPE_LIVE_KEY!;
}ポイントは、握りつぶした事実をログに残すことです。エージェントは操作を最後まで完了できるので自己デバッグの検証は成立し、それでいて実メールは飛びません。私は Webhook の送信先も同じフラグでプレビュー用の受け皿(RequestBin のような使い捨てエンドポイント)に差し替えていて、これで発火の有無だけを確認しています。
もう一つ大切なのは、プレビュー環境に本番の資格情報を一切載せないことです。テストキーしか存在しなければ、たとえエージェントが決済を確定させても本物の請求は発生しません。「エージェントが間違えても被害が出ない」状態を、権限の設計で担保しておくわけです。この考え方はサンドボックスでマルチエージェントを動かしても隔離は思ったほど効かないという運用メモと地続きです。
検証を安定させるために、種データを毎回同じにする
使い捨て環境のもう一つの効能は、データを毎回まっさらから作り直せることです。ここで種データ(seed)を決定的にしておくと、自己デバッグのスクリーンショットが安定します。
ユーザー名や作成日時が毎回ランダムだと、エージェントが撮る画面キャプチャも毎回変わり、視覚的な差分レビューが成り立ちません。プレビュー環境の初期化時に、固定した ID・固定した表示名・固定したタイムスタンプで数件だけ投入しておくと、「前回と同じ入力なら同じ画面になる」前提が確保できます。これは実ブラウザ自己デバッグの証跡を人間がレビューする段になって効いてきます。証跡の置き方そのものはエージェントが実ブラウザで自己デバッグするときの証跡と承認の置き場所が詳しいです。
種データは大量である必要はありません。私は「新規ユーザー・課金済みユーザー・退会予定ユーザー」の三体だけを固定値で入れて、状態遷移を含む画面をエージェントに歩かせています。少数でも状態のバリエーションを押さえておくほうが、件数を増やすより検証の密度が上がります。
次の一歩
まずは、いま自己デバッグがどこを向いているかを確認してみてください。もし localhost が暗黙の既定になっているなら、次のブランチから一つだけ、プレビュー URL を明示してエージェントに渡すところから始めるのがおすすめです。環境変数のガードや種データの固定は後からでも足せます。照準を本物から使い捨てへ移す——この一手だけで、実ブラウザ自己デバッグは「便利だが少し怖い機能」から「安心して回せる検証」に変わります。