新しいLPに広告を出すときは、キャンペーンとキーワードと広告文を毎回設定します。前回の記事で、この設定作業は2分で終わるようにしました。
ただ、広告は出した後も作業が続きます。配信を始めると、狙っていない検索語でもクリックされ、その分の広告費がかかります。「人事 評価 AI」や「アルバイト 求人」で来た人は、採用代行を探しているわけではありません。こうした検索を検索語句レポートから探して、1語ずつ除外していく作業が、毎日発生します。
今回は、この除外作業をAIにやらせて、毎朝自動で動くようにしました。朝、私がやるのは結果の確認だけです。
株式会社プロリクの橋崎です。前回の記事「【実践Claude Code】Google広告操作を自動化した全記録」の続きで、今回は広告を出した後の運用の話を書きます。
AHRとは?
AHR(AI and Human Resources)とは、企業の経営課題に向き合う組織能力を充足させるため、AI資源と人的資源を経営資源として設計・運用・再配分する、株式会社プロリクが2025年6月に提唱した実践フレームです。従来のHRが人的資源のみを扱ったのに対し、AHRはAIを人と並ぶ「経営のコア資源」と捉え、組織能力獲得を目指す考え方です。AHRは、株式会社プロリクの登録商標です。
📄 詳細記事: 【決定版】AHRとは?-人とAIの働き方をリデザインする
この記事の要点(TL;DR)
- 前回は「広告を作る」自動化。今回は「作った広告を運用し続ける」自動化
- 検索語句レポートを毎日取得し、gpt-5-miniが1語ずつ「除外すべきか」を判断。ムダな語を自動で除外リストに追加し、結果をSlackに通知
- 判断ルールは「本質的にニーズと違う語は弾く/競合名はニーズが近いので許容する」——人間の運用感覚をそのまま言語化してAIに渡した
- 自動化の鍵は「自分のPCに依存しないこと」。ローカルのcronは捨て、常時稼働のn8n(クラウド)に載せた
- n8nサンドボックスの罠、GPT-5系APIの作法、Slackの権限など6つの落とし穴を共有
- 初回実行で、20件の新規検索語から「人事評価AI」系3件+URLゴミ1件を正しく除外(「人事"評価"のAI」と「"採用"のAI」をAIが区別した)
出稿後、ムダな検索語が毎日たまる
Googleの検索広告では、「この言葉で検索した人に広告を出したい」という言葉を「キーワード」として登録します。ただし、登録したキーワードと完全に一致する検索にだけ広告が出るわけではありません。Googleは、登録キーワードに関連すると判断した検索にも広告を配信します。そのため、ユーザーが実際に入力した言葉——これを「検索語句」と呼びます——は、こちらが登録したキーワードよりずっと広い範囲に及びます。
この「実際に検索された言葉」は、管理画面の検索語句レポートに毎日たまっていきます。そして、その中には狙っていない検索が必ず混ざります。「採用代行」を狙って広告を出しているのに、「人事 評価 AI」や「アルバイト 求人」で検索した人にも表示され、クリックされてしまう、といった具合です。
クリックされれば、その分だけ広告費がかかります。狙っていない検索を放っておくと、関係ないクリックに毎日お金が流れ続けます。これを止めるために、検索語句レポートを定期的に開き、いらない語を「除外キーワード」(その語では以後広告を出さない設定)として登録していきます。
この作業には、面倒な点が2つあります。
1つは、除外するかどうかに判断が要ることです。「この検索語は採用代行を探している人か、そうでないか」を1語ずつ見ていき、Googleの管理画面で1つ1つ除外操作をしていくことになります。 そして、もう1つは、毎日発生することです。今日除外しても、翌日にはまた新しい検索語が溜まります。この作業を毎日手作業で30分かけるのは、小さい会社には負担でした。
AIでキーワード除外判断を自動化し、除外実行までを完全自動化した
そこで、振り分けの判断をAIによって行い、またGoogleの管理画面を操作して、自動で判断からキーワード除外までを自動化することを考えました。
キーワードを除外するかどうかは各社の担当者の価値観によると思いますが、私の場合は以下のように決めていきました。
採用に課題を持つ企業が、採用代行・AIスカウト・採用AIツールを探している。これが広告のターゲットで、ここと明らかに違う検索だけ除外する。比較検討や、まだ迷っている段階の検索は、採用を考えている人なので除外しない。
採用代行に直接的に関連するキーワードは、採用代行を検討している段階の人なので、狙いたいターゲットです。したがって、そのような直接なキーワードは除外しません。 一方で、「採用とは」「スカウトとは」といったような極めて潜在層に近いキーワード群や、「人事 評価 AI」といった、AIという単語は共通でも、探しているのは採用ではなく人事評価という領域違いものの場合は、キーワード除外をしていきたいわけです。
この振り分けの基準をプロンプトとして記述し、AIによってその判断を代替させることにしたわけです。 検索語を1語ずつ「除外(EXCLUDE)」か「残す(ALLOW)」で判定させ、判断に迷う語は残す(除外しすぎない)よう指示しています。
実行環境はn8n(クラウド)
最初は、自分のPC(WSL)のcronで毎朝8時に実行させようとしました。これはうまくいきませんでした。
PC上のcronは、PCが起動していてWSLが動いている間しか実行されません。毎朝8時にPCが立ち上がっている保証はなく、夜は止まっています。これでは毎朝動かないので、cronはやめました。
代わりに、社内で常時稼働しているn8n(クラウド)というノーコードツールに処理を載せることにしました。 クラウドなら、自分のPCの電源と関係なく毎朝実行されます。
構成はこうです。
[n8n / 毎朝8:00(JST)]
→ アクセストークン取得(OAuth・HTTP)
→ 検索語句レポート取得(Google Ads API・HTTP)
→ gpt-5-miniで1語ずつ判定(OpenAI API・HTTP)
→ 除外する語を共有除外リストへ追加(Google Ads API・HTTP)
→ Slackに当日のサマリを通知AIのモデルは、安いgpt-5-miniを利用しています。
判定から除外リストへの反映までをn8nの中で済ませ、結果をSlackに通知します。間違った除外があれば、共有除外リストからその語を手で削除します。
除外キーワードの追加は、課金が増える操作ではありません(むしろムダなクリックを止めます)。そのため、除外する語は自動で反映し、内容はSlackに通知して後から確認できるようにしました。
初回の実行結果
初回は、直近の新しい検索語が20件ありました。gpt-5-miniが除外と判断したのは、このうち4件です。
人事 評価 ai 事例(1クリック・¥486)→ 除外人事 評価 ai 活用→ 除外ai による 人事 評価→ 除外https ai mensetsu jp iframe view ...(URLのゴミ)→ 除外
「AI」という単語は共通でも、人事評価についての検索は採用ではないと判断して、3件とも除外の判断がされていました。一方で、「採用代行 おすすめ」「採用代行 比較」のような比較検討の語は、除外せず残っていました。私が手で振り分けた場合と、ほぼ同じ結果でした。
この4件は共有除外リストに追加され、配信中のすべての検索キャンペーンに反映されました。
つまずいた6つの落とし穴
前回記事と同じく、コードを書く時間より、環境まわりで詰まった時間の方が長かったです。 私は本職のエンジニアではなく、AIに聞きながら進めた記録です。同じことをやる方は、このリストをそのままClaude Codeに渡せば、私がやった回り道を省けると思います。
落とし穴1:ローカルのcronでは「毎朝自動」は実現できない
発生箇所:スケジュール実行
自分のPC(WSL)上のcronは、PCが起動していてWSLが動いている間しか走りません。毎朝決まった時刻に確実に動かしたいなら、常時稼働しているサーバーかクラウドが必要です。私はここで作りかけのcronをやめて、n8nに載せ替えました。
落とし穴2:「n8nからGoogle広告は触れないのでは?」は誤解
発生箇所:n8n
n8nに「Google Adsノード」は(少なくとも書き込み用途では)ありません。これで無理だと思い込みかけましたが、Google Ads APIはHTTPで叩けます。取得済みのリフレッシュトークンをアクセストークンに交換し、REST(googleAds:searchStream や sharedCriteria:mutate)をHTTPで呼ぶだけです。専用ノードもブラウザログインも要らず、HTTPリクエストノードだけで完結しました。
落とし穴3:n8nのコード実行環境には「あるはずの関数」が無い
発生箇所:n8nのCodeノード
ブラウザやNode.jsなら使える URLSearchParams が、n8nのサンドボックスでは undefined でした(ReferenceError)。フォーム形式の文字列は手動でエンコードする必要があります。同様に、ワークフローをまたいで状態を保存する機能は this.getWorkflowStaticData(...) ではなく、グローバル関数の $getWorkflowStaticData('global') で呼びます。通常のJavaScriptの感覚で書くと、この2つで連続して止まりました。
落とし穴4:GPT-5系APIは従来と書き方が違う
発生箇所:OpenAI API(判定部分)
判定にgpt-5-miniを使いましたが、GPT-5系は従来の書き方が通りません。temperature は指定するとエラー、max_tokens ではなく max_completion_tokens、内部の推論でトークンを使い切ると出力が空で返ることがあります。出力枠は多めに確保し、JSONで返させる指定をしておくと安全でした。
落とし穴5:Slackのbotは「チャンネルに招待」しないと投稿できない
発生箇所:Slack通知
認証情報を設定してチャンネルも選んだのに、not_in_channel というエラーで投稿できませんでした。通知用のbotがそのチャンネルのメンバーになっていなかったのが原因です。チャンネルの「インテグレーション」→「アプリを追加」でbotを招待したら、投稿できました。
落とし穴6:稼働中のワークフローは「設定未完了のノード」があると保存できない
発生箇所:n8n
ワークフローを有効(稼働)状態にしたまま、チャンネル未選択のSlackノードを追加して保存しようとすると、「必須パラメータがありません」で弾かれます。一度無効化してから保存し、設定を完成させてから有効化する、という順序が必要でした。
運用の変化
作業 | Before | After |
検索語句レポートの確認 | 毎日〜毎週、手で開く | 毎朝自動取得 |
除外する語の判断 | 1語ずつ人間が判断 | gpt-5-miniが自動判定 |
除外キーワードの反映 | 管理画面で手作業 | 自動反映(全キャンペーンに即時) |
結果の把握 | 自分で見に行く | Slackに毎朝サマリ通知 |
動かす場所 | 自分のPC(不安定) | クラウドで常時稼働 |
作業時間も減りましたが、それより、毎朝レポートを開く必要がなくなったのが大きいです。除外の判断と反映をn8nとAIに任せたので、私の作業は、通知された結果におかしな除外がないかを見る程度になりました。
まとめ
今回作ったのは、検索語句を毎朝取得し、除外するかをgpt-5-miniに判定させ、除外する語を共有リストに追加し、結果をSlackに通知する、という処理です。 Claude Codeに「こうしたい」と伝え、エラーが出たら貼って直してもらう、というやり方で非エンジニアでも自動化を実現することができました。
毎日広告費が動く運用でも、思いついた日にAIに相談して、まず小さく作って試せます。 同じことをやる方は、上の落とし穴リストもあわせてClaude Codeに渡してみてください。
弊社お問い合わせ窓口 株式会社プロリクでは生成AI導入支援、Claude Codeの実装サポートを行っております。もしご要望ございましたらお気軽にお問い合わせください。
著者について
橋崎 良哉(株式会社プロリク )
Webサイト制作事業にて在学中に起業。家業に入り、鉄鋼加工会社で取締役として業績回復を牽引。その後グローバルに特化したデジタルマーケティング支援会社にてマーケター、データ解析などを担当した後、AIスタートアップであるエッジテクノロジー株式会社の取締役COOとして、機械学習実装支援や、機械学習を用いた営業自動化SaaSを立ち上げ、6年で0から社員70名程度までグロースさせる。2020年2月株式会社プロリクを設立。
よくある質問(FAQ)
Q. Google広告の除外キーワードとは何ですか? A. 指定した語では以後広告を出さない設定です。狙っていない検索(人事評価やアルバイト探しなど)で広告がクリックされ、広告費がムダに流れるのを止めるために使います。検索語句レポートに毎日たまる語から、いらないものを登録していきます。
Q. 除外キーワードを追加すると広告費が増えることはありますか? A. ありません。除外キーワードは広告を「止める」設定なので、課金が増えることは原理的になく、むしろムダなクリックを減らします。ただし、本当は狙いたい語を誤って除外すると、その語で広告が出なくなる機会損失には注意が必要です。
Q. 検索語句レポートとは何ですか? A. 実際にユーザーが検索した言葉(検索語句)の一覧です。登録した「キーワード」に関連するとGoogleが判断した検索にも広告が出るため、検索語句はキーワードより広い範囲に及びます。ここに狙っていない検索が混ざるので、定期的に開いて除外する語を探します。
Q. 除外キーワードの判定をAIに任せて大丈夫ですか? A. 判定の下書きはAIに任せられますが、「迷ったら残す(除外しすぎない)」と指示するのが安全です。今回はgpt-5-miniに1語ずつ「除外」か「残す」を判定させ、結果はSlackに通知して、おかしな除外があれば手で削除できるようにしました。
Q. なぜ自分のPCのcronではなく、n8nを使ったのですか? A. PC上のcronは、PCが起動している間しか動きません。毎朝決まった時刻に確実に動かすには、常時稼働しているクラウドが必要です。そのため、社内で常時稼働しているn8n(クラウドのノーコードツール)に処理を載せました。
Q. n8nからGoogle広告は操作できますか? A. できます。n8nにGoogle広告を書き込む専用ノードはありませんが、Google Ads APIをHTTPリクエストノードから直接呼び出せます。専用ノードもブラウザログインも要らず、検索語句の取得から除外リストへの追加まで完結しました。
Q. gpt-5-mini(GPT-5系のAPI)を使うときの注意点は? A. 従来の書き方が通りません。temperatureは指定するとエラーになり、max_tokensではなくmax_completion_tokensを使い、内部の推論でトークンを使い切ると出力が空で返ることがあります。出力枠を多めに確保し、JSONで返させる指定をしておくと安全です。
Q. 実際にどれくらいの検索語が除外されましたか? A. 初回は新しい検索語20件のうち4件が除外されました。「人事 評価 AI」系が3件と、URLのゴミが1件です。「採用代行 おすすめ」「採用代行 比較」のような比較検討の語は残り、手で振り分けた場合とほぼ同じ結果でした。
Q. 除外した語が間違っていたら、どう戻しますか? A. 共有除外リストから、その語を手で削除すれば戻せます。今回は除外を自動で反映しつつ、結果を毎朝Slackに通知して後から確認できるようにしているので、誤った除外に気づいたらすぐ取り消せます。
Q. 非エンジニアでもこの自動化は作れますか? A. 作れます。今回も社内にエンジニアはいません。Claude Codeに「こうしたい」と伝え、エラーが出たらそのまま貼って直してもらう進め方で、その日のうちに動きました。