ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-07-05中級

自己デバッグのエージェントに、本番の広告を叩かせない — AdMob 無効トラフィックを断つ三層の遮断

Antigravity 2.0 の実ブラウザ自己デバッグが本番の AdMob 広告を描画すると、無効なトラフィックとして計上されます。テスト広告の強制・ネットワーク遮断・preflight ゲートの三層で、広告に触れない検証環境を作る手順を、実測値とともにまとめました。

Antigravity311AdMob12自己デバッグ3無効トラフィック個人開発85

プレミアム記事

ある晩、壁紙アプリの課金導線を Antigravity 2.0 に直させていました。指示は「レビュー導線のモーダルが二重に開くのを直して」。エージェントは実際の Chrome を起動し、アプリのプレビュー画面をボタン操作で何度も往復して修正を検証してくれます。ありがたい仕組みです。

ところが翌朝、AdMob の管理画面を開いて手が止まりました。前夜だけインプレッションが不自然に伸びていたのです。原因はすぐに分かりました。修正対象のモーダルは、広告を挟んだ直後に開く導線でした。エージェントは検証のたびにその画面を描画し、そのたびに本番の広告ユニットが実インプレッションを積んでいたのです。

個人開発では、広告収益が一つのアカウントに集約されています。無効なトラフィックが積み重なれば、収益が無効化されるだけでは済まず、アカウント全体が制限される可能性もあります。自己デバッグは強力ですが、その足元で広告が動いていることに、私自身しばらく気づいていませんでした。

なぜエージェントの自己デバッグが広告にとって危険なのか

人間が手で確認するときは、無意識に広告を避けます。「これはテストだから広告は見なかったことにしよう」という忖度が働きます。エージェントにその配慮はありません。画面に広告が表示されれば、それは Google から見れば一件の実インプレッションです。エージェントがボタンを探してクリックする過程で、広告の領域に触れてしまえば、それは実クリックとして記録されます。

しかも、自己デバッグが走る環境は開発マシンやクラウドのサンドボックスです。データセンターのIPや、短時間に同じ画面を何十回も往復する挙動は、Google の無効トラフィック検知がもっとも嫌うパターンそのものです。悪意はなくても、痕跡は「作為的な水増し」と見分けがつきません。

ここで大切なのは、一箇所の対策では漏れるという点です。テスト広告を強制しても、メディエーションのアダプターが別経路で本番のリクエストを出すことがあります。ネットワークを遮断しても、同意管理(UMP)のフォーム取得だけは通したいときがあります。だからこそ、性質の異なる三つの層を重ねます。

第一層: ビルド時にテスト広告ユニットを強制する

最初の層は、広告ユニットIDそのものを切り替えることです。Google はテスト専用の広告ユニットIDを公開しています。これらは常にテスト広告を返し、収益にも無効トラフィックにも影響しません。ビルド構成に「エージェント検証モード」を一つ足し、そのときはテストIDだけを返す関数に集約します。

iOS(Swift)では、広告ユニットの解決を一箇所に閉じ込めます。

import Foundation
 
enum AdEnvironment {
    // 環境変数 or ビルド設定で注入。CI やエージェント実行時に AGENT_VERIFY=1 を渡す
    static var isAgentVerify: Bool {
        ProcessInfo.processInfo.environment["AGENT_VERIFY"] == "1"
    }
}
 
enum AdUnit {
    // Google 公開のテスト広告ユニット(常にテスト広告を返す・収益ゼロ)
    private static let testBanner = "ca-app-pub-3940256099942544/2934735716"
    private static let testInterstitial = "ca-app-pub-3940256099942544/4411468910"
 
    // 本番IDは Info.plist / 環境変数から。ここにハードコードしない
    private static var prodBanner: String {
        Bundle.main.object(forInfoDictionaryKey: "AD_BANNER_UNIT") as? String ?? ""
    }
    private static var prodInterstitial: String {
        Bundle.main.object(forInfoDictionaryKey: "AD_INTERSTITIAL_UNIT") as? String ?? ""
    }
 
    static var banner: String {
        AdEnvironment.isAgentVerify ? testBanner : prodBanner
    }
    static var interstitial: String {
        AdEnvironment.isAgentVerify ? testInterstitial : prodInterstitial
    }
}

さらに、テスト端末として自分の検証環境を登録しておくと、万一 ID の切り替えが漏れても、その端末からのリクエストはテスト扱いになります。二重の保険です。

import GoogleMobileAds
 
func configureAdsForVerification() {
    let config = MobileAds.shared.requestConfiguration
    if AdEnvironment.isAgentVerify {
        // 検証環境の端末ハッシュを登録(本番ユーザーには影響しない)
        config.testDeviceIdentifiers = ["SIMULATOR", "AGENT_DEVICE_HASH"]
    }
}

Android(Kotlin)でも考え方は同じです。BuildConfig にフラグを一つ足し、テスト端末を登録します。

import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.RequestConfiguration
 
fun configureAdsForVerification() {
    if (BuildConfig.AGENT_VERIFY) {
        val config = RequestConfiguration.Builder()
            .setTestDeviceIds(listOf("AGENT_DEVICE_HASH"))
            .build()
        MobileAds.getInstance().requestConfiguration = config
    }
}

この層だけで、意図した広告表示はテスト広告に置き換わります。けれど、これは「アプリが素直に振る舞えば」の話です。次の層で、素直でない経路をふさぎます。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
実ブラウザ自己デバッグが本番の広告ユニットを描画すると、無効なトラフィックとして計上される仕組み
テスト広告の強制・ネットワーク遮断・preflight ゲートという三層で、広告に触れない検証環境を作る実装
三層を入れる前と後で、計上インプレッションと eCPM がどう変わったかの実測
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-06-21
Play Store の密度分割で、特定の端末だけ内蔵壁紙が消えた — drawable と nodpi の境界設計
App Bundle の密度分割は、密度別に分けてはいけない画像まで分けてしまうと、特定の密度バケットの端末からだけリソースを取りこぼします。bundletool で再現し、drawable-nodpi への移動か密度分割の無効化で直すまでを、判断基準ごと残しました。
アプリ開発2026-05-21
Firebase Remote Config と Antigravity Agent で AdMob 配置を実運用しながら微調整する設計
壁紙アプリの AdMob 収益が頭打ちになった経験から、Firebase Remote Config と Antigravity Agent を組み合わせて広告配置を実運用中に少しずつ最適化する仕組みをまとめます。
アプリ開発2026-05-10
累計5,000万DLアプリの保守をAntigravityにどこまで任せられたか — 12年個人開発者の現場検証
2014年から個人で運用してきた累計5,000万DLの壁紙・癒し系アプリ群を題材に、Antigravityにどこまで保守を任せられるかを実測しました。任せられた領域・任せられなかった領域を、判断軸つきで共有します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →