TECH PLAY

株式会社G-gen

株式会社G-gen の技術ブログ

734

G-genの杉村です。Google Cloud の Identity-Aware Proxy (IAP)で、プロジェクトの所属組織とは異なる Google Workspace 組織の Google アカウントからのアクセスを許可する方法を解説します。 はじめに Identity-Aware Proxy(IAP)とは デフォルトの挙動と課題 カスタム OAuth クライアントの利用 注意点 設定手順の概要 OAuth 同意画面の設定 カスタム OAuth クライアントの作成 IAP にカスタム OAuth クライアントを設定 アクセス許可の設定 はじめに Identity-Aware Proxy(IAP)とは Identity-Aware Proxy (IAP)は、Google Cloud 上で稼働するアプリケーションに対して、ユーザーの ID に基づいた認証機構を提供するサービスです。アプリケーション自体に認証・認可の仕組みを実装しなくても、ロードバランサーや Cloud Run サービスなどのレベルで、安全なアクセス制御を実現します。 IAP を有効化すると、ユーザーはアプリケーションにアクセスする前に Google アカウントでの認証を求められます。認証後、IAM で付与されたロールに基づいてアクセスが許可または拒否されます。 参考 : Identity-Aware Proxy の概要 (図) また IAP は VM への SSH/RDP ログインのための踏み台としても使うことができます。以下の記事も参照してください。 blog.g-gen.co.jp デフォルトの挙動と課題 IAP を有効化すると、デフォルトでは「 Google が管理する OAuth クライアント 」が自動的に作成され、認証に使用されます。この OAuth クライアントは、認証を求めるユーザーが、その Google Cloud プロジェクトが属する Google Cloud 組織と 同じ Google Workspace(または Cloud Identity)組織に所属していることを前提 としています。 参考 : Google 管理の OAuth クライアントを使用して IAP を有効にする 例えば、 example-a.com というドメインを持つ A 社の Google Cloud 組織配下のプロジェクトで動作する Cloud Run でホストされた Web アプリケーションにおいて IAP を有効にした場合、デフォルトでは @example-a.com ドメインの Google アカウントを持つユーザーしか認証を通過できません。アプリケーションを使わせたい顧客である B 社のユーザー( @example-b.com )にアクセスを許可しようとしても、認証画面でエラーとなりアクセスができません。 You don't have access You don't have access. If you're signed in with multiple Google accounts, try a different account. If you should have access, please contact xxx and provide the troubleshooting info above. カスタム OAuth クライアントの利用 この事象は、IAP で使用する OAuth クライアントを、Google 管理のものではなく自前で作成した「 カスタムOAuthクライアント 」に切り替えることで解決できます。 参考 : OAuth 構成をカスタマイズして IAP の有効化 カスタム OAuth クライアントを利用することで、認証を許可する Google アカウントのドメイン(組織)に関する制約がなくなります。これにより、任意の Google アカウントを持つユーザーに対して、IAM ポリシーでアクセスを許可できるようになります。 当記事では、このカスタム OAuth クライアントを作成し、IAP に設定するまでの手順を解説します。 注意点 Cloud Run services では、サービスのレベルで IAP を設定可能です。この方法では Cloud Load Balancing を必要としませんが、認証できるのは Google Cloud プロジェクトと同じ組織に所属する Google アカウントのみです。当記事で紹介する方法は使えませんのでご注意ください。当記事の方法で外部組織のアカウントを認証するには、ロードバランサーが必要です。 参考 : Configure Identity-Aware Proxy for Cloud Run 以下の記事も参考にしてください。 blog.g-gen.co.jp 設定手順の概要 設定は大きく分けて以下の4ステップです。 OAuth 同意画面の設定 カスタム OAuth クライアントの作成 IAP にカスタム OAuth クライアントを設定 アクセス許可の設定 なお前提として、すでに Cloud Load Balancing を使い外部ロードバランサーがセットアップ済みであり、インターネット公開のアプリケーションの準備ができているものとします。バックエンドは Cloud Run でも、Compute Engine でも、種類は問いません。 OAuth 同意画面の設定 カスタム OAuth クライアントを作成する前に、プロジェクトで OAuth同意画面 を設定する必要があります。OAuth 同意画面とは、ユーザーがアプリケーションに個人情報へのアクセスを許可する際に表示される画面のことです。 Google Cloud コンソールの上部検索ボックスに「Google Auth Platform」と入力して表示されるサジェストから「Google Auth Platform」画面へ進みます。 同意画面が未設定の場合、「Google Auth Platform はまだ構成されていません」と表示されるので下部ボタン「開始」をクリックします。ここではアプリ名、連絡先のメールアドレスなどを設定します。ここで、「対象(User Type)」として「 外部 」を選択します。この設定は、OAuth 同意画面の初期設定時のほか、あとからでも変更可能です。 「外部」を選択 参考 : Manage OAuth App Branding 参考 : Manage App Audience カスタム OAuth クライアントの作成 次に、カスタム OAuth クライアントを作成します。 Google Cloud コンソールの「Google Auth Platform」から「クライアント」へ進み、「+ クライアントを作成」を押下します。クライアントは、以下のとおり作成します。 設定項目 設定値 アプリケーションの種類 ウェブ アプリケーション 名前 (任意) 承認済みの JavaScript 生成元 (何も追加しない) 承認済みのリダイレクト URI (何も追加しない) 「作成」をクリックすると、クライアント ID とクライアントシークレットが表示されます。この値は後ほど使用するため、必ず控えておきます。機微な情報のため、注意して扱ってください。 一度クライアントを作成した後、再度 そのクライアントの編集画面を開き、「 承認済みのリダイレクト URI 」を設定します。これは、Google の認証サーバーがユーザーの認証後にリダイレクトさせる宛先を指定するもので、IAP の動作において不可欠な設定です。 「承認済みのリダイレクト URI」の下部にある「URI を追加」をクリックし、以下の形式の URI を入力します。 ${CLIENT_ID} の部分は、先ほど作成した OAuth クライアントの クライアント ID に置き換えてください(クライアントシークレットではありません)。 https://iap.googleapis.com/v1/oauth/clientIds/${CLIENT_ID}:handleRedirect URI は、例えば以下のような値になります。 https://iap.googleapis.com/v1/oauth/clientIds/123456789012-abcdefghijklmnopqr.apps.googleusercontent.com:handleRedirect 設定後、「保存」をクリックします。 OAuth Client の設定 この URI 指定方法については、IAP で外部組織の Google アカウントを設定する方法としては公式ドキュメントには記載がありませんが、以下の Workforce Identity 連携と IAP の併用に関する公式ドキュメントに記載があり、Google アカウントの場合でも同様です。 参考 : Workforce Identity 連携で IAP の構成 - OAuth クライアント ID とシークレットを作成する IAP にカスタム OAuth クライアントを設定 作成したカスタム OAuth クライアントを IAP で使用するよう設定を変更します。 Google Cloud コンソールの「セキュリティ」から「Identity-Aware Proxy」へ移動します。設定を変更したいバックエンドサービスの「IAP」チェックボックスをオンにし、右側の三点リーダーをクリックすると表示されるプルダウンメニューから「設定」をクリックします。 プルダウンメニューから「設定」 OAuth クライアントの選択画面で、「 カスタム OAuth(特定の制御、ブランディング、外部ユーザー用) 」を選択します。 前の手順で控えておいた クライアント ID と クライアントシークレット を入力し、「保存」をクリックします。 カスタム OAuth を選択して ID とシークレットを入力 アクセス許可の設定 最後に、アクセスを許可したい他組織のユーザーやグループ、ドメインに対して IAM ロールを付与します。 IAP の管理画面で対象のバックエンドサービス等を選択し、右パネルの「プリンシパルを追加」をクリックします。 「新しいプリンシパル」に、アクセスを許可したい Google アカウント( john.doe@example-b.com )、Googleグループ( dev-group@example-b.com )、またはドメイン全体( example-b.com )を入力します。 ロールには、 IAP-secured Web App User を選択し、保存します。 プリンシパルを追加 以上で設定は完了です。許可した他組織の Google アカウントでアプリケーションにアクセスすると、Google のログイン画面が表示され、認証後にアプリケーションが利用できることが確認できます。 ログイン画面 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-genの杉村です。BigQuery に組み込まれた AI アシスタント機能である Gemini in BigQuery を解説します。当機能では、SQL の自動生成やデータ変換、メタデータの自動生成など、データ分析の様々なタスクを効率化することができます。 はじめに Gemini in BigQuery とは データの保護 自然言語によるクエリ 料金と割り当て 利用料金 使用可能な機能 割り当て(Quota) 準備 API の有効化 IAM 権限の付与 SQL コーディング補助 概要 有効化 SQL 生成ツール コメントからの自動生成 Gemini Cloud Assist による生成 コード補完 精度向上のコツ SQL の説明 Python コーディング支援 概要 有効化 コード生成と補完 データキャンバス(Data canvas) 概要 使用方法 データ準備(Data preparation) データ分析情報(Data insights) メタデータ自動生成 SQL 変換支援 はじめに Gemini in BigQuery とは Gemini in BigQuery とは、Google Cloud の生成 AI モデルである Gemini を BigQuery に統合した機能群の総称です。ほとんどの機能を原則無料で利用することができます。Gemini in BigQuery は、Google Cloud の AI 支援機能群である Gemini for Google Cloud サービスの一部として位置づけられています。 参考 : Gemini in BigQuery の Gemini の概要 Gemini in BigQuery を利用することで、自然言語による指示(プロンプト)を通じて、データ分析ワークフローの様々なタスクを自動化・効率化できます。 Gemini in BigQuery の機能として、以下が提供されています。 SQL コーディング支援 Python コーディング支援(BigQuery ノートブック) データキャンバス(Data canvas。自然言語によるデータ分析) データ準備(Data preparation。自然言語によるデータ変換) データ分析情報(Data insights) メタデータ自動生成 SQL 変換(他方言から GoogleSQL への変換)支援 データの保護 Gemini in BigQuery に入力されるプロンプトや出力されるレスポンスは、Google Cloud の利用規約に従って保護されます。これらのデータが、Google のモデルのトレーニングに許可なく使用されるようなことはありません。 また、保存時および転送時のデータは常に、透過的に暗号化されています。 詳細は以下のドキュメントを参照してください。 参考 : Security, privacy, and compliance for Gemini in BigQuery 自然言語によるクエリ Gemini in BigQuery には、自然言語によってデータをクエリするためのいくつかの機能が含まれています。しかしながら、BigQuery に自然言語でクエリする手段は、Gemini in BigQuery だけではありません。以下の記事も参考にして下さい。 blog.g-gen.co.jp 料金と割り当て 利用料金 Gemini in BigQuery は、 原則無料 で利用できます。 ただし、どの BigQuery 料金体系を選択しているか(オンデマンドもしくは Editions)によって使用可能な機能が異なります。また、機能の呼び出し回数に制限(割り当て)があります。 参考 : Gemini for Google Cloud pricing - Gemini in BigQuery Pricing Overview BigQuery の料金体系については、以下の記事を参考にしてください。 blog.g-gen.co.jp 使用可能な機能 BigQuery ジョブを実行する Google Cloud プロジェクトの料金体系として、デフォルトの オンデマンドモード 、もしくは BigQuery Enterprise Edition 、 Enterprise Plus Edition を使用している場合、Gemini in BigQuery の すべての機能が使用できます 。ただし、機能の呼び出し回数には後述の制限(割り当て)があります。 プロジェクトで BigQuery Standard Edition を使用している場合のみ機能制限があり、データ分析情報(Data insights) とメタデータ自動生成が 使用できません 。 ただし、Gemini Code Assist の有償ライセンスを購入している場合、BigQuery の料金体系に関係なく、ライセンスに紐づいているユーザーはデータ分析情報(Data insights) とメタデータ自動生成の2機能を使用することができるようになります。 割り当て(Quota) Gemini in BigQuery では、機能の呼び出し回数に制限があります。この制限は 割り当て (Quota)と呼ばれています。 当記事の説明は2025年8月現在の英語版ドキュメントに基づいています。最新の情報や詳細な計算式などは、以下の公式ドキュメントを参照してください。 参考 : Quotas and limits 参考 : Gemini for Google Cloud pricing - Gemini in BigQuery Pricing Overview SQL・Python のコード補完・生成機能の割り当ては、以下のとおりです。割り当てはユーザーごとに適用されます。 割り当て名称 値 1秒あたりのリクエスト数 2 1日あたりのリクエスト数 6,000 データキャンバス(Data canvas)、データ準備(Data preparation)の割り当ては以下の通りです。割り当てはユーザーごとに適用されます。 割り当て名称 値 1日あたりのリクエスト数 960 一方、データ分析情報(Data insights) とメタデータ自動生成の2機能の割り当ては、 前月の BigQuery 使用ボリューム(1日あたりの平均)に応じて計算 されて決まります。割り当ては組織レベルで適用され、同じ組織に所属するすべてのプロジェクトで共有されます。 以下の表の (前月の1日あたりの平均使用量) は、オンデマンドモードの場合はスキャンデータ量の TiB 数です。BigQuery Enterprise または Enterprise Plus Edition の場合は、100スロット時間です。使用ボリュームは100スロット単位で切り上げられます。 割り当て名称 値 1日あたりのリクエスト数 (前月の1日あたりの平均使用量) × 5 ただし、Gemini Code Assist 有償サブスクリプションと紐づいているユーザーは、960回の割り当てが別で与えられます。 前月に BigQuery の使用実績がない場合は、250回/日の割り当てが適用されます。 準備 参考 : Gemini in BigQuery を設定する API の有効化 Gemini in BigQuery は、Google Cloud プロジェクトで Gemini for Google Cloud API( cloudaicompanion.googleapis.com )および BigQuery Unified API( bigqueryunified.googleapis.com )を有効にするだけで機能が使用可能になります。 2025年7月30日のアップデートにより、必要な API はほとんどのプロジェクトでデフォルトで有効になったとされています。 参考 : BigQuery release notes - July 30, 2025 もし API が有効になっていない場合は以下の方法で有効化します。 BigQuery Studio(BigQuery の Web コンソール画面)の右上部分に表示されている鉛筆マークがグレーアウトされている場合は、必要な API が有効になっていません。鉛筆マークにマウスオーバーすると、以下のような表示がポップアップします。「続行」をクリックすると表示されるガイダンスに従って操作することで、API を有効化することができます。 API の有効化 なお、上記の操作方法およびスクリーンショットは、2025年8月現在のものです。 IAM 権限の付与 API を有効化したプロジェクトでは Gemini in BigQuery が使用可能になりますが、ユーザーが適切な権限を持っている必要があります。操作者の Google アカウントがプロジェクトに対して以下の IAM ロールのいずれかを持っていると、Gemini in BigQuery の機能が使用可能です。 BigQuery Studio ユーザー( roles/bigquery.studioUser ) BigQuery Studio 管理者( roles/bigquery.studioAdmin ) あるいは、既にプロジェクトで BigQuery を使用する権限を持っているユーザーに対しては、以下のようなロールをプロジェクトレベルで付与することでも使用可能です。 Gemini for Google Cloud ユーザー( roles/cloudaicompanion.user ) SQL コーディング補助 概要 Gemini in BigQuery には SQL のコーディング補助機能があり、AI による SQL の補完、生成、解説を行うことができます。 コーディング補助は、BigQuery の Web ユーザーインターフェイスである BigQuery Studio 上で使用できます。 参考 : Gemini のアシスタント機能を使用してクエリを作成する 有効化 前提として、使用するプロジェクトで、前述の手順により関連 API が有効化されている必要があります。 その後、BigQuery Studio 画面の鉛筆マークをクリックして表示されるプルダウンメニューから、「SQL クエリの Gemini」の下にある「予測入力」「自動生成」「SQL 生成ツール」にチェックマークを入れます。 SQL 生成の有効化 SQL 生成ツール 自然言語から SQL を生成させるには、SQL 編集エリアの左側に表示される鉛筆マークをクリックします。 鉛筆マーク ポップアップされたテキストエリアに自然言語で指示を記載します。以下のスクリーンショットでは、特に分析対象のテーブルを指定していません。 プロンプト入力画面がポップアップする しかしこの時は、直近でパブリックデータセットのテーブル bigquery-public-data.usa_names.usa_1910_current の詳細画面を表示していました。Gemini はそれを踏まえて、このテーブルへクエリする SQL を生成してくれました。挿入ボタンを押すと、生成された SQL がエディタに挿入されます。 生成された SQL コメントからの自動生成 ポップアップ画面を開かなくても、SQL エディタ内に コメント により自然言語で指示を記載することでも、SQL を生成できます。コメントは -- で始めても、 # で始めても構いません。「SQL 生成ツール」と同様に、テーブルを明示的に指示しなくても直近で開いたテーブルなどを踏まえて生成してくれますが、以下のスクリーンショットは明示的にテーブル ID を指定しました。 コメントを入力して改行するだけで SQL が生成されサジェストされる コメントを入力して Enter を押下して改行すると、鉛筆マークが表示される位置で、処理中を示す回転アイコンが表示されます。しばらく待つとグレー文字で SQL がサジェストされます。Tab キーを押下すると、SQL が挿入されます。 Gemini Cloud Assist による生成 画面右上の Gemini アイコンを押下すると表示される Gemini Cloud Assist のサイドパネル(チャットパネル)でも、自然言語で指示することで SQL の生成が可能です。 Gemini Cloud Assist のサイドパネル コード補完 SQL を記述していると、何もしなくても行番号の横で回転アイコンが表示され、しばらく待つと SQL がサジェストされます。 Tab キーを押下すると、提案内容が挿入されます。 SQL の続きがサジェストされる 精度向上のコツ SQL 生成の提案精度を向上させるには、以下を踏まえて指示をします。 テーブル ID はバッククォート(`)で囲む コンテキスト(背景情報)を十分指示に含ませる。列名や、列名と回答との関連性、複雑な用語などを含ませる コメントからの SQL 生成時、コメントは複数行でも可能 Gemini は BigQuery テーブルや列の説明(Description)を読み取る。説明(Description)を充実させることで精度が向上する SQL の説明 既存の SQL を、Gemini に自然言語で解説させることもできます。ただし2025年8月現在、当機能は Google Cloud コンソールの設定(Preferences)で 言語設定を英語 にしていないと使えません。 BigQuery Studio のクエリエディタ上で、説明させたい SQL を選択して、左側に表示される星型のマークをクリックして表示されるプルダウンメニューから Explain this query を選択します。 クエリを選択し、AI マークをクリックしてから Explain this query を選択 すると、画面右側に Gemini Cloud Assist のチャットパネルが開き、SQL の意味が自然言語で解説されます。 チャットパネル内で SQL が解説される 2025年8月現在は、Google Cloud コンソールの設定を英語にしないと使えませんが、コンソール設定が英語でも、解説に続いて「日本語で解説して」のように入力すると、日本語での解説が出力されます。 日本語で出力された解説 Python コーディング支援 概要 Gemini in BigQuery には Python のコーディング補助機能もあります。BigQuery ノートブック上で、AI による Python の補完、生成、解説を行うことができます。 Python コーディング補助は、BigQuery の Web ユーザーインターフェイス上で使える Jupyter ノートブックで使用できます。このノートブックは、バックエンドで Google Cloud のフルマネージドサービスである Colab Enterprise が使用されています。ノートブック上では、Python ソースコードを記述・実行できます。 参考 : Gemini のアシスタント機能を使用してクエリを作成する - Python コードを生成する 有効化 前提として、使用するプロジェクトで、前述の手順により関連 API が有効化されている必要があります。 その後、BigQuery Studio 画面の鉛筆マークをクリックして表示されるプルダウンメニューから、「Python ノートブックの Gemini」の下にある「コード補完」「コード生成」にチェックマークを入れます。 Python コード生成の有効化 コード生成と補完 ノートブック上では、Gemini アイコンを押すことでコードを生成させたり、解説させたりすることができます。 また、コーディング中に補完内容が自動でサジェストされます。Tab キーを押すと、コードが挿入されます。 SQL コーディングと同様に、Gemini Cloud Assist のサイドパネルでもコード生成が可能です。 ノートブック上でのコード生成・補完 データキャンバス(Data canvas) 概要 データキャンバス (Data canvas)は自然言語による指示と、グラフィカルなユーザーインターフェイスによってデータの検索、変換、クエリ、可視化を行う機能です。 この機能を使うことで、SQL のスキルがないユーザーでも、自然言語により BigQuery のデータをクエリすることができます。複数テーブルの結合を含むある程度複雑な質問にも答えることができます。 参考 : BigQuery データ キャンバスで分析する データキャンバス(Data canvas) データキャンバスの使い方や使用例については、以下の記事も参考になります。 blog.g-gen.co.jp 使用方法 データキャンバスを使うには、BigQuery Studio において、新しいクエリエディタのタブを開く + ボタンの 右にある逆三角形 を押して表示されるプルダウンメニューから「データ キャンバス」を選択します。 プルダウンから「データ キャンバス」を選択 以下のように、データキャンバスが開きます。まずは、対象のテーブルを選びます。最近開いたテーブルの履歴から選択したり、あるいは Search for data をクリックして対象テーブルを検索することもできます。 データキャンバスの画面 テーブルは複数個、キャンバスに追加できます。以下のスクリーンショットでは、架空の売上トランザクションデータと、架空の顧客マスタテーブルを追加しました。 複数テーブルをキャンバスに追加 左下に表示されている「 キャンバスアシスタントに聞く 」ボタンを押すと、キャンバス上のテーブルに、自然言語でクエリすることができます。キャンバス上では明示的にクエリや結合などを指示することもできますが、取っ掛かりがない場合はキャンバスアシスタントに聞くことで、ヒントを得ることができます。 キャンバスアシスタント スクリーンショットの例では、「2024年の売上を、売上チャンネル別に算出して」と指示しました。明示的にテーブルを指定していなくても、適切に「sales」テーブルへクエリが発行されました。また、クエリ結果はチャート(図表)でも表示されます。 キャンバスアシスタントが質問に応じてクエリを発行 クエリ結果はチャート(図表)でも表示される 複数テーブルの結合が必要な質問にも、適切にクエリが生成されました。テーブル間の結合が線でグラフィカルに表現されています。 複数テーブルの結合 キャンバスアシスタントを使う以外にも、柔軟な使い方が可能です。テーブルを選択して「クエリ」をクリックすると、SQL を記述できます。自然言語で指示して、Gemini にクエリを書かせることもできます。 テーブルを選択して「クエリ」をクリック テーブルを選択して「高度な分析」をクリックすると、BigQuery ノートブック(Colab Enterprise)を利用して、テーブルに Python を使った分析が実行できます。ここでも、ソースコードを Gemini に書かせることが可能です。 テーブルを選択して「高度な分析」をクリック テーブルを選択して「結合」をクリックすると、結合相手のテーブルを指定して、結合クエリを記述、または Gemini に書かせることができます。 テーブルを選択して「結合」をクリック データ準備(Data preparation) データ準備 (Data preparation)は、生成 AI を利用した簡易的なデータ準備ツールです。Gemini の補助のもと、データのプレビューを確認しながら自然言語でデータ変換のロジックを開発できます。 定義した data preparation は、オンデマンドに実行することも、スケジュールに基づいて定期的に実行することもできるので、簡易的な ELT(ETL)ワークフローとして利用可能です。 参考 : BigQuery データの準備の概要 データ準備(Data preparation) データ分析情報(Data insights) データ分析情報 (Data insights)機能を BigQuery テーブルに対して実行すると、テーブルのメタデータ(テーブルや列の説明)に基づいて、Gemini が自然言語の質問とそれに対応する SQL クエリを複数個生成します。 この機能により、テーブルに対して分析を始めるに当たっての取っ掛かりとなる問いや、それに対応する SQL を速やかに生成することができます。データ分析情報(Data insights)は、データ分析の初速を向上するための機能であるといえます。 参考 : BigQuery でデータ分析情報を生成する データ分析情報(Data insights)で生成された問いとクエリ メタデータ自動生成 メタデータ自動生成 を使うと、BigQuery テーブルとその列の説明(Description)を自動生成することができます。Gemini がテーブルデータに基づいてテーブルの性質やカラムの性質を判断して、自然言語による説明を生成してくれます。 参考 : Generate data insights in BigQuery - Generate table and column descriptions 生成された説明(Description) 詳細は以下の記事を参照してください。 blog.g-gen.co.jp SQL 変換支援 Gemini in BigQuery には、他方言の SQL を BigQuery で使う GoogleSQL へ変換する機能が備わっています。 当機能は、以下のような SQL 方言に対応しています(一部抜粋)。 Amazon Redshift SQL Apache HiveQL IBM Netezza SQL Teradata Apache Spark SQL Azure Synapse T-SQL IBM DB2 SQL MySQL SQL Oracle SQL, PL/SQL, Exadata PostgreSQL SQL PrestoSQL(Trino) Snowflake SQL SQL Server T-SQL SQLite 当機能を使用するには、BigQuery Studio のエディタを使用します。以下のように、変換元と変換後のクエリを対照させて確認できます。また変換ルールを定義することで、変換方法をカスタマイズすることもできます。 Gemini による SQL 変換支援 詳細は、以下の公式ドキュメントを参照してください。 参考 : インタラクティブな SQL トランスレータを使用してクエリを変換する 杉村 勇馬 (記事一覧) 執行役員 CTO 元警察官という経歴を持つ IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
Google Cloud Next Tokyo '25 の「Next Tokyo イベントアンバサダー」に選出いただきました G-gen の堂原です。当記事は、Google Cloud Next '25 Tokyo の2日目に行われた ブレイクアウトセッション「 最新技術で実現する Pokémon Trading Card Game Pocket のスケーラブルな運用とコスト最適化 」 のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 全体アーキテクチャ Spanner Pre-splitting で大規模なスパイクに立ち向かう 概要 Spanner について Spanner の負荷分散の仕組みと課題 スパイクに対するこれまでの対処法 Pre-splitting C4A インスタンスへの移行 概要 C4A インスタンスとは 導入効果 セッションの概要 本セッションでは、月間アクティブユーザ数が 5,100 万人(2024 年度第 4 四半期平均)にも達するスマートフォン向けゲームアプリ Pokémon Trading Card Game Pocket (以下、ポケポケ)のアーキテクチャ及び、インフラ基盤で取り入れられている最新技術について紹介されました。 全体アーキテクチャ ポケポケのインフラ基盤は、API Server と Battle Server の 2 つの Google Kubernetes Engine(GKE) クラスタで構成されています。 API Server はプレイヤー情報の管理やマッチメイキングを行い、Battle Server では実際の対戦処理が行われます。API Server のデータベースとしては Spanner が稼働しています。 実際のアクセス数は非公表であるものの、本基盤に対して以下の規模の負荷試験を実施したとのことです。 API Server に対して 70 万 RPS(Request Per Second)以上 Spanner に対して 1,000 万 QPS(Query Per Second)以上 スパイクは 3 分間で 9 倍以上 Spanner Pre-splitting で大規模なスパイクに立ち向かう 概要 前半パートでは、Spanner を運用するにあたって考える必要があるスプリット戦略について、ポケポケで採用されている Pre-splitting という機能が紹介されました。 Spanner について Spanner (または Cloud Spanner)は Google Cloud が提供するフルマネージドデータベースであり、強整合性を保証しつつ水平スケーリングが可能なデータベースとなっています。 Spanner については、以下の記事で解説していますのでご参照ください。 blog.g-gen.co.jp Spanner の負荷分散の仕組みと課題 Spanner では、データが スプリット という単位に分割されて管理されています。Spanner の処理部である ノード が、それぞれに割り当てられたスプリットの処理を行うことで負荷分散が行われています。スプリットは負荷状況に応じて、自動で追加や削除が行われます。 参考 : スキーマの概要  |  Spanner  |  Google Cloud そんなスプリットですが、自動で追加されるまでには時間がかかるため、スパイク時には追加が間に合わずレイテンシが悪化するという課題があります。 スパイクに対するこれまでの対処法 スパイクに対してスプリットの追加が間に合わないという課題に対して、これまでは ウォームアップ を実施することで対処されていたそうです。ローンチ前にダミーデータであらかじめ負荷をかけておくことで、十分なスプリットを確保した状態でローンチするという手法となります。 ただし、この方法にも以下のような課題がありました。 ローンチ後に発生するスパイクに対しては使用できない ウォームアップ中は人が張り付いて負荷状況を調整しないといけない ミスをするとスプリットを割りすぎてコスト増加につながる Pre-splitting Pre-splitting は、特定のテーブル・インデックスのスプリットを予め設定することができる機能です。この機能により、ローンチ時など、スパイクが想定されるタイミングで事前にスプリットを増やすことができます。 本機能を使うことにより、ポケポケではスプリット不足が起因のレイテンシ悪化がほぼ無くなったとのことです。ただし、以下のような配慮すべきポイントについても紹介されていました。 スプリットポイント(どの値でスプリットを分けるか)が不適切な場合、特定のスプリットに負荷が集中する(ホットスポット) スプリット数の予測 スプリット数が少ないと、ホットスポットが発生する スプリット数が多いと、ノード数が減らせずコスト増加につながる スパイク後はノード数を減らすことでコスト削減が可能だが、1 ノードあたりのスプリット数が増えすぎるとパフォーマンスが低下する 目安として「1 ノード 50 スプリットを超える際は慎重に」と紹介されていました C4A インスタンスへの移行 概要 後半パートでは、GKE クラスタのインスタンスとして C4A インスタンス を導入した事例について紹介されました。 C4A インスタンスとは C4A インスタンスは、Google Cloud が提供する Compute Engine マシンタイプの一種です。2024 年 10 月 31 日に一般提供が開始され、Arm ベースの Axion プロセッサが搭載されています。メモリについても、均一メモリアクセス(UMA)が採用されており、一貫したパフォーマンスを提供することができます。 参考 : Compute Engine の汎用マシン ファミリー  |  Compute Engine Documentation  |  Google Cloud 導入効果 Google 公式ブログ において、x86 ベースのインスタンスと比べて費用対効果が最大 65% 向上すると記載されている C4A インスタンスですが、ポケポケ環境においては、それまで採用していた Tau T2D インスタンスと比較して以下のような費用対効果が得られました。 API Server : 73% 向上 Battle Server : 11% 向上 また、Tau T2D インスタンスではメモリアクセスに起因して発生していた CPU 性能の劣化についても、先述の通り UMA が採用されている C4A インスタンスでは発生することが無くなったそうです。 更に、セッションではマシンタイプの移行に際して以下のような利点が紹介されていました。 Tau T2D インスタンスから C4A インスタンスへの移行が容易であった C4A インスタンスは CPU 使用率に対して、比例的に許容 RPS が伸びた 他のマシンタイプの場合、ハイパースレッディングがあると CPU 使用率 50 % を境に性能の劣化が見られることがある エネルギー効率も最大 60% と高く、環境に配慮したマシンタイプとなっている 堂原 竜希 (記事一覧) クラウドソリューション部クラウドエクスプローラ課。2023年4月より、G-genにジョイン。 Google Cloud Partner Top Engineer 2023, 2024, 2025に選出 (2024年はRookie of the year、2025年はFellowにも選出)。休みの日はだいたいゲームをしているか、時々自転車で遠出をしています。 Follow @ryu_dohara
アバター
Google Cloud Next Tokyo '25 の「Next Tokyo イベントアンバサダー」に選出いただきました G-gen の堂原です。当記事は、Google Cloud Next '25 Tokyo の2日目に行われた ブレイクアウトセッション「 AI Agent で実現するメルカリの顧客エンゲージメント変革 」 のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 高まる期待と新たなニーズ 新たな顧客体験の創造 メルカリ社の事例紹介 概要 採用理由 導入時の障壁 デモ セッションの概要 本セッションでは、Google Cloud が提供するカスタマーサービス業務向けのプロダクト群である Customer Engagement Suite の概要と、メルカリ社での導入事例が紹介されました。 高まる期待と新たなニーズ はじめに Google Cloud 社の鈴木氏より、企業における AI 利用の進化について説明されました。 主にチャットボットから始まった AI の利用は、AI エージェントを経てより自律した、能動的に動く存在へと進化していくだろうと期待されています。 そんな中、顧客体験への期待値は大きく上がってきています。顧客ごとにパーソナライズされた顧客体験の提供や能動的な働きかけを通じて、カスタマーサービスをクロスセル・アップセルを創出するような部門にしたいという希望があるようです。 新たな顧客体験の創造 Google では、顧客体験を創造するにあたって次のようなビジョンがあると紹介されました。 プロアクティブにお客様一人ひとりに寄り添い 自然な顧客体験をお届けする そして、このビジョンを達成するための 3 つの柱が紹介されました。 高度な個別最適化(ハイパーパーソナライゼーション) 能動的な働きかけ(プロアクティブ) 人間らしい対話(ヒューマンライク) Google では上記のような顧客体験を達成するために AI を用いたプロダクトを開発しています。Customer Engagement Suite はそのようなプロダクトを束ね、エンドツーエンドでカスタマーサービス業務を形成するものとなっています。 Customer Engagement Suite は世界中で導入されており、以下のようなビジネスインパクトを与えていると説明されました。 メルカリ社の事例紹介 概要 後半パートでは、メルカリ社の宮坂氏より、メルカリ社での Customer Engagement Suite の導入事例について、具体的には採用理由や導入時の障壁、デモなどが紹介されました。 採用理由 まずメルカリ社のありたい姿と、これまでの課題について紹介されました。「困りごと」は、顧客にとっては快適なサービス利用を阻害するものでしかなく、短時間で解決することが重要である一方、従来のサポート体制では問題解決までに 50 時間程度かかることもあったそうです。 そこで次のような理由からメルカリ社では Customer Engagement Suite 採用を決めたとのことです。 24 時間、多言語での問い合わせ対応が可能 人によるサポートとなった場合、AI が事前に状況を整理し、案内作成に必要なナレッジを自動提示してくれる メルカリ社では Google Cloud をベースとしたマイクロサービスのシステムを構築しており、他の Google Cloud プロダクトとの連携がシームレス 導入時の障壁 Customer Engagement Suite 導入時は、日々アップデートされていくことによるナレッジの少なさに苦戦したとのことです。Customer Engagement Suite を知るために、また、Google Cloud の製品開発チームにメルカリ社を知ってもらうために、両者は日々コミュニケーションを行ったそうです。 デモ 最後に、実際に開発した顧客サポートシステムのデモが動画で紹介されました。以下、動画の内容を一部抜粋して紹介します。 顧客画面:担当者による対応となった際の、AI によるこれまでの要約 担当者画面:顧客の問い合わせ履歴や社内ドキュメントに基づいた、AI による回答文の提案 担当者画面:対応完了後作成する必要のあるサマリーの自動生成 堂原 竜希 (記事一覧) クラウドソリューション部クラウドエクスプローラ課。2023年4月より、G-genにジョイン。 Google Cloud Partner Top Engineer 2023, 2024, 2025に選出 (2024年はRookie of the year、2025年はFellowにも選出)。休みの日はだいたいゲームをしているか、時々自転車で遠出をしています。 Follow @ryu_dohara
アバター
G-gen の奥田です。当記事は、Google Cloud Next '25 Tokyo の2日目に行われたブレイクアウトセッション「 Gemini CLI で実現する AI Agent 時代のプロダクト開発 」のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 Gemini CLI とは Gemini CLI の機能 入力モード Context Engineering MCP サポート Gemini CLI を用いたデモ デモの内容 1. 自然言語で SQL を生成して BigQuery でデータ分析 2. ウェブサイトに追加する動画を生成 3. Cloud Run にデプロイ 関連記事 セッションの概要 本セッションでは、Gemini CLI の新機能の紹介、及び Gemini CLI を用いたデモが発表されました。 当セッションの紹介にあたり、事前の理解が必須なのが、 Gemini Code Assist という Google のソリューションです。Gemini Code Assist は AI によるコーディング支援を提供するサービスであり、バックエンドでは Gemini が使用されています。 Gemini Code Assist では、VS Code や IntelliJ といった IDE 上で、コード生成・補完、リファクタリング、コード変換、テスト作成などの開発作業をAI が支援します。 参考 : Gemini Code Assist | AI coding assistant 参考 : Gemini Code Assist の概要 2025年4月に行われた Google Cloud Next では Gemini Code Assist Agents が発表されました。 Gemini Code Assist agents は、ソフトウェア開発ライフサイクル全体を支援する エージェント機能の総称 です。その中核となるのが、Gemini Code Assist の エージェントモード (Agent mode)です。 参考 : Agent mode Gemini Code Assist の Agent mode を使うと、例えば仕様書に基づいてゼロからアプリケーションを開発するといった、包括的な作業を AI に依頼できます。詳細な事例については、以下の記事をご参照ください。 blog.g-gen.co.jp Agent mode は IDE 上で動作しますが、特に VS Code で実行される Agent mode のバックエンドでは、 Gemini CLI が使用されます。 加えて、Gemini CLI ではコマンドラインターミナル上でも、自律的にマルチステップのタスクを実行することができます。 当セッションでは、この Gemini CLI の用例などが紹介されました。 Gemini CLI とは Gemini CLI とは、ターミナルから直接 Gemini の機能を利用できるオープンソースの AI エージェントです。 組み込みツールとローカルまたはリモートの MCP サーバーを組み合わせた ReAct (React) ループを使用できます。 具体的には、以下の用途で利用します。 コード生成 ファイル管理 ツールの呼び出し 他のアプリとの連携 コンテキストの理解 blog.g-gen.co.jp Gemini CLI の機能 当セッションでは、Gemini CLI の様々な機能が紹介されました。 入力モード 入力モードは2種類あります。 1.Interactive Prompt デフォルトのモードです。 対話をしながら指示を出すモードです。 2.Non-Interactive Prompt CLI 上のコマンドとして呼び出し回答を得るモードです。 ユースケースとしては、 他のツール中心で利用する場合 や、 インテグレーション で利用します。 Context Engineering コンテキストを管理することにより、Gemini CLI の精度をコントロールできます。Gemini CLI で精度を向上するには、 コンテキストをピンポイントに提供する必要がある ことが強調されました。 ピンポイントな情報を提供することでノイズを減らし、より的確なアドバイスを提供できるためです。 以下2つの方法でコンテキストを提供できます。 1. Context file / Memory(GEMINI.md) コンテキストファイル( GEMINI.md )にプロジェクトの概要やツールの内容、コーディング規約、命名規則などを自然言語で記述することで、あらかじめ コンテキストを定義 できます。 また @<file_path> コマンドで複数のファイルをインポートできます。 参考 : gemini.md 2. Conversations Conversations はセッションごとに管理され、揮発性のあるコンテキストです。必要に応じて GEMINI.md ファイルに転記する等して永続化できます。 参考 : CLI Commands MCP サポート Gemini CLI は様々な Model-Centric Prompting(以下、MCP)ツールと連携できます。 MCP は、AI モデル・エージェントと外部のツールやデータソースとのやり取り(呼び出し・入出力)を標準化する、オープンなプロトコル仕様です。 settings.json ファイルで MCP や認証方法などの設定を指定できます。 参考 : modelcontextprotocol Gemini CLI を用いたデモ デモの内容 架空の通販サイトで、 Gemini CLI を用いた以下の流れが発表されました。 自然言語で SQL を生成して BigQuery でデータ分析 ウェブサイトに追加する動画を生成 Cloud Run にデプロイ アーキテクチャは以下のとおりです。 1. 自然言語で SQL を生成して BigQuery でデータ分析 /mcp コマンドで Gemini CLI が認識している MCP サーバーが一覧表示されます。 ここで認識される MCP サーバーは、あらかじめ settings.json ファイルで定義したものです。 Gemini CLI から BigQuery MCP サーバーを呼び出し、特定のプロジェクトのデータセット一覧とデータセットのテーブル一覧をリストで表示させます。 その後、自然言語で以下のように問い合わせ、評価の高い商品を特定します。 テーブルのプロダクトの中から最も評価の高い商品を探して、プロダクトのタイトル、評価値、評価数を教えて この問い合わせにより Gemini CLI が SQL を生成し、BigQuery MCP サーバーを呼び出してタスクを完了します。 2. ウェブサイトに追加する動画を生成 あらかじめ Gemini CLI で生成したプロンプトを元にウェブサイト用の動画を生成します。 はじめに、動画作成用の画像を4枚生成します。 その後、生成した画像から4つの動画を生成し、1つの動画に統合することで、ウェブサイト用の動画が数分で完成しました。 3. Cloud Run にデプロイ Gemini CLI で自然言語で指示をし、既存のウェブサイトに動画を表示させるように指示します。 Gemini CLI に入力したプロンプトは以下のとおりです。 生成した動画を、トップページの画像と入れ替えるように挿入してください。投入した動画の横幅が常にブラウザ画面の横幅 100% になるようにして、縦横比は元のまま維持されるように HTML と CSS を修正してください。なお、動画はループするように設定し、動画以外のコンテンツはレイアウトを変更しないようにしてください その後、既存の Cloud Run のリビジョンとしてデプロイするように指示します。 Artifact Registry のパスも指定し、他の設定は変更しないように指示します。 その結果、生成した動画が表示されたウェブサイトが Cloud Run にデプロイされました。 関連記事 blog.g-gen.co.jp Risa (記事一覧) クラウドソリューション部クラウドデベロッパー課 Google Cloudの可能性に惹かれ、2024年4月G-genにジョイン。 Google Cloud Partner Top Engineer 2025 Google Cloud 11 資格保有。日々修行中です! Follow @risa_hochiminh
アバター
G-gen の杉村です。当記事では、Google Cloud Next Tokyo '25 の、2日目のキーノートに関する速報レポートをお届けします。 Google Cloud Next Tokyo '25 イベント概要 キーノートの概要 AI 時代の変革 GKE と Cloud Run における GPU 新たな野球体験 まったく新しいデジタルバンクの設立 Gemini CLI データと AI セブン&アイ・ホールディングス セキュリティと AI Google Cloud Next Tokyo 26 関連記事 Google Cloud Next Tokyo '25 イベント概要 Google Cloud の旗艦イベントである Google Cloud Next の東京版である Google Cloud Next Tokyo '25 は、2025年8月5日(火)と6日(水)の2日間で開催されます。本年は、東京ビッグサイトで開催されました。 2日目のキーノート会場の様子 2日目のキーノート(基調講演)では例年、開発者向けの技術的な内容にフォーカスした発表が行われます。本投稿では、Google Cloud Next Tokyo '25 の第2日目のキーノートの概要をお伝えします。 G-gen Tech Blog では、Google Cloud Next Tokyo '25 に関連する記事を随時発信しています。 blog.g-gen.co.jp なお、初日のキーノートのレポートは以下の記事を参照してください。 blog.g-gen.co.jp キーノートの概要 Google Cloud Next の2日目のキーノートでは、開発者やデータエンジニア、データサイエンティスト向けの様々な Google Cloud ソリューションが紹介されました。 1日目と同じく、AI にフォーカスし、Google Cloud の AI 系プロダクトが、開発者体験やデータエンジニアリング、データ分析などを効率化することができることが示されました。またセキュリティの領域についても、AI との関連性が「AI で守る」「AI を守る」の2つの視点で語られました。 また株式会社 NPB エンタープライズ、ソニー株式会社、株式会社三菱 UFJ フィナンシャル・グループ、株式会社セブン&アイ・ホールディングスが登壇し、Google Cloud を使った事例が紹介されました。 技術的な新発表としては、 Gemini CLI GitHub Actions が発表されました(Preview)。Gemini CLI GitHub Actions では、Issue の振り分け、自動的な PR レビュー、Issue や PR 内で Gemini CLI にメンションして作業を指示するなど、Gemini CLI と GitHub が高度に統合され、開発ワークフローを自動化することができます。 参考 : AI コーディングの新たなパートナー:Gemini CLI GitHub Actions を発表 AI 時代の変革 Google Cloud カスタマーエンジニアリング 技術本部長 渕野 大輔氏 Google Cloud カスタマーエンジニアリング 技術本部長 渕野 大輔氏が登壇し、当講演では「AI 時代の変革」をテーマに、以下を紹介することが述べられました。 AI インフラ アプリのモダナイズ データとセキュリティ Google Cloud は AI に最適化されたプラットフォームであり、インフラからアプリ開発まで、エンドツーエンドの一気通貫した AI ジャーニーを提供できることが「 明確な差別化ポイントである 」と述べられました。 AI 時代の変革 これを裏付けるように、2025年4月にラスベガスで開催された Google Cloud Next '25 でも発表された、新型 TPU である Ironwood や、GB200 GPU を搭載した Compute Engine マシンタイプの提供など、Google Cloud の AI 向けインフラサービスが紹介されました。 GKE と Cloud Run における GPU Google Cloud VP & GM ブラッド カルダー氏 続けて、Google Cloud の VP & GM であるブラッド カルダー氏が登壇し、GKE と Cloud Run における GPU 提供機能などについて言及しました。 AI ワークロードにおける GKE の強み Cloud Run with GPU 新たな野球体験 株式会社 NPB エンタープライズ 執行役員デジタル事業部長 丹羽大介氏 株式会社 NPB エンタープライズの執行役員デジタル事業部長、丹羽大介氏が登壇し、日本プロ野球の観戦に AI を使った新たな体験を導入しようとしていることが発表されました。 同社は2024に全12球団の球場に、HAWK-EYE と呼ばれるトラッキングカメラを導入し、その映像をもとに AI によって動画像を描画。新たな野球観戦体験を提供することを紹介しました。 AI で描画された打球軌跡 続けてこの取り組みを支援したソニー株式会社の執行役員、平位文淳氏が登壇し、技術的な背景を紹介しました。 ソニー株式会社 執行役員 平位文淳氏 このシステムは Google Cloud 上に構築されています。また開発に当たっては、Google による TAP(Tech Acceleration Program)による支援があったと述べ、強力なパートナーシップがあったことを紹介しました。 将来的には API 経由で詳細データや自動生成コンテンツへのアクセスを、放送事業者や消費者へ提供することも視野に入れています。 アーキテクチャ コンテンツ提供 まったく新しいデジタルバンクの設立 株式会社三菱 UFJ フィナンシャル・グループ 執行役常務 山本忠司氏 株式会社三菱 UFJ フィナンシャル・グループの執行役常務 リテール・デジタル事業本部長 兼 グループ CDTO の山本忠司氏が登壇し、新サービスブランドであるエムットの事例を紹介しました。 エムットは「お金のあれこれ、まるっと」をテーマにした同行の新サービスです。 エムット 金融を取り巻く変化と多様化 同氏は、同サービスの開発にあたり、同行の店舗網とプロのアドバイスという、デジタルとリアルの「いいとこ取り」を図るべく、「まったく新しいデジタルバンクの設立」を意図したと述べます。同サービスでは、勘定系システムのフルクラウド開発を Google Cloud で行っています。 参考 : Google Cloud 、三菱 UFJ 銀行が新設するデジタルバンクの勘定系システム基盤に採用 同氏は Google Cloud が採用された理由として、信頼性(堅牢なセキュリティ)、スケーラビリティと柔軟性、高可用性とデータの一貫性などを挙げました。またデータベースとして、リージョンレベルの障害があってもサービスが止まらないことと、データの不整合が発生しないことの2点を重視したポイントとして挙げ、これを満たす Spanner を採用したことを明らかにしました。 加えてコンテナ技術の成熟や、AI と機械学習の高度なエコシステムも採用にあたってプラス要素になったと述べます。 Gemini CLI 続けて、Gemini CLI についても改めて紹介されました。 Gemini CLI はコード生成やコーディング補助だけでなく、様々な用途に使うことができます。そういった用例の1つとして、Kubernetes のトラブルシューティングが挙げられました。 Gemini CLI の用例 Gemini CLI は yaml 定義ファイルから環境情報を理解し、クラスタに接続。ログを取得して状況を把握すると、関連ソースコードを特定して修正案を提示します。Gemini CLI が単なるコーディング補助ツールではなく、クラウド環境の運用にも用いることができることが示されました。 また、Gemini CLI が MCP サーバー経由で GitHub から issue を取得して修正したり、「過去1週間の Cloud Logging のログ情報をもとに Cloud Run の最適化をして」といった指示に基づいて、Cloud Run の最大・最小インスタンス数やリソース割り当ての提案などを行う様子もデモされました。 Gemini CLI の画面 さらに、新機能である Gemini CLI GitHub Actions が発表されました。Gemini CLI GitHub Actions では、Issue の振り分け、自動的な PR レビュー、Issue や PR 内で Gemini CLI にメンションして作業を指示するなど、Gemini CLI と GitHub が高度に統合され、開発ワークフローを自動化することができます。 参考 : AI コーディングの新たなパートナー:Gemini CLI GitHub Actions を発表 Gemini CLI GitHub Actions の発表 データと AI Google Cloud GM & VP アンディ ガットマンズ氏 Google Cloud の GM & VP であるアンディ ガットマンズ氏が登壇し、Google Cloud におけるデータと AI について紹介しました。 Google Cloud におけるデータと AI MCP Toolbox 経由で AI エージェントが BigQuery、AlloyDB、Cloud SQL、Spanner などの各データベースサービスに接続できることや、Spanner や AlloyDB に搭載された高度な検索機能などが示されました。 BigQuery のデータエンジニアリングエージェントやデータサイエンスエージェントについてもデモが行われました。Colab Enterprise や BigQuery Studio のノートブック上で、自然言語による指示に基づき、AI が Python ソースコードを生成し、高度な分析を行うことができます。 データサイエンスエージェント また Looker や Looker Studio に搭載された会話型分析(Conversational Analytics)エージェントと、高度な分析を実現する Code Interpreter についても紹介されました。対話型分析 API を経由することで、自社アプリケーションにこういった機能を組み込むこともできます。 Conversational Analytics セブン&アイ・ホールディングス 株式会社セブン&アイ・ホールディングス 常務執行役員 グループ DX 本部長 西村出氏 株式会社セブン&アイ・ホールディングスの常務執行役員 グループ DX 本部長である西村出氏が登壇し、全国 21,756 店舗の POS レジ情報を統合する基盤であるセブンセントラルについて紹介しました。 セブンセントラル 次世代店舗システム セブンセントラルはデータベースとして BigQuery や Spanner、AlloyDB を採用としており、1日52億件のレコードを処理し、また店舗で発生した最新データへのアクセスを1分以内に実現します。 また次世代店舗システムでは、ストアコンピューター(1店1台)をなくし、全面クラウド化を行うという野心的な計画も示されました。その実現のため、「ハードとソフトの分離」「疎結合システムで改修スピードアップ」「クラウド上のデータを有効活用」という方針が示されました。 次世代店舗システムの方針 Google Cloud 採用の理由として、「圧倒的な信頼性」「高い柔軟性」が挙げれらました。 セキュリティと AI Google は次に、AI とセキュリティの関連性を「AI で守る」「AI を守る」の2つの視点で紹介しました。 攻撃者による AI の悪用は進んでおり、自然な日本語によるフィッシングサイトなども多く観測されています。 攻撃者による AI 悪用 これに対して、Google Cloud は「AI で守る」という視点で、セキュリティ向上に AI を利用します。Google の SIEM/SOAR 製品である Google SecOps には Gemini が組み込まれており、検出事項を AI がトリアージしたり、詳細な分析や次のステップの提案を行います。 Google Cloud のセキュリティ関連スイート Google SecOps と AI 将来的な開発計画として、AI エージェント同士が連携してセキュリティ関連タスクをこなすことを視野に入れていることが述べられました。 AI エージェント同士の連携 次に、「AI を守る」という視点では、Google Cloud の AI Protection が紹介されました。AI Protection は Security Command Center と Model Armor に統合されており、Google Cloud 環境内で「AI アセットの発見」「AI アセット保護」「AI への脅威対応」などを行い、それらの統合ダッシュボードも提供します。 AI Protection グラフィカルに AI アセットを表示して対処を提案する Gemini 以外のモデルにも対応 Google Cloud Next Tokyo 26 最後に、次回の Google Cloud Next Tokyo '26 の予告が行われました。 Google Cloud Next Tokyo '26 の日程は2026年7月30日(木)〜31日(金)で、会場は2025年と同じ、東京ビッグサイトの南展示棟です。 関連記事 Google Cloud Next Tokyo '25 の関連記事は、以下の記事一覧をご参照ください。開催期間中は、記事が随時公開されます。 blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の高宮です。当記事は、Google Cloud Next '25 Tokyo の1日目に行われた スポンサーセッション「 Google Cloud + GitLab で作る最高のソフトウェア開発環境の作り方 」 のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 GitLab合同会社の概要 なぜ開発環境は整備すべきか 迅速に開発環境を展開 人とAIによるレビューで品質の向上 セキュリティスキャンの必須化と脆弱性への対応 快適な開発環境の構築例 開発環境の構成 チームワークを健康に保てるレビュー環境 DevSecOpsのアーキテクチャ 関連記事 セッションの概要 本セッションでは、 GitLab合同会社の小松原つかさ氏から GitLab と Cloud WorkStations を使用した快適なソフトウェア開発環境が紹介されました。 GitLab合同会社の概要 GitLab合同会社は、開発ライフサイクル全体を単一のアプリケーションで提供するDevOpsプラットフォーム GitLab の日本法人です。 GitLab は2年連続で『2024 Gartner® Magic Quadrant™ for DevOps Platforms』においてリーダーの1社として評価され、さらに「実行能力」と「ビジョンの完全性」で最上位の評価を獲得しています。 また、Google Cloud パートナー アワードの「2025 テクノロジー パートナー オブ ザ イヤー - アプリケーション開発 - DevOps」を受賞しています。 参考: GitLab named a Leader in the Gartner® Magic Quadrant™ 参考: GitLabのパートナープロフィール なぜ開発環境は整備すべきか 以下の3つの観点で開発環境を整備する必要があり、これらを満たすことで、 品質とアジリティ の向上が期待できると発表されました。 迅速に開発環境を展開 ソフトウェア開発において各開発者がローカルPCに開発環境を構築して開発をすることが多いです。その際、手順書に沿って環境を構築するケースでは、開発者のスキルによっては、独力では環境構築が完結しない場合があります。 また、複数の開発を同一の端末で行っている場合、ツールのバージョンを誤ってアップ・ダウングレードする場合があります。 環境構築がうまくいかない場合や、ツールのバージョン差異が発生した場合、開発者本人だけではなく、他の開発者の時間も奪われてしまうので、 迅速に展開可能な開発環境 の整備は重要です。 人とAIによるレビューで品質の向上 ソフトウェア開発において生成AIの利用に伴い、成果物が完成する速度は飛躍的に向上しています。そうした状況の中では、レビュワーには日々大量のレビュー依頼があり、パンクしている状況で、レビューが形骸化することがあります。また、レビューの指摘内容によっては、チームワークが悪化する可能性もあります。 このような課題に対処するために、人だけでなく、 AIも活用する ことで 高速に必ずレビューを実施できる環境 を構築することが重要です。また、コードだけでなく 実際に動作する環境 でのレビューを実施できる環境の構築も品質向上のためには必要です。 セキュリティスキャンの必須化と脆弱性への対応 セキュリティスキャンとは、アプリケーションのソースコードや実行環境を自動的に分析し、潜在的な脆弱性を検出するプロセスです。脆弱性は、攻撃者にとって格好の侵入経路となり、脆弱性を放置することは、不正アクセス、データ漏洩、サービス停止などのサイバー攻撃を招く大きなリスクとなります。セキュリティインシデントが発生すると、企業のブランドイメージや顧客からの信頼は大きく損なわれる可能性があります。また、訴訟や多額の賠償金など、法的なリスクや経済的な損失を伴う可能性があります。 このようなリスクを未然に防ぐためにも、 セキュリティスキャンジョブをスキップできない環境 と、進化する 生成AIでのコーディング支援 を使用して、脆弱性に適切に対応し修正することが重要です。 快適な開発環境の構築例 開発環境の構成 本セッションでは、快適な開発環境として、 Cloud WorkStations と GitLab を使用した構成が紹介されました。 Cloud WorkStations クラウド上で動作するフルマネージドの仮想開発環境を提供するサービスです。開発者は、ローカルPCに複雑な開発環境を構築することなく、ブラウザやローカルのIDE(統合開発環境)から、セキュアで一貫性のある開発環境にアクセスできます。 参考: Cloud Workstations の概要 Cloud WorkStations を使用し、環境をイメージ化し展開することで、全開発者で迅速に同一のセキュアな環境で開発を行うことが可能です。 また Cloud WorkStations については、以下の当社記事で詳しく解説しています。 blog.g-gen.co.jp GitLabは、Gitリポジトリ管理、CI/CD、セキュリティ、プロジェクト管理など、ソフトウェア開発のライフサイクル全体をカバーする統合DevSecOpsプラットフォームです。 GitLab を使用することでソースコード管理だけでなく、ビルド、テストとセキュリティスキャンの実施、実際に動作する環境へのデプロイも行うことが可能です。また、開発における工程管理もソースコードと連動させて行うことができます。 参考: GitLab チームワークを健康に保てるレビュー環境 チームワークを健康に保てるレビューのために、 GitLab Duo のコードレビュー機能を使用します。マージリクエストで Duo をアサインし、レビューを実施します。AI がレビューすることで、以下のメリットがあります。 必ずレビューが実施される 開発者が指摘の内容を受け入れやすい また、事前に Duo にコードレビューの観点を指示することで、人がレビューする時と近いレベルでレビューが可能になります。そうすることで、人は要件が網羅されているかなど、本質的な部分の確認に注力することが可能です。 参考: GitLab Duo 参考: Have GitLab Duo review your code DevSecOpsのアーキテクチャ 下図に示すアーキテクチャで、DevSecOps を実現します。 GKE でのアーキテクチャ Cloud Run でのアーキテクチャ ソースコードのビルド時にSAST(Static Application Security Testing)、Google Cloud へのアプリデプロイ後にDAST (Dynamic Application Security Testing)を行うことで、開発の早期の段階で脆弱性を検出し、対処することが可能です。 GitLab では、公式 CI/CD テンプレートが提供されており、特別な設定をすることなくセキュリティスキャンを有効にできます。 参考: Static Application Security Testing (SAST) 参考: Dynamic Application Security Testing (DAST) このようにして検出した脆弱性に対して、 GitLab Duo などの AI を活用し修正を行うことで、形骸化を回避し、確実に脆弱性に対処する環境を構築することができます。 関連記事 blog.g-gen.co.jp 高宮 怜 (記事一覧) クラウドソリューション部クラウドエクスプローラ課 2025年6月より、G-genにジョイン。前職は四国のSIerで電力、製造業系のお客様に対して、PM/APエンジニアとして、要件定義から運用保守まで全工程を担当。現在はGoogle Cloudを学びながら、フルスタックエンジニアを目指してクラウドエンジニアとしてのスキルを習得中。
アバター
Google Cloud Next Tokyo '25 の「Next Tokyo イベントアンバサダー」に選出いただきました G-gen の堂原です。当記事は、Google Cloud Next '25 Tokyo の2日目に行われた ブレイクアウトセッション「 もう手放せない!Gemini の NotebookLM、Deep Research、Canvas で思考を加速 」 のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 思考を変革する、新しい情報活用ワークフロー 概要 Deep Research NotebookLM Canvas AbemaTV のユースケースご紹介 概要 文章作成 調査業務 社内データ活用 関連記事 セッションの概要 本セッションでは、 Google の AI ツールである Deep Research 、 NotebookLM 及び Canvas の活用方法と、株式会社 AbemaTV 社での実際の活用例について紹介されました。 思考を変革する、新しい情報活用ワークフロー 概要 前半パートでは、Google Cloud 社の服部氏より、Deep Research、NotebookLM 及び Canvas を活用した新しい情報活用ワークフローが紹介されました。 業務において情報を活用するための大きなフローである 情報の収集 集約・整理・分析 アウトプット それぞれのフェーズにおける、Deep Research、NotebookLM、Canvas の有用性が紹介されました。 Deep Research Deep Research は、以下のような情報収集における必要なフローを数分で完結させることができます。 Deep Research は与えられたプロンプトをただ文字通りに検索するのではなく、その目的を理解し、調査を複数のステップに落とし込みます。そして最大 100 種類のウェブサイトを自動的に検索し、得られたデータを統合し、整合性が取れるように適宜修正します。調査結果は最終的に引用元へのリンクを含んだレポートとして出力されます。 NotebookLM NotebookLM では、議事録等といった社内データや Deep Research が出力したレポートなどの情報の集約・整理・分析をすることができます。 NotebookLM は Google Docs や Google Slide、YouTube、PDF 等といった複数のデータ形式に対応しています。また、全ての回答には適切な引用元へのリンクが付いているため、ハルシネーションが起きにくいです。更に、音声としての出力も可能という特徴も持っています。 Canvas Canvas は与えられた情報の整理を行いアウトプットとします。文章としてのアウトプットはもちろん、HTML・CSV・JavaScript によるページを作成することも可能です。 AbemaTV のユースケースご紹介 概要 後半パートでは、AbemaTV 社の上田氏より、AbemaTV 社における Google の生成 AI ツールの具体的な活用例が紹介されました。 AbemaTV 社では、文章作成や調査業務、社内データ活用といった業務において Gemini が活用されています。 文章作成 文章作成においては、メールや議事録、企画の提案資料などといった様々な文章作成を Gemini が支援しています。Gemini は資料のたたき台を瞬時に作成し、メール作成や要約・議事録作成を大幅に効率化します。また企画創案のアイデア出しも支援してくれます。 具体例として、Gmail でのメール作成支援や Gem をプレゼンテーション作成アドバイザーとして活用しているケースが紹介されました。 Gmail でのメール作成支援 Gem による、プレゼンテーション作成アドバイザー 調査業務 調査業務においては Deep Research が活用されています。市場調査や競合分析を Gemini が代行し、膨大な情報からレポートの作成を行ってくれます。 社内データ活用 社内データ活用においては NotebookLM が用いられています。 具体例として、社員の自己紹介スライドをデータソースとしたオンボーディング用 NotebookLM や、文章化されたデザインポリシーに関する FAQ システムとして NotebookLM を活用するケースが紹介されました。 オンボーディング NotebookLM デザインポリシー NotebookLM 関連記事 blog.g-gen.co.jp 堂原 竜希 (記事一覧) クラウドソリューション部クラウドエクスプローラ課。2023年4月より、G-genにジョイン。 Google Cloud Partner Top Engineer 2023, 2024, 2025に選出 (2024年はRookie of the year、2025年はFellowにも選出)。休みの日はだいたいゲームをしているか、時々自転車で遠出をしています。 Follow @ryu_dohara
アバター
G-gen の奥田です。当記事は、Google Cloud Next '25 Tokyo の1日目に行われたブレイクアウトセッション「 生成AI活用を進めるゴルフダイジェスト・オンライン(GDO)が Google Cloud で実現したい未来 」のレポートです。 他の Google Cloud Next Tokyo '25 の関連記事は Google Cloud Next Tokyo '25 カテゴリ の記事一覧からご覧いただけます。 セッションの概要 GDO 社の概要 データ活用による課題 1.データカオスの発生 2. データの民主化 3. 生成 AI の活用 Looker での解決 セマンティックレイヤー Explore Assistant Dashboard Summarization GDO 社による生成 AI 活用の取り組み 『GDO 店員さん AI』 カスタマーパーソナライズDB 関連記事 セッションの概要 本セッションでは、ゴルフダイジェスト・オンライン社(以下、GDO社)のデータに関する課題と、その解決策としての Looker が紹介されました。 GDO 社の概要 GDO 社は「ゴルフで世界をつなぐ」をミッションにゴルフに関する以下のサービスを展開しています。 ゴルフメディア ゴルフ用品販売 ゴルフレッスン ゴルフ場予約 ゴルフ練習場事業 スコア管理 また、2024年には生成 AI を活用した PoC(概念実証)を開始しました。 データ活用による課題 GDO 社は、データ活用において以下3点の課題があると発表しました。 1.データカオスの発生 データ抽出には SQL の知識が必須であったため担当者が限定され、ビジネスユーザーへのデータ提供が滞るボトルネックが生じていました。この状況を解消するため各部署が個別の BI ツールや基幹システムを導入した結果、かえってツールが乱立してしまい、部署をまたいでデータを分析する際には都度データ定義のすり合わせが必要になる、といった課題がありました。 2. データの民主化 SQL の知識が必要なデータ抽出が、社内でのデータ活用の属人化を招いていました。この課題に対し、自然言語で誰もがデータにアクセスできる「データの民主化」を推進する必要がありました。その解決策として Gemini in Looker の機能である 会話型分析(Conversational Analytics) の導入により、自然言語でのデータ集計・検索・可視化を目指すとしています。 参考 : Conversational Analytics in Looker 3. 生成 AI の活用 GDO 社では生成 AI を組み込んだサービスを2024年からラボ型開発組織で実装し、エンドユーザーに向けてテストを始めており、以下の取り組みが紹介されました。 対話型予約 AI ゴルフ場予約サービスに導入し、主にゴルフ初心者のユーザーに向けてゴルフ場を選ぶためのアドバイスをするチャットボットを使用しました。 チャットボットは商品マスタと口コミを学習しており、パーソナルな提案を実現しました。 Looker での解決 セッションの後半では、Google Cloud よりこれらの課題に対する Looker を用いた解決策が紹介されました。 セマンティックレイヤー セマンティックレイヤー を用いることで、部署毎に異なっていたデータの定義を統一できることが紹介されました。セマンティックレイヤーは、元となるデータをビジネスユーザーやAIが理解できる言葉に変換する層のことで、Looker では LookML という言語を用いて構築します。 参考 : Looker のモデリング 参考 : GoogleのBIツール、LookerとLooker Studioを比較してみた - G-gen Tech Blog このセマンティックレイヤーによって信頼性が担保されたデータ基盤が、ビジネス成果に繋がります。 Looker 上のデータを元にターゲットの選定やマーケティング施策の立案ができますが、そのためには信頼できるデータ基盤が不可欠です。本セッションでは、信頼できるAI 基盤の構築には、まず信頼できるデータ基盤が必要であることが強調されました。 生成 AI が情報を分析する上でもセマンティックレイヤーは重要です。セマンティックレイヤーで定義を明確にすることで、生成 AI からのレスポンスのエラーを 最大で3分の2削減できる と発表しました。 Explore Assistant データの活用が進むほど、社内特有の用語や要望に答える必要があります。 そのための解決策としてオープンソースの Explore Assistant が紹介されました。 Explore Assistant については、以下の記事で詳しく解説しています。 blog.g-gen.co.jp Dashboard Summarization また、ダッシュボードの要約が必要な際に活用できる、オープンソースの Dashboard Summarization も紹介されました。 Dashboard Summarization については、以下の記事で詳しく解説しています。 blog.g-gen.co.jp GDO 社による生成 AI 活用の取り組み 『GDO 店員さん AI』 前述の対話型予約 AI の様な、 顧客がゴルフを楽しむための全ての体験をサポートする AI を導入することを目指します。 カスタマーパーソナライズDB 顧客の属性 や ゴルフのプレー履歴 といった情報だけでなく、 ライフスタイル や 閲覧メディア などの個人情報も一括管理するデータベースを構築し、広告の強化や購買促進に繋げることを目指します。 GDO 社は、製品情報や顧客情報管理をさらに強化するため、 今後も Looker を活用していきたい と述べました。 関連記事 blog.g-gen.co.jp Risa (記事一覧) クラウドソリューション部クラウドデベロッパー課 Google Cloudの可能性に惹かれ、2024年4月G-genにジョイン。 Google Cloud Partner Top Engineer 2025 Google Cloud 11 資格保有。日々修行中です! Follow @risa_hochiminh
アバター
G-gen の杉村です。当記事では、Google Cloud Next Tokyo '25 の、1日目のキーノートに関する速報レポートをお届けします。 Google Cloud Next Tokyo '25 イベント概要 キーノートの概要 AI エージェント メディア生成 AI Agent Development Kit(ADK) Google Agentspace 株式会社 MIXI の事例 株式会社メルカリの事例 クリエイティブエージェント AI 関連の補償 Google Workspace with Gemini 株式会社博報堂の事例 札幌市の事例 関連記事 Google Cloud Next Tokyo '25 イベント概要 Google Cloud の旗艦イベントである Google Cloud Next の東京版である Google Cloud Next Tokyo '25 は、2025年8月5日(火)と6日(水)の2日間で開催されます。本年は、東京ビッグサイトで開催されました。 東京ビッグサイト ゆりかもめ「東京ビッグサイト」駅構内 Expo エリア(開場前) 初日のキーノート(基調講演)では、Google が最も強調したい内容が発表されます。本投稿では、Google Cloud Next Tokyo '25 の第1日目のキーノート(基調講演)で行われた発表の概要をお伝えします。 G-gen Tech Blog では、Google Cloud Next Tokyo '25 に関連する記事を随時発信します。 blog.g-gen.co.jp キーノートの概要 Google Cloud Next の開幕を飾る初日のキーノート(基調講演)では、Google Cloud の AI や AI エージェントに関連する顧客事例が紹介されました。 今回のキーノートでは、技術的な新発表はほとんどなく、事例紹介が中心でした。ただし、以下は今回の講演で初めて発表された情報であると思われます。 Gemini 2.5 Flash に東京リージョンエンドポイントが登場予定 Google Agentspace が日本リージョンに対応予定 Generative AI Leader 試験が日本語に対応 当講演では、Vertex AI、Vertex AI Search、Gemini、Veo などの AI モデル、Google Agentspace などの既存の AI 系プロダクトの紹介が改めて行われ、またそれらを活用した事例が、MIXI、メルカリ、博報堂、そして札幌市の登壇者により発表されました。 キーノート会場 AI エージェント 最初に登場したのは、Google Cloud Japan の代表、平手智行氏です。 2025年が「AI エージェント元年」と呼ばれていることに言及し、AI エージェントが分断された情報を繋いだり、エンドツーエンドの業務自動化、またスキル・人材不足を解消するためのキーとなることを強調しました。 Google Cloud において、Vertex AI が、AI 開発のインフラからアプリケーションまでを一気通貫でサポートするプラットフォームであることを改めて強調し、また Google Distrbuted Cloud が、セキュリティ・統制やレイテンシの非常に厳しい要件にも対応できることを紹介しました。 Google Cloud Japan 代表 平手智行氏 メディア生成 AI Google の Cloud AI 担当 VP & GM のサウラブ ティワリ氏が登壇し、Imagen(画像)、Veo(動画)、Chirp(音声)、Lyria(音楽)など、メディア系の生成 AI モデルについて紹介しました。 参考 : Google Cloud Next '25 速報レポート - キーノート(1日目) - G-gen Tech Blog - マルチモーダルな AI モデル Google Cloud AI 担当 VP & GM サウラブ ティワリ氏 Veo 3 と Veo 3 Fast は2025年7月に GA された Agent Development Kit(ADK) Agent Development Kit (ADK)は、Google が開発した AI エージェント開発用のフレームワークです。2025年8月現在では、Python 用と Java 用が公開されています。 デジタル庁、日本テレビおよびメルカリが、ADK を使って AI エージェント実装を行っていることが紹介されました。 当社 G-gen でも、Google Cloud Next Tokyo '25 の初日と同日に、AI エージェントを使った独自サービスを公開しています。 参考 : 株式会社G-gen、新サービス G-gen Tech Suite を提供開始 参考 : ナレッジ検索・回答AIエージェントG-gen Tech AgentをADKで開発した事例 Agent Development Kit(ADK)や Agent Engine デジタル庁による ADK の利用 日本テレビとメルカリによる ADK の利用 Google Agentspace Google Agentspace は、Google が提供する AI エージェントプラットフォームです。複数データソースへの横断検索と、AI によるタスク実行が可能です。 Google の鈴木かの子氏および蓮池拓哉氏が、架空のエレベーター管理会社を題材に、Google Agentspace が自律的に呼び出すエージェントを判断して呼び出し、エレベーターの保守のためのワークフローを実行していく様子をデモしました。 Agentspace のデモ ユーザーが Google Agentspace に自然言語で指示すると、複数エージェントが呼び出され、故障予知、優先順位付け、整備担当者をマッチング、ServiceNow にタスクをアサイン、Chatで自動通知などが行われました。1つの指示で、複数のタスクが実行されました。 Google Agentspace は2025年7月31日に一般公開(GA)され、このキーノートでは、日本リージョンへの対応が発表されました。従来の Global リージョンの利用でも使用感としては問題ありませんでしたが、日本リージョンを選択することで、データの所在に関する規制要件などにも対応することができます。 参考 : Google Agentspaceを徹底解説! - G-gen Tech Blog AI エージェントのメリット 株式会社 MIXI の事例 株式会社 MIXI 代表取締役社長の木村弘毅氏が登壇し、同社における Google Agentspace の事例を紹介しました。 株式会社 MIXI 代表取締役社長 木村弘毅氏 管理業務の自動化によりクリエイティブな業務に時間を使える 単にお金を稼ぐための「ライスワーク」から「ライフワーク」へ 同社は日本で初めて Google Agentspace を導入し、業務利用しています。AI エージェントの活用が進み、セキュリティやコンプライアンスへの対応も課題となった中で、Google Agentspace のカバー範囲が目的に合致したといいます。 AI エージェント統合の基盤として Agentspace を採用 同氏は、コラボ企画案を生成する様子をデモしました。過去のコラボ案件に関する情報を集約し、マーケ効果を可視化、それに基づいて新しいアイデアの提案が行われ、イメージ画像も生成されました。 Agentspace による画像生成 株式会社メルカリの事例 続いて株式会社メルカリの執行役員 CTO、木村 俊也氏が登壇しました。 株式会社メルカリ 執行役員 CTO 木村 俊也氏 同社はカスタマーエージェントとして Customer Engagement Suite with Google AI を利用した事例を紹介しました。カスタマーサポート領域に AI を適用することで、顧客による問題の自己解決を24時間サポートできるようになりました。 また、従来はコストのかかった、日本語以外の多言語対応も、AI により容易になりました。 Customer Engagement Suite with Google AI による顧客対応 AI が解決できなかった問題は人間にエスカレーションされる クリエイティブエージェント Google のカスタマーソリューションズエンジニアである大場勇太氏は、Google が開発したという Scenario Builder を紹介しました。 Scenario Builder これは、Gemini、Veo、Imagen などを組み合わせたソリューションです。新しい広告施策の検討ワークフローを AI によって自動化し、企画案や動画広告の絵コンテ、動画のプロトタイプまでを生成する様子がデモで紹介されました。 このような仕組みにより生成された動画を本格的な撮影のためのたたき台にできるほか、動画の出来によってはそのまま利用することもできます。 複数案をスプレッドシート上で確認 AI 関連の補償 Google の AI に関する補償として「トレーニングデータ補償」「生成出力補償」が紹介されました。 AI 関連補償 これは、著作権に関連する法的リスクについて Google が責任を負うことを示した以下の発表について示したものです。 参考 : 運命の共有: 生成 AI についての補償によるお客様の保護 Google Workspace with Gemini Google Workspace には Gemini が組み込まれており、追加のコストなしで Gemini の強力な AI 機能が利用できます。 また Web 会議ツール Google Meet では AI によるリアルタイム翻訳が実装されており、日本語は未対応ですが、同時通訳のように異なる言語間で翻訳が行われます。 Google Cloud Japan の佐瀬郁恵氏と佐藤芳樹氏が登壇し、様々なユースケースを紹介しました。 Deep Research NotebookLM スプレッドシートの AI 関数 Google Workspace Flows ではメール受信をトリガにタスクを自動化できる Deep Research によるレポート作成、スプレッドシートの AI 関数、また今後より広く公開が予定されている Google Workspace Flows によるワークフローの自動化などが、業務を効率化させます。 なお以下の当社記事では、Google Workspace に組み込みの生成 AI 機能のユースケースについて紹介しています。 参考 : 生成AI「Gemini」をクラウドインテグレーター社員が活用した事例 - G-gen Tech Blog 株式会社博報堂の事例 株式会社博報堂の代表取締役社長、名倉健司氏は、同社における AI 活用事例を紹介しました。 株式会社博報堂 代表取締役社長 名倉健司氏 同氏は、AI は正解を出すために使うものという「従来の AI 観」を脱却し、AI は「別解を生み出すパートナー」であるという新しい AI 観への転換が必要だと説きます。 従来の AI 観には問題があった 新しい AI 観では「別解を生み出すパートナー」とみなす AI 逆メンター制度 同社は Gemini と NotebookLM を全社導入しました。また、マルチクラウドの活用を推進しています。同社では役員が率先して AI を活用し、その知見を動画などで社内発信することで社員への浸透を図っています。社内で AI 活用のナレッジが自律分散的に生まれ、そのナレッジが社内に共有される仕組みを実現しています。 役員が率先して知見を配信 AI 利用率が向上 社内知見の蓄積と共有 NotebookLM の活用 社内に AI エバンジェリストを養成し、有効なプロンプトを社内で共有する。また、役員がそれらを積極的に推進する。このような施策により、同社では AI 活用が推進されています。 札幌市の事例 札幌市のデジタル戦略推進局 情報システム部長の小澤秀弘氏が登壇し、札幌市役所が実現した全庁への Google Workspace 導入の事例を紹介しました。自治体への Google Workspace 導入は近年増加しており、札幌市の導入事例は特に象徴的だったと言えます。 札幌市 デジタル戦略推進局 情報システム部長 小澤秀弘氏 札幌市役所は、ライセンスコストの増大(グループウェア)や情報共有の欠如、資料管理の破綻(メールの往復、バージョン違いファイルの存在)などを課題として抱えていました。その中で、職員の働き方を変えることを目的に Google Workspace を導入し、16,000人のユーザーへの展開を成功させました。既存ツールとの併用を辞めて、原則的に Google Workspace へ完全移行することをゴールとしています。 従来のグループウェアは組織ベース Google Workspace はプロジェクトベース 同氏は、Google Workspace の導入により「組織の壁が溶けた」と表現します。部門ベースだった情報共有とチーム形成は、仕事(プロジェクト)ベースになりました。また Google ドキュメントや Google Meet により「会議が変わった」としています。会議の動画や議事メモは NotebookLM に読み込ませ、議論のパターンやアイデアの発見に活かしています。これにより、会議の回数と1回あたりの時間が短縮されたといいます。 会議が変わった 札幌市役所が内側から変わり始める 関連記事 Google Cloud Next Tokyo '25 の関連記事は、以下の記事一覧をご参照ください。開催期間中は、記事が随時公開されます。 blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-genの杉村です。 Agent Development Kit (ADK)を使い、社内外のドキュメントやナレッジを検索して、技術的な質問に回答する AI エージェントを開発した事例を紹介します。 はじめに 開発したもの 利用可能ユーザー 動作 ユースケース 技術的な仕様に関する質問 トラブルシューティング 学習リソースの提案 アーキテクチャ マルチエージェント なぜ AI エージェントなのか インフラ構成 Vertex AI Search バッチ処理 ADK 関連記事 はじめに 開発したもの 当記事では、G-gen のサービスとして提供されている G-gen Tech Agent の開発事例を紹介します。G-gen Tech Agent は、Google Cloud や Google Workspace に関する技術的な質問に回答するチャットツールです。バックエンドでは AI エージェントが稼働しており、以下のような情報ソースから情報を取得して、その結果を要約して回答を生成します。 Google Cloud 公式ガイド( https://cloud.google.com/ ) Google Workspace 管理者ヘルプ( https://support.google.com/ ) G-gen Tech Blog( https://blog.g-gen.co.jp/ ) G-gen の技術サポート窓口 G-gen Tech Agent の画面 ユーザーが自然言語による質問を行うと、AI エージェントはこれらのソースに対して、Google Cloud の Vertex AI Search (AI Applications サービスの1機能)という仕組みを使って検索を行います。 参考 : Vertex AI Searchを徹底解説! - G-gen Tech Blog Vertex AI Search の検索結果を、生成 AI モデル Gemini が解釈・要約を行い、ユーザーに対する回答を生成します。 参考 : 全Geminiプロダクトを徹底解説! - G-gen Tech Blog 公式ドキュメントに加え、G-gen の技術ブログや過去のサポートナレッジに基づいて生成が行われるため、高い精度が期待できます。 G-gen Tech Agent では、上記の「Vertex AI Search による複数データソースへの検索」「その結果を要約して最終回答を作成する」という一連の流れを、 Agent Development Kit (ADK)というフレームワークを使って実装しました。 利用可能ユーザー G-gen Tech Agent は、G-gen の Google Cloud / Google Workspace 請求代行サービスの付帯サービスとして顧客に提供されています。「Google Cloud と Google Workspace の両方で請求代行サービスを契約している」などの提供条件があります。 G-gen Tech Agent は、G-gen 独自の AI ソリューションである G-gen Tech Suite の一部として提供されています。G-gen Tech Suite には G-gen Tech Agent の他に、Google Cloud と Google Workspace の最新技術アップデート情報に関する解説を日本語で閲覧できる G-gen Tech Update という Web サービスも付帯しています。 利用条件など、詳細は営業担当者にお問い合わせください。 参考 : 株式会社G-gen、新サービス G-gen Tech Suite を提供開始 参考 : Google Cloud 請求代行 - 株式会社G-gen 参考 : Google Workspace 請求代行 - 株式会社G-gen 請求代行サービスに無料付帯する G-gen Tech Suite 動作 G-gen Tech Agent は、以下のように動作します。 URL にアクセスすると、Google アカウントでの認証画面が表示されます。認証が完了されると、以下のような画面が表示されます。 G-gen Tech Agent の画面 質問を画面下部のテキストボックスに入力し、送信します。マークダウン形式での入力に対応しており、AI に正しく質問内容を伝えるのに役立ちます。 バックエンドでは複数のデータソースに検索を行い、またそれらを要約するため、回答には30秒ほどかかる場合があります。 エージェントが思考中 回答が生成されました。AI エージェントには、前の会話を引き継いで続けて質問することもできます。また、公式ドキュメントや関連ブログ記事リンクなども表示されます。 生成された回答 関連リンクも表示される ユースケース 技術的な仕様に関する質問 「Google ドライブで共有ドライブ間でファイルを移動すると、共有リンクは変わってしまいますか?」 トラブルシューティング 「Vertex AI で Gemini API を呼び出していますが、 429 RESOURCE_EXHAUSTED というエラーが頻発します。どうしたらいいですか?」 学習リソースの提案 「BigQuery を学ぶのに役立つコンテンツを教えてください。」 アーキテクチャ マルチエージェント G-gen Tech Agent は、 マルチエージェント構成 となっています。マルチエージェント構成では、複数の AI エージェントが協働してタスクを遂行します。以下は、エージェント構成を示したものです。 G-gen Tech Agent のマルチエージェント構成 ユーザーが質問を行うとまず、ルートエージェント(root = 根)と呼ばれるエージェントが起動します。このエージェントは SequentialAgent と呼ばれる ADK の Class を用いて構成されています。 SequentialAgent は、複数のエージェントをシーケンシャルに(直列に)実行するものです。このエージェント自体は思考を行わず、単に複数エージェントを直列に実行するワークフローを構成するために存在します。 参考 : ADKのSequential agentsを使って実装するマルチエージェント SequentialAgent の指示に基づき、はじめにデータソース検索エージェントが起動します。このエージェントは ParallelAgent で実装されています。 ParallelAgent も、SequentialAgent と同様に、思考を行わず、複数のエージェントをパラレルに(並列で)実行するためのワークフロー制御を行うエージェントです。この ParallelAgent から呼び出されて、2つのエージェントが同時に起動します。公式ドキュメント検索エージェントと、G-gen ナレッジ検索エージェントです。 これらの検索エージェントは、Tools(エージェントが目的を達成するために使うプログラム群)として Vertex AI Search を用いて、Google の公式ドキュメントや G-gen のナレッジに対して検索を行います。パラレルに実行している理由は、回答までの時間を短縮するためです。 これらの検索ツールに対して検索を行う際、エージェントはユーザーからの質問を適切な検索クエリに変換して検索を実行します。この検索クエリ生成には、LLM の特性である 自然言語の解釈が必須 です。ユーザーからの質問をそのまま検索にかけたのでは、適切な検索結果は得られません。データソースに応じて、技術要素をスペース区切りの単語で検索したり、あるいは技術的な要素だけを抽出した自然な質問文に変換して、Vertex AI Search に対して検索または質問を実行します。 なお、G-gen ナレッジ検索エージェントは補助的な情報源として、Google 検索グラウンディングを有効化した Gemini による生成も用います。G-gen のナレッジだけを基にするのではなく、一般的なインターネット情報を追加の情報源とできるように、いわばサードオピニオンとして追加しています。 Vertex AI Search から検索結果が得られると、最後に最終回答作成エージェントが起動します。生成 AI モデル Gemini を用いて、前のエージェントが見つけ出した検索結果を統合・要約して、質問者の意図に沿う回答を生成します。 なぜ AI エージェントなのか 当システムを実装するにあたり、単純な RAG 構成等ではなく、ADK を使った AI マルチエージェントという実装を選択した理由として、以下が挙げられます。 AI エージェントおよび ADK の実証実験としての意義 複数のデータソースへの検索を統合して要約するというワークフロー的な処理の性質 前者については、当社が Google Cloud 専業インテグレーターであり、今後顧客に AI エージェントの実装を提案するにあたっての実証実験的な意義がありました。ただし、これはシステムの技術選定における本筋ではありません。 後者のほうが重要です。従来型の RAG では、例えば Gemini における実装であれば、API エンドポイントへ生成リクエストを送信するときに Tools として Google 検索ツールを渡し、グラウンディングを指示します。また Vertex AI Search であれば、あるデータソースをグラウンディング先として指定した Vertex AI Search アプリに対して answer メソッドで回答の生成を指示します。 参考 : Grounding with Google Search 参考 : Get answers and follow-ups これらの生成方法だと、「単一の生成リクエストで1つまたは複数のデータソースに対するグラウンディングを行う」ということはできても、「あるデータソースを根拠とした生成リクエスト A と、別のデータソースを根拠とした生成リクエスト B を統合して、複数の根拠や視点に基づいて結果を生成する」といったことはできません。実際に Vertex AI Search の Blended Search(複数のデータソースに対してグラウンディングを行う機能)を使って Google Cloud の技術に関する質問に回答させたところ、関連度が高いと判断された一部のデータソースに基づいて回答が生成されてしまい、AI エージェント構成とした場合よりも精度が低いものとなりました。 G-gen Tech Agent のユースケースでは、AI エージェントが複数の生成結果を統合することにより精度が高まったため、単純な RAG 構成よりも適切と判断されました。 インフラ構成 G-gen Tech Agent は Web サービスであり、ホストするためにサーバーが必要です。G-gen Tech Agent は、サーバーレスなプラットフォームである Cloud Run にホストされています。 AI エージェントのホスト先として、Google Cloud では他に Vertex AI Agent Engine が挙げられます。今回は、エージェントを Web 経由だけでなく社内の Slack 経由でも呼び出すなどの将来的な拡張性を見込み、より小回りの効く Cloud Run を採用しました(Agent Engine でも同様のことは実現できます。追加の採用理由として、類似の社内ツールが以前 Cloud Run で実装されていたため、このアセットを流用したという背景もあります)。 参考 : Agent Development Kitでエージェントを開発してAgent Engineにデプロイしてみた 構成図は、以下のとおりです。 インフラ構成図 すべての要素はサーバーレスで実装されています。利用した Google Cloud サービスは以下のとおりです。 Cloud Run(フロントエンド・バックエンド) Vertex AI(生成 AI モデル Gemini の API) AI Applications - Vertex AI Search(データソースに対する検索) Vertex AI Search 当システムでは、Vertex AI Search を使ってデータソースに対する検索を行っています。 G-gen が保有する Web サイトである G-gen Tech Blog に対しては、高度なインデックス登録(Advanced index)が有効化できます。これを行うことで、ウェブサイトに対して単なる単語検索ではなく、自然言語でクエリすると自然言語によって回答が返ってくる answer メソッド が利用可能になります。 参考 : 高度な機能について - ウェブサイトの高度なインデックス登録 参考 : Vertex AI Searchを徹底解説! - G-gen Tech Blog - Web データストア 一方で、Google の公式ドキュメントは G-gen が保有するものではないため、高度なインデックス登録に必須なドメイン認証を行うことができません。そのため通常のウェブサイト検索となり、検索には search メソッド を使っています。投げかける検索クエリはスペース区切りの単語としています。 また、過去サポートケースに基づいた FAQ に対しても、Vertex AI Search の answer メソッドを使っています。データストアは BigQuery に格納された構造化データです。 このようにデータソースに応じて適切な検索クエリが異なりますが、生成 AI により、適切な検索クエリを生成させています。 バッチ処理 G-gen の過去サポートケースについては、過去の顧客とのやりとりを直接的に検索させているわけではありません。日次のバッチ処理で顧客とのやりとりの情報を要約して FAQ 化し、BigQuery に格納したうえで、Vertex AI Search のデータストア化しています。 また FAQ には純粋な技術的な情報のみが含まれており、顧客固有の情報や機密情報、個人情報が入りこまないよう、検知と処理、人間の目によるチェックを行っています。さらに、バッチ処理時やフロントエンド側のシステムプロンプトでも、そういった情報が回答に入りこまないように LLM に指示されており、この対策は信頼度が絶対といえないまでも多層的な対策の一環を担っています。 過去のサポートケースを FAQ 化するための日次のバッチ処理でも、Gemini モデルが使われています。 バッチ処理構成図 ADK 関連記事 以下は、最近の ADK に関する関連記事です。開発にあたり、参考にしてください。 blog.g-gen.co.jp blog.g-gen.co.jp blog.g-gen.co.jp blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO 元警察官という経歴を持つ IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。2025年7月のイチオシ Google Cloud(旧称 GCP)アップデートをまとめてご紹介します。記載は全て、記事公開当時のものですのでご留意ください。 はじめに 組織のポリシーの Policy Simulator が Preview -> GA Cloud SQL for MySQL/PostgreSQL で書き込みエンドポイントが GA Google Workspace の Gemini 関連の監査ログが強化 Gemini サイドパネルで、Gems が利用可能に Cloud Storage でバケット IP フィルタリングが Preview → GA Vertex AI Search で文字列の完全一致検索が可能に Google Meet のライブストリーミングで参加者がチャット送信可能に Google Drive Events API が Preview 公開 BigQuery でデフォルトの SQL が LegacySQL → GoogleSQL に変更 Vertex AI Agent Engine で Memory Bank が登場(Preview) Gmail に 「サブスクリプションを管理」画面が登場 SCC に Notebook Security Scanner が登場(Preview) Gemini アプリでVeo 3 による動画生成が可能に(一部ユーザーのみ) Vertex AI Search の回答生成モデルで Gemini 2.5 Flash が利用可能 SharePoint から Google ドライブへの移行ツールが Beta → GA Google Cloud Marketplace の自社データ販売機能が Preview → GA Google カレンダーのアポイント予約をメールに直接組み込めるように AppSheet Enterprise Plus エディションで AI Tasks が Preview -> GA Looker Studio レポートで Short query optimized mode が利用可能に BigQueryのパイプ構文が拡張 IAM 編集画面で Gemini による最小権限ロールの提案(Preview) Gemini 2.5 Flash-Lite が Preview → GA(一般公開) Google Maps グラウンディングが米国以外でも利用可能に(Preview) Looker で BigQuery への Optional job creation mode が使われるように Looker Studio レポートに Description(説明欄)が追加できるように Cloud Monitoring の1機能として Cost Explorer が Preview 公開 Code Interpreter が Looker と Looker Studio Pro で 試験運用版 →Preview Vertex AI と Model Armor が統合 (Preview) Gemini for Google Cloud API が BigQuery プロジェクトで自動で有効化 NotebookLM に「動画概要」機能が登場 はじめに 当記事では、毎月の Google Cloud(旧称 GCP)や Google Workspace(旧称 GSuite)のアップデートのうち、特に重要なものをまとめます。 また当記事は、Google Cloud に関するある程度の知識を前提に記載されています。前提知識を得るには、ぜひ以下の記事もご参照ください。 blog.g-gen.co.jp リンク先の公式ガイドは、英語版で表示しないと最新情報が反映されていない場合がありますためご注意ください。 組織のポリシーの Policy Simulator が Preview -> GA Test organization policy changes with Policy Simulator (2025-07-01) 組織のポリシーの Policy Simulator が Preview -> GA。 組織ポリシーの影響を事前にシミュレーションできる。「マネージド制約」や「カスタム制約」 のみで利用可能。通常の従来型の制約では利用できないので注意。 Cloud SQL for MySQL/PostgreSQL で書き込みエンドポイントが GA Cloud SQL for PostgreSQL release notes - July 01, 2025 (2025-07-01) Cloud SQL for MySQL/PostgreSQL で書き込みエンドポイントが Preview → GA。 Enterprise Plus Edition でのみ利用可。プライマリインスタンスのプライベート IP を指す DNS 名。インスタンスがフェイルオーバーしてもアプリ側で向き先を変える必要がない。 Google Workspace の Gemini 関連の監査ログが強化 Access Gemini Audit logs using the Reporting API, the security and audit investigation tools (2025-07-01) Google Workspace の Gemini 関連の監査ログが強化。 Drive、Gmail、Docs 上の Gemini アクションを記録。Security Investigation Tool で閲覧可能なほか、Reporting API で取得可能。 Gemini サイドパネルで、Gems が利用可能に Gems are now available in the side panel of Google Workspace apps (2025-07-02) Gemini サイドパネルで、Gems が利用可能になる。 Gems は事前にカスタムプロンプトを登録しておける機能。これまで Gemini アプリだけで使えたが、今後は Google Drive、Docs、Sheets、Slides、Gmail でも使えるようになる。順次ロールアウト。 Cloud Storage でバケット IP フィルタリングが Preview → GA Bucket IP filtering (2025-07-02) Cloud Storage でバケット IP フィルタリングが Preview → GA。 バケット単位で接続元 IP アドレスや接続元 VPC ネットワークを制限できる。BigQuery へのロードなどの機能が使用できなくなることに注意が必要。 Vertex AI Search で文字列の完全一致検索が可能に AI Applications release notes - July 02, 2025 (2025-07-02) Vertex AI Search で文字列の完全一致検索が可能に。 検索時に文字列をダブルクォーテーション( " )で囲うと、文字列完全一致での検索が可能になる。固有名詞や厳密な検索が必要なときに使える。 Google Meet のライブストリーミングで参加者がチャット送信可能に Live stream viewers can now send chat messages, plus additional host controls (2025-07-02) Google Meet のライブストリーミングで参加者がチャット送信可能になった。 管理設定で閲覧者が「チャット送信」「チャット閲覧」できるかどうかを設定できる(デフォルトはいずれも許可)。 Google Drive Events API が Preview 公開 Google Drive Events API now available in Developer Public Preview (2025-07-07) Google Drive Events API が Preview 公開。 Google ドライブのファイル変更通知を Pub/Sub で受け取る等が可能に。従来も notification channel 作成は可能だったが、今回発表の新 API は Google Workspace Events API と統合されており、イベント形式が CloudEvent 形式になっている。より Pub/Sub、Cloud Run 等と統合がしやすくなった。 BigQuery でデフォルトの SQL が LegacySQL → GoogleSQL に変更 BigQuery release notes - July 08, 2025 (2025-07-08) BigQuery で CLI/API のデフォルト SQL が LegacySQL → GoogleSQL に変更(2025-08-01から)。 古くから CLI/API で LegacySQL を実行している場合、引き続き LegacySQL を使うには明示的に設定が必要。管理者には以前からメールで通知されていた。G-gen からもお知らせメールを配信済み。 Vertex AI Agent Engine で Memory Bank が登場(Preview) Vertex AI Agent Engine Memory Bank overview (2025-07-08) Vertex AI Agent Engine で Memory Bank が登場(Preview)。 ユーザーと AI エージェントの会話を長期的に保管するストレージ。長期記憶のために DB を外部に作成する必要がなくなる。 短期記憶 → Session 管理 長期記憶 → Memory Bank Gmail に 「サブスクリプションを管理」画面が登場 Manage email subscriptions from a single location in Gmail (2025-07-08) Gmail で、メルマガ登録等のサブスクリプションを「サブスクリプションを管理」の1画面でまとめて管理(購読解除)できるようになる。順次ロールアウトされまもなく Web、iOS、Android アプリで使用可能になる。 SCC に Notebook Security Scanner が登場(Preview) Notebook Security Scanner (2025-07-11) Security Command Center の Premium/Enterprise ティアに Notebook Security Scanner が登場(Preview)。 Colab Enterprise ノートブック内で使われている Python パッケージを24時間ごとにスキャンして脆弱性を検知。現在は US と EU の一部リージョンのみ対応。 Gemini アプリでVeo 3 による動画生成が可能に(一部ユーザーのみ) Google Workspace Updates Weekly Recap - July 11, 2025 (2025-07-11) 一部の Google Workspace ユーザー(for select Workspace customers)の Gemini アプリで Veo 3 による動画生成が可能になった。 音声付きの8秒間の動画を、1日3回生成できる。写真から動画生成も可能。 Vertex AI Search の回答生成モデルで Gemini 2.5 Flash が利用可能 AI Applications release notes - June 26, 2025 (2025-06-26) Vertex AI Search の回答生成時のモデルに、Gemini 2.5 Flash が選択できるようになった。 これまでの最新は Gemini 2.0 Flash。コンテキストを意識した回答の生成で精度が向上する見込み。 SharePoint から Google ドライブへの移行ツールが Beta → GA Now Generally Available: Migrate files from Microsoft SharePoint Online to Google Drive (2025-07-14) SharePoint から Google ドライブへの移行ツールが Beta → 一般提供(GA)。 Workspace 管理画面組み込みのツール。ドキュメントライブラリ、フォルダ、ファイル、権限を移行可能。新規追加・更新されたファイルの差分転送も可能。 Google Cloud Marketplace の自社データ販売機能が Preview → GA Commercialize listings on Google Cloud Marketplace (2025-07-15) BigQuery sharing(旧 Analytics Hub)を使い Google Cloud Marketplace で自社データを販売する機能が Preview → GA。 自社保有データの収益化が容易になる。ただし規約上、まだ日本国内企業が対象になっていないため、日本企業はまだ利用できない。 Google カレンダーのアポイント予約をメールに直接組み込めるように Link your Google Calendar booking pages when composing emails in Gmail (2025-07-15) Google カレンダーのアポイント予約(apointment booking)を Gmail のメールに直接組み込めるように。順次ロールアウト。 AppSheet Enterprise Plus エディションで AI Tasks が Preview -> GA Now generally available: extract and categorize data in AppSheet with the power of Gemini (2025-07-16) AppSheet の Enterprise Plus エディションで使える AI Tasks が Preview -> GA(一般提供)。 Gemini が、写真や PDF からのデータ抽出や分類を Automation 内で自動的に行う。つまり、ノーコードで生成 AI アプリが簡単に作れる。 Looker Studio レポートで Short query optimized mode が利用可能に Looker Studio release notes - July 17, 2025 (2025-07-17) Looker Studio レポート(BigQuery データソース)で Short query optimized mode(Optional job creation mode)がサポート。 小規模クエリが高速化する可能性あり。データソースが「閲覧者の認証情報」を使っているなど特定条件でのみ適用される。 BigQuery の Optional job creation mode(オプションのジョブ作成モード)については以下も参照。 blog.g-gen.co.jp BigQueryのパイプ構文が拡張 BigQuery release notes - July 17, 2025 (2025-07-17) BigQueryのパイプ構文が拡張。以下の構文が利用可能になった。 WITH 使い回せるテーブル表現を定義 named windows ウインドウ関数と似ており結果の各行で共通して表示する集計を定義 DISTINCT 一意にレコードを抽出 IAM 編集画面で Gemini による最小権限ロールの提案(Preview) Get predefined role suggestions with Gemini assistance (2025-07-21) IAM 権限編集画面で Gemini による最小権限ロールの提案が使用可能になった(Preview)。 自然言語による質問で適切なロールを提案。ただしコンソールの言語を英語版にしないと使えない。 Gemini 2.5 Flash-Lite が Preview → GA(一般公開) Gemini 2.5 Flash-Lite (2025-07-22) Gemini 2.5 Flash-Lite が Preview → GA(一般公開)。 Gemini 2.5 Flash より軽量・高速・安価なモデル。バッチ推論にも対応。Vertex AI と Google AI Studio の両方で GA 版が利用可能。 Google Maps グラウンディングが米国以外でも利用可能に(Preview) Grounding with Google Maps in Vertex AI (2025-07-23) Gemini の Google Maps を使ったグラウンディングが米国以外でも利用可能に(Preview)。 これまで米国ユーザーのみプレビュー可能だった。Vertex AI 経由の Gemini 呼び出しで使える。 Looker で BigQuery への Optional job creation mode が使われるように Looker release notes - July 24, 2025 (2025-07-24) Looker Studio に続いて Looker でも、BigQuery に対する Optional job creation mode( Short query optimized mode)が使われるようになった。 小規模クエリがより短時間で返る可能性がある。 BigQuery の Optional job creation mode(オプションのジョブ作成モード)については以下も参照。 blog.g-gen.co.jp Looker Studio レポートに Description(説明欄)が追加できるように Looker Studio release notes - July 24, 2025 (2025-07-24) Looker Studio レポートに Description(説明欄)が追加できるようになった。 テキストで説明を付記できる。レポート検索時にも検索対象になる。 Cloud Monitoring の1機能として Cost Explorer が Preview 公開 Optimize costs with the Cost Explorer (2025-07-24) Cloud Monitoring の1機能として Cost Explorer が Preview 公開。 対応プロダクト(主に Compute 系)のコストを分析してダッシュボード表示してくれる。 Code Interpreter が Looker と Looker Studio Pro で 試験運用版 →Preview Conversational Analytics Code Interpreter (2025-07-25) 試験運用版だった Code Interpreter in Conversational Analytics が Looker と Looker Studio Pro で Preview 公開され全ユーザー利用可能になった。 データソースに対する、より高度な分析が自然言語で可能になる。 通常の Conversational Analytics => 自然言語を SQL に変換 Code Interpreter in Conversational Analytics => 自然言語を Python に変換 Vertex AI と Model Armor が統合 (Preview) Model Armor integration with Vertex AI (2025-07-29) Vertex AI と Model Armor が統合(Preview)。 最小限のソースコード変更で、Gemini へのリクエストとそのレスポンスを検査できる。プレビュー期間中は無料。 現時点で us-central1、us-east4、us-west1、europe-west4 の API エンドポイントにのみ対応している。 Model Armor と、上記の使い方については以下の記事に追記した。 blog.g-gen.co.jp Gemini for Google Cloud API が BigQuery プロジェクトで自動で有効化 BigQuery release notes - July 30, 2025 (2025-07-30) Gemini for Google Cloud API が BigQuery 使用中のプロジェクトで自動的に有効化される。 数ヶ月前から Google より管理者へ一斉通知があった通り。Gemini in BigQuery の SQL 生成・補完やデータキャンバスなどが無料で使用可能。 NotebookLM に「動画概要」機能が登場 Introducing Video Overviews and upgrades to the Studio panel in NotebookLM (2025-07-30) NotebookLM に「動画概要」機能が登場。 データソースに基づいて、解説動画を生成する。現在の対応言語は英語のみだが、今後は拡張予定。 2025 年 8 月 4 日の週に 100% ロールアウト完了予定。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の min です。Looker Studio の機能である 計算フィールド について、その概要から具体的な使い方、トラブルシューティングを解説します。 計算フィールドとは 計算フィールドの種類 計算フィールドの作成方法 データソースの計算フィールドを作成する レポート固有の計算フィールドを作成する 関数 関数とは CASE 文の使い方 トラブルシューティング 構文エラー データ型の不一致 集計エラー 計算フィールドとは Looker Studio における 計算フィールド とは、データソースに元々存在するフィールドを基に、関数や数式を用いて新しいディメンションや指標を作成する機能です。 例えば、データソースに「売上」と「費用」の指標がある場合、これらを使って 売上 - 費用 という数式で「利益」という新しい指標を作成できます。また、「姓」と「名」のディメンションを結合して「氏名」という新しいディメンションを作成することも可能です。 このように、計算フィールドを利用することで、元のデータを加工したり、複数のフィールドを組み合わせたりして、レポートで表現したい形にデータを整形できます。可視化の幅を広げるために非常に重要な機能です。 参考 : 計算フィールドについて 計算フィールドの種類 計算フィールドには、作成する場所によって2つの種類があります。それぞれの特徴を理解し、用途に応じて使い分けることが大切です。 種類 説明 メリット デメリット データソースの計算フィールド データソースの編集画面で作成するフィールド。 そのデータソースを使用する全てのレポートで再利用できる。一貫性が保たれる。 作成・編集にはデータソースの編集者の権限が必要。 レポート固有の計算フィールド レポート内の特定のグラフ(表やスコアカードなど)に対して作成するフィールド。 レポートの編集者の権限があれば作成できる。特定のグラフでのみ使用する一時的な計算に便利。 他のグラフやレポートで再利用できない。同じ計算を複数のグラフで使う場合は都度作成が必要。 基本的には、複数のレポートやグラフで汎用的に使用するフィールドは データソースの計算フィールド として作成し、特定のグラフでのみ一時的に必要な計算は レポート固有の計算フィールド として作成するとよいでしょう。 計算フィールドの作成方法 データソースの計算フィールドを作成する Looker Studio のレポート編集画面で、メニューから「リソース」>「追加済みのデータソースの管理」を選択します。 計算フィールドを追加したいデータソースの「編集」をクリックします。 データソースのフィールド一覧画面の右上にある「フィールドを追加」>「計算フィールドを追加」をクリックします。 フィールドエディタが開きます。「フィールド名」を入力し、「計算式」の欄に数式を入力します。 右下の「保存」をクリックして完了です。作成したフィールドは、このデータソースを使用する全てのレポートで利用できます。 レポート固有の計算フィールドを作成する レポート編集画面で、計算フィールドを追加したいグラフ(表、スコアカードなど)を選択します。 画面右側のプロパティパネルで、「ディメンション」または「指標」セクションの下部にある「 ディメンションを追加 」または「 指標を追加 」をクリックします。 表示されたメニューから「 計算フィールドを追加 」を選択します。 フィールドエディタが開きます。「表示名」を入力し、「数式」の欄に数式を入力します。 データ型を選択し、「適用」をクリックします。作成したフィールドは、選択したグラフでのみ利用できます。 参考 : グラフ固有の計算フィールドの制約 関数 関数とは 計算フィールドでは、単純な四則演算( + , - , * , / )だけでなく、 関数 を利用することでより高度なデータ操作ができます。 関数はカテゴリごとに分類されています。以下に代表的な関数を紹介します。 カテゴリ 代表的な関数 説明 集計 SUM , AVG , COUNT , COUNT_DISTINCT 指標の合計、平均、個数、ユニークな値の個数を計算する。 算術 POWER , ROUND べき乗や四捨五入などの算術計算を行う。 日付 TODAY , YEAR , DATE_DIFF , DATETIME_TRUNC 今日の日付の取得、年から年の抽出、日付の差分計算、日付の切り捨てなどを行う。 テキスト CONCAT , LENGTH , LOWER , UPPER , SUBSTR , REGEXP_MATCH 文字列の結合、長さの取得、大文字・小文字変換、部分文字列の抽出、正規表現による一致判定などを行う。 条件分岐 CASE , IF 条件に応じて返す値を変更する。 全ての関数の一覧は、以下の公式ドキュメントを参照してください。 参考 : 関数リスト CASE 文の使い方 特に使用頻度が高いのが、条件分岐を行う CASE 文です。 CASE 文を使うと、フィールドの値に応じて新しい値を割り当てることができます。 構文は以下の通りです。 CASE WHEN 条件 1 THEN 結果 1 WHEN 条件 2 THEN 結果 2 ELSE その他の結果 END 例えば、「国コード」フィールド( JP , US など)を基に「国名」フィールド( 日本 , アメリカ など)を作成する場合は、以下のように記述します。 CASE WHEN Country_Code = " JP " THEN " 日本 " WHEN Country_Code = " US " THEN " アメリカ " WHEN Country_Code = " KR " THEN " 韓国 " ELSE " その他 " END また、正規表現関数と組み合わせることで、より柔軟な条件設定が可能です。 CASE WHEN REGEXP_MATCH(店舗名, " .*駅前.* " ) THEN " 駅前店舗 " WHEN REGEXP_MATCH(店舗名, " .*SC.* " ) THEN " SC内店舗 " ELSE " その他の店舗 " END トラブルシューティング 計算フィールドの作成時によく発生するエラーとその対処法を解説します。 構文エラー 関数名のスペルが間違っている 、 括弧が閉じていない といった単純な文法ミスです。 計算フィールドのエディタは、エラーがある箇所を赤くハイライトしてエラーメッセージを表示してくれます。メッセージをよく読み、数式を修正してください。 データ型の不一致 テキスト型のフィールドと数値型のフィールドを足し算しようとする など、異なるデータ型のフィールド間で不適切な演算を行うとエラーになります。 この場合、 CAST 関数を使ってデータ型を明示的に変換する必要があります。例えば、テキストとして保存されている数値を数値型に変換するには CAST(フィールド名 AS NUMBER) のように記述します。 集計エラー 「集計指標と非集計ディメンションを混在させることはできません」というエラーは、計算フィールドの作成時に頻繁に発生するエラーの一つです。 これは、 集計済みの値 と 未集計の値 を一つの数式内で混ぜて使おうとしたときに発生します。Looker Studio の指標は、グラフに表示される際に行単位のデータが SUM や AVG などで 集計 されてから表示されます。 例えば、以下のような店舗ごとの商品単価データがあるとします。 店舗名 商品名 単価 渋谷店 商品A 1,000 新宿店 商品A 1,200 池袋店 商品A 900 このデータを使って「渋谷店の単価が、全店舗の単価の合計に占める割合」を計算したいとします。 ここで、以下のような誤った数式を入力したとします。 // 誤った例 ( CASE WHEN 店舗名 = " 渋谷店 " THEN 単価 ELSE 0 END ) / SUM (単価) この数式がエラーになる原因は、分子と分母で値の集計レベルが異なるためです。 分母の SUM(単価) は 集計済みの値 です。これは、表全体の単価を合計した 1000 + 1200 + 900 = 3100 という単一の数値を返します。 一方、分子の (CASE WHEN 店舗名 = "渋谷店" THEN 単価 ELSE 0 END) は 未集計の値 です。この部分は行ごとに評価されるため、結果は 1000, 0, 0 という複数の数値の集まりになります。 この数式は、「行ごとの複数の値( 1000, 0, 0 )を、全体で一つしかない値 3100 で割る」という計算を意味します。Looker Studioはどの値を割れば良いか判断できないため、エラーを返します。 このエラーを解決するには、分子も分母と同じように集計済みの値にする必要があります。 // 正しい例 SUM ( CASE WHEN 店舗名 = " 渋谷店 " THEN 単価 ELSE 0 END ) / SUM (単価) この数式では、分子と分母の両方が集計済みの単一の値になるため、計算できます。 分子は SUM(CASE ...) によって SUM(1000, 0, 0) が計算され、 1000 という単一の値になります。 分母は SUM(単価) によって 3100 という単一の値になります。 1000 / 3100 という明確な計算となり、正しく割合が返されます。 どのタイミングで集計が必要かを理解することが、このエラーを回避する鍵となります。 参考 : 計算フィールドのトラブルシューティング 佐々木 愛美 (min) (記事一覧) クラウドソリューション部 データアナリティクス課。2024年7月 G-gen にジョイン。G-gen 最南端、沖縄県在住。最近覚えた島言葉は、「マヤー(猫)」。
アバター
G-gen の杉村です。人間からの自然言語での質問に基づいて BigQuery にクエリを実行する AI エージェントを、 Agent Development Kit (ADK)で開発する方法を紹介します。 概要 Agent Development Kit(ADK)とは BigQuery ツールセット 実装 ソースコード エージェント定義と非同期実行 BigQuery ツールの定義 BigQuery を使うエージェントの定義 動作確認 最終回答 エージェントとツールの挙動 精度確認 質問のしかたを変える 複雑な質問 会話型分析(参考情報) 概要 Agent Development Kit(ADK)とは Agent Development Kit (ADK)は、AI エージェントの開発、デプロイ、評価を効率化するために Google が開発したオープンソースのフレームワークです。2025年7月現在、Python および Java 向けのライブラリとして公開されています。 ADK を利用することで、AI エージェントを容易に開発できます。また、ADK に組み込みの Built-in tools を使うことで、最小限のコーディングでエージェントに様々なタスクを行わせることができます。当記事では、Built-in tools の1つである BigQuery ツールセットを使って、人間からの自然言語での質問に応じて BigQuery テーブルにクエリを行うエージェントを開発する方法を紹介します。 参考 : Agent Development Kit 参考 : Built-in tools BigQuery ツールセット BigQuery ツールセット は、ADK の組み込みツールセットです。最小限のコーディングで、AI エージェントがユーザーの質問に応じたクエリを自動的に生成し、結果を得て、それに応じた回答を生成します。このツールセットには、以下のようなツールが含まれています。 ツール名 説明 list_dataset_ids プロジェクト内の BigQuery データセットをリストアップする get_dataset_info BigQuery データセットの情報を取得する list_table_ids BigQuery データセット内のテーブル ID をリストアップする get_table_info BigQuery テーブルのメタデータ(スキーマや Description)を取得する execute_sql BigQuery にクエリ(SQL)を実行する 参考 : Built-in tools - BigQuery 上記のツールを使うことで、エージェントは BigQuery に対する一通りの操作が可能です。これらのツールを使うことにより、以下のようなユーザーの質問に対して、AI エージェントが自律的に情報を取得することができます。 「BigQuery テーブル `〇〇.〇〇.〇〇` から xxx を取得して xxx のように集計して」 「BigQuery データセット `〇〇.〇〇` から xxx の情報を探し出して」 「プロジェクト 〇〇 の BigQuery から xxx の情報を取得して教えてください」 実装 ソースコード サンプルとして以下のソースコードを用意しました。 import asyncio import logging from google.adk.agents import LlmAgent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.adk.tools.bigquery import BigQueryCredentialsConfig from google.adk.tools.bigquery import BigQueryToolset from google.adk.tools.bigquery.config import BigQueryToolConfig from google.adk.tools.bigquery.config import WriteMode from google.genai import types import google.auth # 書き込みオペレーションが実行されるのを防ぐ tool_config = BigQueryToolConfig(write_mode=WriteMode.BLOCKED) # BigQuery への認証(Application Default Credentials) application_default_credentials, _ = google.auth.default() credentials_config = BigQueryCredentialsConfig( credentials=application_default_credentials ) # BigQuery ツールセットを定義 bigquery_toolset = BigQueryToolset( credentials_config=credentials_config, bigquery_tool_config=tool_config ) # BigQuery のジョブ実行プロジェクト ID(課金先) PROJECT_ID= "my-project" # BigQuery を使うエージェント bigquery_agent = LlmAgent( model= "gemini-2.5-flash" , name= "bigquery_agent" , instruction=f """ あなたは BigQuery のデータ分析をするエージェントです。 tools である `bigquery_toolset` を使って SQL を実行し、データを取得・分析してユーザーからの質問に回答を生成します。 BigQuery ジョブはプロジェクト ID `{PROJECT_ID}` で実行します。 """ , tools=[bigquery_toolset], ) # runner の定義 APP_NAME = "My Agent App" SESSION_SERVICE = InMemorySessionService() RUNNER = Runner( agent=bigquery_agent, app_name=APP_NAME, session_service=SESSION_SERVICE, ) async def stream_agent_events (query: str , user_id: str , session_id: str ): ''' # 概要 エージェントを実行します。 # 引数 query (str): エージェントに投げかけるクエリ(プロンプト) user_id (str): ユーザー ID session_id (str): セッション ID ''' # 既存セッションがなければ新規作成 session = await SESSION_SERVICE.get_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) if not session: await SESSION_SERVICE.create_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) # ユーザークエリを所定の形式で格納 content = types.Content(role= 'user' , parts=[types.Part(text=query)]) # エージェントの実行 async for event in RUNNER.run_async(user_id=user_id, session_id=session_id, new_message=content): parts = event.content.parts message = event.content.parts[ 0 ].text if message: yield (f "--- Message: {message}" ) return async def main (): """ エージェントを実行し、ストリーミングされたメッセージを出力するメイン関数 """ user_id= "test_user" session_id= "test_session" query= "BigQuery テーブル `bigquery-public-data.samples.shakespeare` から、シェイクスピア作品で頻出の単語のトップ10を教えてください。" # async for を使って非同期ジェネレータを処理 async for message in stream_agent_events(query=query, user_id=user_id, session_id=session_id): print (message) # ロギングを設定 logging.basicConfig( level=logging.DEBUG, format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s' ) # スクリプトのエントリーポイント if __name__ == "__main__" : asyncio.run(main()) エージェント定義と非同期実行 エージェントの定義( LlmAgent() )やそれに対する非同期実行( run_async() 等)については、以下の記事を参照してください。 blog.g-gen.co.jp BigQuery ツールの定義 当サンプルコードでは、ADK の組み込みツールである BigQuery ツールを以下のように定義しています。 # 書き込みオペレーションが実行されるのを防ぐ tool_config = BigQueryToolConfig(write_mode=WriteMode.BLOCKED) # BigQuery への認証(Application Default Credentials) application_default_credentials, _ = google.auth.default() credentials_config = BigQueryCredentialsConfig( credentials=application_default_credentials ) # BigQuery ツールセットを定義 bigquery_toolset = BigQueryToolset( credentials_config=credentials_config, bigquery_tool_config=tool_config ) tool_config で BigQueryToolConfig(write_mode=WriteMode.BLOCKED) とすることで、BigQuery に誤って書き込みオペレーションが実行されてしまうことを防ぎます。 認証については、 google.auth.default() により、Application Default Credentials を取得しています。これは、実行環境が Cloud Run や Vertex AI Agent Engine であれば環境にアタッチされたサービスアカウントを参照し、ローカルの実行環境であれば gcloud auth application-default login で設定された Google アカウントの認証情報等を参照します。 参考 : gcloud auth loginとgcloud auth application-default loginの違いとは? - G-gen Tech Blog また BigQueryToolset() により、書き込みブロックの設定や認証情報を指定して、BigQuery ツールを定義します。 BigQuery を使うエージェントの定義 ツールとして BigQuery を使うエージェントの定義は、以下のようになっています。 # BigQuery のジョブ実行プロジェクト ID(課金先) PROJECT_ID= "my-project" # BigQuery を使うエージェント bigquery_agent = LlmAgent( model= "gemini-2.5-flash" , name= "bigquery_agent" , instruction=f """ あなたは BigQuery のデータ分析をするエージェントです。 tools である `bigquery_toolset` を使って SQL を実行し、データを取得・分析してユーザーからの質問に回答を生成します。 BigQuery ジョブはプロジェクト ID `{PROJECT_ID}` で実行します。 """ , tools=[bigquery_toolset], ) ここでは定義した bigquery_toolset を tools として指定するだけで、エージェントが BigQuery ツールセットを使用するようになります。また instruction にて、「BigQuery ジョブはプロジェクト ID `{PROJECT_ID}` で実行します。」と指示しています(Python の f-strings により {PROJECT_ID} は実際のプロジェクト ID に置き換わります)。 検証時は、この指示を入れない場合だと、ユーザーのプロンプトで BigQuery データセット bigquery-public-data.samples.shakespeare からデータを取ってきてください のように指定されたとき、エージェントはパブリックデータセットのプロジェクトに対してジョブを実行しようとしてしまい、権限不足でクエリが失敗しました。 なお検証では、認証時に google.auth.default(quota_project_id=PROJECT_ID) のようにクォータプロジェクト(課金先プロジェクト)を指定しても、同様の挙動でした。 BigQuery のジョブ実行権限についての解説は、以下の記事も参考にしてください。 blog.g-gen.co.jp 動作確認 最終回答 上記のソースコードを実行した結果、以下のような最終回答が得られました。 クエリ BigQuery テーブル bigquery-public-data.samples.shakespeare から、シェイクスピア作品で頻出の単語のトップ10を教えてください。 最終回答 --- Message: はい、BigQuery テーブル `bigquery-public-data.samples.shakespeare` から、シェイクスピア作品で頻出の単語トップ10は以下の通りです。 1. the: 25568回 2. I: 21028回 3. and: 19649回 4. to: 17361回 5. of: 16438回 6. a: 13409回 7. you: 12527回 8. my: 11291回 9. in: 10589回 エージェントとツールの挙動 ロギング設定(ログレベルが DEBUG)により、エージェントがツールを使う挙動が標準出力に出力されます。この出力を確認することで、エージェントがどのように思考し、ツールを使用したのかを確認できます。出力の一部を抜粋すると、以下のとおりでした。 Function calls: name: list_table_ids, args: { 'project_id' : 'bigquery-public-data' , 'dataset_id' : 'samples' } Function calls: name: get_table_info, args: { 'table_id' : 'shakespeare' , 'dataset_id' : 'samples' , 'project_id' : 'bigquery-public-data' } Function calls: name: execute_sql, args: { 'project_id' : my-project, 'query' : 'SELECT word, SUM(word_count) AS total_count FROM `bigquery-public-data.samples.shakespeare` GROUP BY word ORDER BY total_count DESC LIMIT 10' } Contents: { "parts" :[{ "text" : "BigQuery テーブル `bigquery-public-data.samples.shakespeare` から、シェイクスピア作品で頻出の単語のトップ10を教えてください。" }], "role" : "user" } { "parts" :[{ "function_call" :{ "args" :{ "project_id" : "bigquery-public-data" , "dataset_id" : "samples" }, "name" : "list_table_ids" }}], "role" : "model" } { "parts" :[{ "function_response" :{ "name" : "list_table_ids" , "response" :{ "result" :[ "github_nested" , "github_timeline" , "gsod" , "natality" , "shakespeare" , "trigrams" , "wikipedia" ]}}}], "role" : "user" } { "parts" :[{ "function_call" :{ "args" :{ "table_id" : "shakespeare" , "dataset_id" : "samples" , "project_id" : "bigquery-public-data" }, "name" : "get_table_info" }}], "role" : "model" } { "parts" :[{ "function_response" :{ "name" : "get_table_info" , "response" :{ "kind" : "bigquery#table" , "etag" : "BeoZAW5rQH2EllmuKl2a2A==" , "id" : "bigquery-public-data:samples.shakespeare" , "selfLink" : "https://bigquery.googleapis.com/bigquery/v2/projects/bigquery-public-data/datasets/samples/tables/shakespeare" , "tableReference" :{ "projectId" : "bigquery-public-data" , "datasetId" : "samples" , "tableId" : "shakespeare" }, "schema" :{ "fields" :[{ "name" : "word" , "type" : "STRING" , "mode" : "REQUIRED" , "description" : "A single unique word (where whitespace is the delimiter) extracted from a corpus." },{ "name" : "word_count" , "type" : "INTEGER" , "mode" : "REQUIRED" , "description" : "The number of times this word appears in this corpus." },{ "name" : "corpus" , "type" : "STRING" , "mode" : "REQUIRED" , "description" : "The work from which this word was extracted." },{ "name" : "corpus_date" , "type" : "INTEGER" , "mode" : "REQUIRED" , "description" : "The year in which this corpus was published." }]}, "numBytes" : "6432064" , "numLongTermBytes" : "6432064" , "numRows" : "164656" , "creationTime" : "1457975805856" , "lastModifiedTime" : "1457975805856" , "type" : "TABLE" , "location" : "US" , "numTimeTravelPhysicalBytes" : "0" , "numTotalLogicalBytes" : "6432064" , "numActiveLogicalBytes" : "0" , "numLongTermLogicalBytes" : "6432064" , "numTotalPhysicalBytes" : "485656" , "numActivePhysicalBytes" : "0" , "numLongTermPhysicalBytes" : "485656" , "numCurrentPhysicalBytes" : "485656" }}}], "role" : "user" } { "parts" :[{ "function_call" :{ "args" :{ "project_id" : "my-project" , "query" : "SELECT word, SUM(word_count) AS total_count FROM `bigquery-public-data.samples.shakespeare` GROUP BY word ORDER BY total_count DESC LIMIT 10" }, "name" : "execute_sql" }}], "role" : "model" } { "parts" :[{ "function_response" :{ "name" : "execute_sql" , "response" :{ "status" : "SUCCESS" , "rows" :[{ "word" : "the" , "total_count" : 25568 },{ "word" : "I" , "total_count" : 21028 },{ "word" : "and" , "total_count" : 19649 },{ "word" : "to" , "total_count" : 17361 },{ "word" : "of" , "total_count" : 16438 },{ "word" : "a" , "total_count" : 13409 },{ "word" : "you" , "total_count" : 12527 },{ "word" : "my" , "total_count" : 11291 },{ "word" : "in" , "total_count" : 10589 },{ "word" : "is" , "total_count" : 8735 }]}}}], "role" : "user" } 出力を見ると、ツールセットに含まれる list_table_ids 、 get_table_info 、 execute_sql が順に実行されています。エージェントはまずテーブルの存在確認を行い、次にテーブルのスキーマを取得して構造を理解しました。このとき、テーブルやカラムのメタデータ( description )も取得していることがわかります。最後に SELECT 文を実行し、データを取得し、それを解釈して回答を生成したことがわかります。 このような挙動からも、AI エージェントがテーブル構造を適切に理解してクエリを実行するには、メタデータ管理が重要であることがわかります。 参考 : メダリオンアーキテクチャ2.0とGoogle CloudのAIエージェント活用 - G-gen Tech Blog 精度確認 エージェントが生成したクエリを確認し、また念の為、エージェントが実行したクエリを手作業でも実行してみます。 質問内容に対して、エージェントの実行したクエリは適切であり、実行結果とも整合性が取れていることがわかります。 クエリ SELECT word, SUM (word_count) AS total_count FROM `bigquery- public -data.samples.shakespeare` GROUP BY word ORDER BY total_count DESC LIMIT 10 実行結果 word total_count the 25568 I 21028 and 19649 to 17361 of 16438 a 13409 you 12527 my 11291 in 10589 is 8735 質問のしかたを変える エージェントが自律的に判断して BigQuery の様々なタスクを実行できることを確認するため、以下のようなクエリも実行してみます。 BigQuery データセット bigquery-public-data.samples から、シェイクスピア作品で頻出の単語のトップ10を教えてください。 先程はテーブル ID を指定しましたが、今回はデータセット ID のみを指定しています。結果は、エージェントが適切にデータセット内からテーブルをリストアップし、適切なテーブルを見つけ出してクエリを実行しました。 最終回答 シェイクスピア作品で最も頻出する単語トップ10は以下の通りです。 1. the: 25568 2. I: 21028 3. and: 19649 4. to: 17361 5. of: 16438 6. a: 13409 7. you: 12527 8. my: 11291 9. in: 10589 10. is: 8735 これらの単語は、シェイクスピアの作品で最も多く使用されています。 エージェントの処理 Function calls: name: list_table_ids, args: {'project_id': 'bigquery-public-data', 'dataset_id': 'samples'} Function calls: name: get_table_info, args: {'dataset_id': 'samples', 'table_id': 'shakespeare', 'project_id': 'bigquery-public-data'} Function calls: name: execute_sql, args: {'project_id': my-project, 'query': 'SELECT word, SUM(word_count) AS total_word_count FROM `bigquery-public-data.samples.shakespeare` GROUP BY word ORDER BY total_word_count DESC LIMIT 10'} さらに、以下のようなクエリでも想定どおりの結果が返りました。 BigQuery プロジェクト bigquery-public-data から、シェイクスピア作品で頻出の単語のトップ10を教えてください。 この場合は、 list_dataset_ids → list_table_ids → get_table_info → execute_sql と順番にツールを使って処理が実行され、適切なテーブルにたどり着きました。 複雑な質問 AI エージェントは、以下のような少し複雑な質問にも対応できます。処理結果を見ると、必要な分、複数回のクエリを発行し、それを最後に LLM がまとめていることがわかります。このような質問にエージェントが回答できれば、より実践的なユースケースにも対応できる可能性が出てきます。 クエリ 米国で生まれた子供に多い名前の傾向を、2000年と2020年で比較してください。どのような違いがありますか? BigQuery テーブル bigquery-public-data.usa_names.usa_1910_current からデータを取得してください。 最終回答 2000年と2020年の米国における人気のある名前の傾向を比較すると、以下の点が挙げられます。 **2000年の人気上位の名前:** * **男の子:** Jacob, Michael, Matthew, Joshua, Christopher, Nicholas, Andrew, Joseph, Daniel, Tyler * **女の子:** Emily, Hannah, Madison, Ashley, Sarah, Alexis, Samantha, Jessica, Elizabeth, Taylor **2020年の人気上位の名前:** * **男の子:** Liam, Noah, Oliver, Elijah, William, James, Benjamin, Lucas, Henry, Alexander * **女の子:** Olivia, Emma, Ava, Charlotte, Sophia, Amelia, Isabella, Mia, Evelyn, Harper **主な違い:** * **名前のトレンドの変化:** 2000年と2020年の上位10位の名前には、ほとんど重複がありません。これは、わずか20年の間に名前の流行が大きく変化したことを示しています。 * **新しい名前の台頭:** 2020年には、「Liam」「Noah」「Olivia」「Ava」など、2000年には上位に入っていなかった新しい名前が人気を集めていることがわかります。 * **伝統的な名前の継続的な人気:** 「William」や「James」、「Elizabeth」など、比較的時間に左右されない伝統的な名前も依然として一定の人気を保っていることが伺えますが、上位を占めるのはより現代的な名前になっています。 この比較から、米国における子どもの名前の傾向は、社会や文化の変化を反映して、20年間で大きく移り変わっていることが明確にわかります。 処理の経緯 (一部のみ抜粋) Function calls: name: get_table_info, args: {'dataset_id': 'usa_names', 'project_id': 'bigquery-public-data', 'table_id': 'usa_1910_current'} 2025 - 07 - 29 09: 22 : 58 , 336 - DEBUG - google_adk.google.adk.models.google_llm - LLM Response: ----------------------------------------------------------- Text: 2000 年と 2020 年の米国で生まれた子供に多い名前の傾向を比較するため、`bigquery-public-data.usa_names.usa_1910_current` テーブルからデータを取得します。 まず、 2000 年の男女別人気上位 10 の名前を抽出します。 ----------------------------------------------------------- Function calls: name: execute_sql, args: { 'project_id' : my-project, 'query' : " \n SELECT \n name, \n SUM(number) as total_occurrences \n FROM \n `bigquery-public-data.usa_names.usa_1910_current` \n WHERE \n year = 2000 AND gender = 'M' \n GROUP BY \n name \n ORDER BY \n total_occurrences DESC \n LIMIT 10; \n " } 2025 - 07 - 29 09: 23 : 04 , 532 - DEBUG - google_adk.google.adk.models.google_llm - LLM Response: ----------------------------------------------------------- Text: 次に、 2020 年の男女別人気上位 10 の名前を抽出します。 ----------------------------------------------------------- Function calls: name: execute_sql, args: { 'project_id' : my-project, 'query' : " \n SELECT \n name, \n SUM(number) as total_occurrences \n FROM \n `bigquery-public-data.usa_names.usa_1910_current` \n WHERE \n year = 2020 AND gender = 'M' \n GROUP BY \n name \n ORDER BY \n total_occurrences DESC \n LIMIT 10; \n " } 会話型分析(参考情報) ADK とは関係のない参考情報ですが、BigQuery のデータに対して自然言語によるクエリや分析を行いたい場合、 Looker や Looker Studio Pro に搭載の Conversational Analytics (会話型分析)も有用な選択肢です。 この機能では、自然言語、かつチャット形式で Looker や Looker Studio の画面から問いを投げかけるだけで、AI が BigQuery 等のデータソースに対してクエリを発行し、分析や可視化が可能です。 参考 : Looker の会話分析 参考 : Looker Studio の会話分析 Looker Studio Pro の会話型分析 Looker や Looker Studio Pro については、以下の記事も参考にしてください。 blog.g-gen.co.jp blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の三浦です。当記事では、特定の GitHub リポジトリの内容を Gemini アプリに解説させる方法を紹介します。 概要 当機能について Gemini アプリとは 前提条件 検証手順 検証 リポジトリとディレクトリ構成 main.py error/error.py パブリックリポジトリのインポート コード理解と改善の確認 プライベートリポジトリのフォルダインポート デバッグとコード生成の確認 概要 当機能について Gemini アプリでは、GitHub のパブリックリポジトリまたはプライベートリポジトリをインポートして、その内容に関する質問や依頼ができます。 この機能は、ソースコードの理解の支援や改善案の提案、コード生成、エラー解析といった用途に利用できます。 詳細は以下の公式ドキュメントをご参照ください。 参考 : GitHub リポジトリをインポートして Gemini ウェブアプリでそれについて質問する Gemini アプリとは Gemini アプリ は、Google が提供する生成 AI チャットアプリケーションです。プログラミング、ドキュメント作成、質問応答など多用途に対応しています。 Google アカウントを持っていれば、ウェブブラウザで gemini.google.com にアクセスしたり、モバイルデバイス向けアプリをダウンロードすることで利用できます。 詳細は以下の公式ドキュメントや記事をご参照ください。 参考 : Gemini ウェブアプリを利用する 参考 : 全Geminiプロダクトを徹底解説! - G-gen Tech Blog - Gemini アプリ 前提条件 当機能は、以下の特定の Google Workspace エディションまたはアドオンでのみ利用できます。 Business Standard / Plus Enterprise Standard / Plus Gemini Education Education Premium 詳細は以下をご参照ください。 参考 : Upload code folders or import your GitHub repositories directly into the Gemini app 検証手順 検証手順は次のとおりです。 項番 内容 説明 1 パブリックリポジトリをインポートし、コード理解と改善を試行 GitHub リポジトリをインポートし、コードベースの理解や改善提案を Gemini に依頼します。 2 プライベートリポジトリのフォルダをインポートし、デバッグやコード生成を試行 フォルダをアップロードし、生成・デバッグ用途での使い方を確認します。 検証 リポジトリとディレクトリ構成 本検証に使用したリポジトリの構成は以下のとおりです。 # パブリックリポジトリ . ├── README.md └── main.py   # プライベートリポジトリ . ├── README.md └── error └── error.py main.py シンプルな Flask アプリを使用しています。ブラウザに "Hello, World!" を返すだけの最小構成です。 from flask import Flask   app = Flask(__name__)   @ app.route ( "/" ) def hello (): return "Hello, World!"   if __name__ == "__main__" : app.run() error/error.py 意図的に ZeroDivisionError を引き起こすテストコードです。Gemini アプリでのデバッグ用に使用します。 from flask import Flask   app = Flask(__name__)   @ app.route ( "/" ) def home (): return 1 / 0   if __name__ == "__main__" : app.run(debug= True )   パブリックリポジトリのインポート Gemini アプリ( https://gemini.google.com )へアクセスします。 [+(ファイルの追加)] > [コードをインポート] を選択します。 コードをインポートを選択 GitHub リポジトリの URL を入力し、「インポート」を選択します。 インポートの実施 内容を確認し、「接続」を選択します。 GitHub との接続を実施 接続が完了すると、接続した GitHub のリポジトリ情報が表示されます。 インポート確認 コード理解と改善の確認 まずは以下のプロンプトで、リポジトリのコード全体について説明を求めてみます。 このリポジトリのコードについて教えてください リポジトリのコード解説 次に以下のプロンプトで、アプリのセキュリティ改善の提案を依頼してみます。 この Web アプリに対して、セキュリティ上のリスクがあれば指摘し、改善案を提示してください リポジトリのコード改善 プライベートリポジトリのフォルダインポート Gemini アプリの新しいチャットから、再度 [+(ファイルの追加)] > [コードをインポート] を選択します。 [フォルダをアップロード] から、 error フォルダを選択します。 フォルダをアップロード 注意内容を確認し、[アップロード] を選択します。 アップロードを選択 アップロードしたフォルダが表示されていることを確認します。 アップロード確認 デバッグとコード生成の確認 以下のプロンプトで、エラーが出る原因と改善方法を確認します。 このアプリの実行時にエラーが出る理由を教えてください。また、修正方法も教えてください。 原因と改善方法の提示 次に以下のプロンプトで、認証機能を追加するコードを生成できるか確認します。 このアプリに対して、ユーザー名とパスワードでログインできる認証機能を追加したいです。必要なコードを生成して教えてください。 機能追加のためのコード生成 三浦 健斗 (記事一覧) クラウドソリューション部 2023年10月よりG-genにジョイン。元オンプレ中心のネットワークエンジニア。ネットワーク・セキュリティ・唐揚げ・辛いものが好き。
アバター
G-gen の高井(Peacock)です。Cloud Run のサイドカー機能と MailHog を利用し、アプリケーションからのメールを捕捉するダミーの SMTP サーバー環境を構築する方法を紹介します。 はじめに やりたいこと 実現方法 サイドカー機能とは 構成 ソースコード デプロイ 動作確認 はじめに やりたいこと Cloud Run services を使い、メール送信機能があるアプリケーションを開発しているケースを考えます。本番環境のアプリケーションでは SMTP サーバーを利用してメールを送信していますが、開発環境のアプリケーションではメールが外部に送信されないようにしたい場合があります。 当記事では、上記のようなケースにおいて、アプリケーションのコードは極力変更せずに、開発環境のみメールを MailHog で構築したダミー SMTP サーバーで受け取るようにします。 MailHog は、MIT ライセンスのもと配布されているオープンソースソフトウェアです。 参考 : GitHub - mailhog/MailHog 参考 : GitHub - mailhog/MailHog/LICENSE.md 実現方法 当記事では、前述の要件を Cloud Run の サイドカー (Sidecar)機能を利用して実現します。 アプリケーションコンテナのデプロイ時に、MailHog のコンテナをサイドカーとして同時にデプロイします。これにより、2つのコンテナは同一の Cloud Run サービスインスタンス内で起動し、 localhost を通じて通信できます。 アプリケーション側では、接続先 SMTP サーバーのホスト名を localhost に、ポートを MailHog が待機するポート(デフォルトで 1025 )に設定するだけで、メール送信の向き先を MailHog に変更できます。 サイドカー機能とは サイドカー とは、1つの Cloud Run サービスに、複数のコンテナをデプロイできる機能です。 メインのリクエストを処理するコンテナ(Ingress コンテナ)と、それを補助するサイドカーコンテナを組み合わせて使用します。サイドカーのユースケースとして、ログ転送エージェントや、サービスメッシュのプロキシ、そして今回のような補助的なサービスが挙げられます。 サイドカーとしてデプロイされたコンテナは、Ingress コンテナと同じネットワーク名前空間を共有するため、 localhost を使用して相互に通信できます。ただし、外部からの HTTP リクエストは Ingress コンテナのみが受信し、サイドカーコンテナのポートが直接外部に公開されることはありません。 参考 : Cloud Run へのコンテナ イメージのデプロイ - サービスに複数のコンテナをデプロイする(サイドカー) 構成 外部からのリクエストは、ポート 8080 で待機する FastAPI アプリケーションコンテナ(Ingress コンテナ)が受け取ります。 アプリケーションがメールを送信する際は、環境変数で指定された localhost:1025 に接続します。そこでは MailHog コンテナが SMTP サーバーとして待機しており、送信されたメールを捕捉します。 ソースコード まず、メール送信機能を持つ FastAPI アプリケーションを用意します。 重要な点は、SMTP サーバーの接続情報を環境変数( SMTP_HOST 、 SMTP_PORT など)から読み込むように実装することです。これにより、コンテナイメージを再ビルドすることなく、デプロイ時の設定だけで接続先を切り替えられます。 Dockerfile FROM python:3.13-bookworm COPY --from = ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ WORKDIR /app ADD . /app RUN uv sync --locked EXPOSE 8080 CMD [" /app/.venv/bin/fastapi " , " run " , " main.py " , " --host " , " 0.0.0.0 " , " --port " , " 8080 "] main.py from email.message import EmailMessage import smtplib import os from fastapi import FastAPI, HTTPException, Request, Response from pydantic import BaseModel, EmailStr app = FastAPI() # 環境変数からSMTPサーバーの接続情報を取得 SMTP_HOST = os.environ.get( "SMTP_HOST" ) SMTP_PORT = int (os.environ.get( "SMTP_PORT" , 587 )) SMTP_USER = os.environ.get( "SMTP_USER" ) SMTP_PASS = os.environ.get( "SMTP_PASS" ) class EmailModel (BaseModel): from_: EmailStr to: EmailStr subject: str body: str @ app.get ( "/" ) def root (): return { "message" : "ok" } @ app.post ( "/sendmail" ) def sendmail (email: EmailModel): if SMTP_HOST is None : raise HTTPException( status_code= 500 , detail= "SMTP_HOST environment variable is not set" ) # MailHogは認証不要なため、USER/PASSの有無で処理を分岐 if SMTP_USER and SMTP_PASS: server = smtplib.SMTP_SSL(SMTP_HOST, port=SMTP_PORT) server.set_debuglevel( 1 ) server.login(user=SMTP_USER, password=SMTP_PASS) else : server = smtplib.SMTP(SMTP_HOST, port=SMTP_PORT) server.set_debuglevel( 1 ) msg = EmailMessage() msg[ "Subject" ] = email.subject msg[ "From" ] = email.from_ msg[ "To" ] = email.to msg.set_content(email.body) server.send_message(msg) server.close() return { "ok" : True } pyproject.toml [project] name = "etude-mailhog" version = "0.1.0" description = "" readme = "README.md" requires-python = ">=3.13" dependencies = [ "fastapi[standard]>=0.115.12" , ] デプロイ gcloud コマンドで、アプリケーションと MailHog を Cloud Run にデプロイします。 まず、アプリケーションのコンテナイメージを Artifact Registry などにプッシュします。 # Cloud BuildでコンテナイメージをビルドしてArtifact Registryにプッシュ # (事前に gcloud artifacts repositories create ... でリポジトリ作成が必要) gcloud builds submit --tag asia-northeast1-docker.pkg.dev/ $( gcloud config get-value project ) /smtp-mocker/app:1. 0 次に、Cloud Run にサービスをデプロイします。 --container フラグを2つ指定することで、サイドカー構成を定義します。 gcloud run deploy mail-service \ --region asia-northeast1 \ --allow-unauthenticated \ --container " app " \ --image " asia-northeast1-docker.pkg.dev/ $( gcloud config get-value project ) /smtp-mocker/app:1.0 " \ --port 8080 \ --set-env-vars " SMTP_HOST=localhost,SMTP_PORT=1025 " \ --container " mailhog " \ --image " mailhog/mailhog " このコマンドの主要なフラグは以下の通りです。 フラグ 説明 --container "app" Ingress コンテナとなるアプリケーションを定義します。このフラグに続く --port 8080 で待ち受けポートを指定し、 --set-env-vars で SMTP の接続先を localhost:1025 に設定します。 --container "mailhog" サイドカーとなる MailHog コンテナを定義します。Docker Hub の公式イメージ mailhog/mailhog を指定します。 参考 : Docker Hub - mailhog/mailhog 動作確認 デプロイが完了したら、 curl コマンドでアプリケーションの /sendmail エンドポイントを呼び出し、テストメールを送信します。 # Cloud RunサービスのエンドポイントURLを取得 SERVICE_URL = $( gcloud run services describe mail-service --region asia-northeast1 --format ' value(status.url) ' ) # テストメールを送信 curl -X POST " ${SERVICE_URL} /sendmail " \ -H " Content-Type: application/json " \ -d ' { "from_": "from@example.com", "to": "to@example.com", "subject": "Test from Cloud Run", "body": "This is a test mail with a sidecar." } ' このように Cloud Run のサイドカー機能と環境変数を利用することで、アプリケーションコードを変更することなく、環境に応じた柔軟なシステム構成を実現できます。 Peacock (高井 陽一) (記事一覧) クラウドソリューション部 カスタマーサポート課 2022年12月より入社。普段は Google Cloud の技術サポートや Terraform などによる IaC の推進を行なっている。また、プライベートでは PyCon JP 2022, 2023(APAC) にて副座長など、カンファレンスのスタッフとしても活動している。趣味はカメラ・スキー・クラシック音楽など。 Follow @peacock0803sz
アバター
G-gen の山崎です。 当記事では、Cloud Run jobs を使用して Google Drive の差分を検知し、差分ファイルを Cloud Storage にアップロードする方法を解説します。 システム構成 前提知識 環境構築 API の有効化 サービスアカウントの構築 Cloud Run jobs 用サービスアカウントの作成 Cloud Scheduler 用サービスアカウントの作成 Cloud Storage の構築 ページトークン格納用バケットの作成 アップロードファイル格納用バケットの作成 Cloud Run jobs の構築 Artifact Registry の作成 アプリケーションの準備 環境変数の設定 コンテナイメージのビルド Cloud Run jobs のデプロイ Cloud Scheduler の構築 動作確認 Google Drive のフォルダに対して Cloud Run jobs 用サービスアカウントに参照権限を付与 Cloud Run jobs を実行し、現在のページトークンを取得 Google Drive のフォルダに対してファイルを配置し、Cloud Run jobs を実行 補足 : Google Drive Events API システム構成 今回構築したシステム構成は、以下のとおりです。 構成図 Cloud Scheduler を使って定期的に Cloud Run jobs を起動します。 起動した Cloud Run jobs は、以下の流れで前回処理を行った以降に発生した Google Drive の差分を検知し、その差分のファイルを Cloud Storage にアップロードします。 ページトークン取得 差分ファイル情報取得 ファイルアップロード ページトークン更新 ページトークン は、Google Drive API で変更を追跡する際の起点となる識別子です。 このトークンを保存・更新することで、前回処理を実行した時点からの差分のみを効率的に取得できます。 参考 : 変更を取得する 前提知識 今回使用する Google Cloud サービスの詳細は、以下の記事をご参照ください。 Cloud Storage blog.g-gen.co.jp Cloud Run jobs blog.g-gen.co.jp Cloud Scheduler blog.g-gen.co.jp 環境構築 以下の順序で環境を構築しました。 API の有効化 サービスアカウントの構築 Cloud Storage の構築 Cloud Run jobs の構築 Cloud Scheduler の構築 API の有効化 Google Cloud プロジェクトで、今回の構成に必要な Google Cloud サービスの API を有効化します。 gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ cloudscheduler.googleapis.com \ drive.googleapis.com サービスアカウントの構築 Cloud Run jobs、Cloud Scheduler 用のサービスアカウントを作成します。 Cloud Run jobs 用サービスアカウントの作成 Google Cloud コンソールのサービスアカウント画面で、[サービスアカウントを作成] を選択します。 任意のサービスアカウント名を入力し、[作成して続行] を選択します。 作成したサービスアカウントに「Storage オブジェクト管理者( roles/storage.objectAdmin )」「ログ書き込み( roles/logging.logWriter )」の権限を付与して[完了]を選択します。 Cloud Scheduler 用サービスアカウントの作成 再度[サービスアカウントを作成] を選択し、任意のサービスアカウント名の入力を行い、[作成して続行] を選択します。 作成したサービスアカウントに「Cloud Run ジョブ エグゼキュータ( roles/run.jobsExecutor )」の権限を付与して[完了]を選択します。 Cloud Storage の構築 ページトークン格納用、アップロードファイル格納用のバケットを作成します。 ページトークン格納用バケットの作成 Google Cloud コンソールのバケット画面で、[作成] を選択します。 グローバルに一意の名前を入力し、[続行] を選択します。 データの保存場所を選択し、[作成] を選択します。 「このバケットに対する公開アクセス禁止を適用する」にチェックがついていることを確認し、[確認] を選択します。 アップロードファイル格納用バケットの作成 再度バケット画面で、[作成] を選択し、グローバルに一意の名前を入力してアップロードファイル格納用バケットを作成します。(設定内容はページトークン格納用バケットと同様) Cloud Run jobs の構築 Artifact Registry の作成、アプリケーションの準備、環境変数の設定、コンテナイメージのビルド、Cloud Run jobs のデプロイを行います。 Artifact Registry の作成 Google Cloud コンソールのリポジトリ画面で、[リポジトリの作成] を選択します。 任意のリポジトリ名とリージョンを指定し、[作成] を選択します。 アプリケーションの準備 今回開発する Python アプリケーションのディレクトリ構成は以下のとおりです。 drive-to-gcs-demo-app |-- requirements.txt |-- Dockerfile |-- main.py requirements.txt google-api-python-client google-auth google-cloud-storage google-cloud-logging Dockerfile FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY main.py . CMD [ " python ", " main.py " ] main.py import base64 import binascii import io import os import sys import google.auth import google.cloud.logging import logging from googleapiclient.discovery import build from googleapiclient.errors import HttpError from googleapiclient.http import MediaIoBaseDownload from google.cloud import storage from google.api_core import exceptions # --- 環境変数から設定を読み込み --- # アップロード先のGCSバケット名 UPLOAD_BUCKET_NAME = os.environ.get( 'UPLOAD_BUCKET_NAME' ) # pageTokenを保存するためのGCSバケット名(UPLOAD_BUCKET_NAMEと同じでも可) START_BUCKET_NAME = os.environ.get( 'START_BUCKET_NAME' ) # ログの出力レベル LOG_LEVEL = int (os.environ.get( 'LOG_LEVEL' )) # ログレベル debug=10 / info=20 / warning=30 # pageTokenを保存するファイル名 PAGE_TOKEN_FILE = 'drive_page_token.txt' # Cloud Logging クライアントを初期化し、ロギングを設定 client = google.cloud.logging.Client() client.setup_logging() # 標準の logger を取得し、ログレベルを設定 logger = logging.getLogger() logger.setLevel(LOG_LEVEL) # Google Drive APIのスコープ(読み取り専用) DRIVE_SCOPES = [ 'https://www.googleapis.com/auth/drive.readonly' ] def get_drive_service (): """ 実行環境のデフォルト認証情報を取得する """ credentials, _ = google.auth.default(scopes=DRIVE_SCOPES) return build( 'drive' , 'v3' , credentials=credentials) def read_page_token_from_gcs (storage_client: storage.Client) -> str | None : """GCSから前回のpageTokenを読み込む""" try : bucket = storage_client.bucket(START_BUCKET_NAME) blob = bucket.blob(PAGE_TOKEN_FILE) return blob.download_as_text() except exceptions.NotFound: # ファイルが存在しない場合は初回実行とみなし、Noneを返す logger.info(f "'{PAGE_TOKEN_FILE}' not found in GCS. Assuming first run." ) return None except Exception as e: logger.critical( f "CRITICAL: Failed to read page token from GCS due to an unexpected error. " f "This will cause the job to fail. Error: {e}" ) raise def write_page_token_to_gcs (storage_client: storage.Client, token: str ): """次回の実行のために新しいpageTokenをGCSに保存する""" try : bucket = storage_client.bucket(START_BUCKET_NAME) blob = bucket.blob(PAGE_TOKEN_FILE) blob.upload_from_string(token) logger.info(f "Successfully saved new page token to GCS: {token}" ) except Exception as e: logger.critical(f "CRITICAL: Failed to save new page token to GCS. {e}" ) # ここで失敗すると次回実行時に変更が重複する可能性があるため、エラーを明示 raise def stream_drive_file_to_gcs (drive_service, storage_client, drive_file_id, drive_file_name, bucket_name): """ 特定のファイルをDriveからGCSへ、一時ファイルを使わずに直接ストリーミングコピーする """ # GCSのオブジェクトパスとして、Driveのファイル名をそのまま使用する object_path = drive_file_name logger.info(f "--- Starting copy for '{drive_file_name}' ({drive_file_id}) to gs://{bucket_name}/{object_path} ---" ) try : # 1. Google Driveからファイルのメタデータを取得 (サイズ、MIMEタイプ、チェックサム) file_metadata = drive_service.files().get( fileId=drive_file_id, supportsTeamDrives= True , fields= 'size, mimeType, md5Checksum' ).execute() total_size = int (file_metadata.get( 'size' , 0 )) content_type = file_metadata.get( 'mimeType' , 'application/octet-stream' ) source_md5_checksum = file_metadata.get( 'md5Checksum' ) if not source_md5_checksum: logger.warning(f "Warning: MD5 checksum not available for '{drive_file_name}'. Skipping verification." ) # 2. GCSのアップロードストリームを開く bucket = storage_client.bucket(bucket_name) destination_blob = bucket.blob(object_path) with destination_blob.open( 'wb' , content_type=content_type) as gcs_stream: # 3. Driveのダウンローダーを初期化し、GCSストリームに直接接続 request = drive_service.files().get_media(fileId=drive_file_id) downloader = MediaIoBaseDownload(fd=gcs_stream, request=request, chunksize= 10 * 1024 * 1024 ) # 4. ダウンロード(=アップロード)を開始 done = False while not done: status, done = downloader.next_chunk(num_retries= 3 ) if status: logger.info(f " Copy in progress: {int(status.progress() * 100)}%" ) logger.info( " Streaming finished." ) # 5. 整合性チェック (MD5チェックサムが取得できている場合のみ) if source_md5_checksum: destination_blob.reload() # GCSから最新のメタデータを取得 gcs_md5_b64 = destination_blob.md5_hash gcs_md5_hex = binascii.hexlify(base64.b64decode(gcs_md5_b64)).decode( 'utf-8' ) if source_md5_checksum == gcs_md5_hex: logger.info(f " Success! MD5 checksums match for '{drive_file_name}'." ) else : logger.error(f " ERROR: MD5 CHECKSUM MISMATCH for '{drive_file_name}'!" ) raise logger.info(f "--- Successfully copied '{drive_file_name}' ---" ) return True except HttpError as e: # 特にダウンロード権限がない(403)やファイルが見つからない(404)などの場合に発生 logger.error(f "ERROR: An HTTP error occurred while copying '{drive_file_name}': {e}" ) raise except Exception as e: logger.error(f "ERROR: An unexpected error occurred while copying '{drive_file_name}': {e}" ) raise def main (): """ Google Driveの変更を検知してGCSにファイルを同期するメインの処理 """ if not UPLOAD_BUCKET_NAME or not START_BUCKET_NAME or not LOG_LEVEL: logger.error( "Error: Environment variables 'UPLOAD_BUCKET_NAME' and 'START_BUCKET_NAME' and 'LOG_LEVEL' must be set." ) raise ValueError ( "Required environment variables are not set." ) drive_service = get_drive_service() storage_client = storage.Client() # 処理対象と対象外のファイル名を記録するためのリストを初期化 processed_files = [] skipped_files = [] page_token = read_page_token_from_gcs(storage_client) if page_token is None : # 初回実行時は、全ての変更を検知するための最初のトークンを取得する response = drive_service.changes().getStartPageToken().execute() page_token = response.get( 'startPageToken' ) logger.info(f "First run detected. Starting with token: {page_token}" ) logger.info(f "Processing changes starting from page token: {page_token}" ) while page_token is not None : response = drive_service.changes().list( pageToken=page_token, spaces= 'drive' , includeItemsFromAllDrives= True , supportsAllDrives= True , fields= 'nextPageToken, newStartPageToken, changes(fileId, file(id, name, trashed, mimeType))' ).execute() # 取得した差分情報の出力(debug) logger.debug(f "response info: {response}" ) for change in response.get( 'changes' , []): drive_file_id = change.get( 'fileId' ) drive_file_info = change.get( 'file' ) # ファイルが存在し、ゴミ箱になく、かつMIMEタイプが'application/pdf'である場合のみ処理を続行 if drive_file_info and not drive_file_info.get( 'trashed' ) and drive_file_info.get( 'mimeType' ) == 'application/pdf' : drive_file_name = drive_file_info.get( 'name' ) logger.info(f " \n PDF change detected, will process: '{drive_file_name}' (ID: {drive_file_id})" ) # 処理対象リストにファイル名を追加 processed_files.append(drive_file_name) # ストリーミングコピー関数を呼び出す stream_drive_file_to_gcs( drive_service=drive_service, storage_client=storage_client, drive_file_id=drive_file_id, drive_file_name=drive_file_name, bucket_name=UPLOAD_BUCKET_NAME ) else : # 処理対象外のファイルとして記録 if drive_file_info: file_name_to_skip = drive_file_info.get( 'name' , drive_file_id) skipped_files.append(file_name_to_skip) # スキップ理由をログに記録 reason = "" if drive_file_info.get( 'trashed' ): reason = "it is in trash" elif drive_file_info.get( 'mimeType' ) == 'application/vnd.google-apps.folder' : reason = "it is a folder" else : reason = f "its MIME type is not PDF ('{drive_file_info.get('mimeType')}')" logger.info(f "Skipping '{file_name_to_skip}' because {reason}." ) else : # ファイル情報自体がない場合 logger.info(f "Skipping change for file ID {drive_file_id} because file information could not be retrieved." ) # 次のページのトークンがあればループを継続、なければ終了 if 'nextPageToken' in response: page_token = response.get( 'nextPageToken' ) else : # ループ終了。次回の実行のために新しいStartPageTokenを保存 new_start_page_token = response.get( 'newStartPageToken' ) write_page_token_to_gcs(storage_client, new_start_page_token) logger.info( " \n Finished processing all changes." ) page_token = None # すべての処理ループが終わった後で、最終的な結果をINFOレベルでロギング logger.info( "--- Execution Summary ---" ) summary_processed = f "処理対象ファイル:{', '.join(processed_files)}" if processed_files else "処理対象ファイル:なし" summary_skipped = f "処理対象外ファイル:{', '.join(skipped_files)}" if skipped_files else "処理対象外ファイル:なし" logger.info(summary_processed) logger.info(summary_skipped) if __name__ == "__main__" : logger.info( "Cloud Run Job started." ) try : main() logger.info( "Cloud Run Job finished successfully." ) except Exception as e: logger.critical(f "Job failed with a critical error: {e}" , exc_info= True ) sys.exit( 1 ) finally : if 'client' in locals () and client: client.close() 環境変数の設定 以降の手順で繰り返し使用する Google Cloud プロジェクト ID やリージョンなどの情報を環境変数に設定します。 ご自身の環境に合わせて、以下のコマンドで環境変数を設定してください。 # Google Cloud プロジェクト ID export PROJECT_ID = " your-project-id " # プロジェクトのデフォルトリージョン export LOCATION = " asia-northeast1 " # Artifact Registry の名前 export REPO = " my-repo " # Image の名前 export IMAGE = " my-image " # Cloud Run jobs の名前 export JOB_NAME = " my-job " # Cloud Run jobs 用サービスアカウントの名前 export SERVICE_ACCOUNT_NAME = " cloud-run-jobs-sa " # アップロードファイル格納用のバケットの名前 export UPLOAD_BUCKET = " upload-drive-pdf " # ページトークン格納用のバケットの名前 export START_BUCKET = " pagetoken " コンテナイメージのビルド Dockerfile が存在するディレクトリで、以下の gcloud コマンドを実行します。 gcloud builds submit --tag ${LOCATION} -docker.pkg.dev/ ${PROJECT_ID} / ${REPO} / ${IMAGE} :latest Cloud Run jobs のデプロイ 作成したコンテナイメージを使用して、Cloud Run jobs をデプロイします。 gcloud run jobs deploy ${JOB_NAME} \ --image ${LOCATION} -docker.pkg.dev/ ${PROJECT_ID} / ${REPO} / ${IMAGE} :latest \ --region = ${LOCATION} \ --service-account =" ${SERVICE_ACCOUNT_NAME} @ $PROJECT_ID .iam.gserviceaccount.com " \ --set-env-vars =" UPLOAD_BUCKET_NAME= ${UPLOAD_BUCKET} " \ --set-env-vars =" START_BUCKET_NAME= ${START_BUCKET} " \ --set-env-vars =" LOG_LEVEL=20 " \ --tasks = 1 \ --max-retries = 3 \ --task-timeout = 1440m Cloud Scheduler の構築 Google Cloud コンソールのジョブ画面で、作成した Cloud Run jobs を選択します。 ジョブの詳細画面で、[トリガー]を選択し、[スケジューラトリガーを追加]を選択します。 任意の名前、リージョン、頻度、タイムゾーンを指定し、[続行] を選択します。 サービスアカウントに Cloud Scheduler 用サービスアカウントを設定し、[作成] を選択します。 動作確認 以下の順番で動作確認を行います。 Google Drive のフォルダに対して Cloud Run jobs 用サービスアカウントに参照権限を付与 Cloud Run jobs を実行し、現在のページトークンを取得 Google Drive のフォルダに対してファイルを配置し、Cloud Run jobs を実行 Google Drive のフォルダに対して Cloud Run jobs 用サービスアカウントに参照権限を付与 差分検知を行う Google Drive のフォルダ上で、共有アイコンを選択します。 Cloud Run jobs 用サービスアカウントに閲覧者権限を付与し、[共有]を選択します。 Cloud Run jobs を実行し、現在のページトークンを取得 今回は動作確認のため、Cloud Schduler による時刻起動は行わず、Google Cloud コンソールのジョブの詳細画面で、[実行] を選択します。 ページトークン格納用バケットにページトークンを保持するテキストファイルが配置されています。 Google Drive のフォルダに対してファイルを配置し、Cloud Run jobs を実行 差分検知を行う Google Drive のフォルダ上に PDF ファイルを配置します。 再度、Google Cloud コンソールのジョブの詳細画面で、[実行] を選択します。 アップロードファイル格納用のバケットに、Google Drive のフォルダに配置した PDF ファイルが配置されています。 補足 : Google Drive Events API 2025年7月7日に Google Drive Events API が Preview 公開されました。 Google ドライブのファイル変更通知を CloudEvent 仕様に従ってフォーマットされた Pub/Sub メッセージで受け取ることが可能 となるため、より活用の幅が広がることが期待されます。 参考 : Google ドライブのイベントを操作する 山崎 曜 (記事一覧) クラウドソリューション部 元は日系大手SIerにて金融の決済領域のお客様に対して、PM/APエンジニアとして、要件定義〜保守運用まで全工程に従事。 Google Cloud Partner Top Engineer 2025 選出。 Google Cloud 全 13 資格保有。 フルスタックな人材を目指し、日々邁進。 Follow @Akira_Yamasakit
アバター
G-gen の杉村です。 Agent Development Kit (ADK)は、Google Cloud が提供する、AI エージェント開発のためのフレームワークです。当記事では、ADK の中核をなす LLM Agent と Workflow Agents 、および Tools を解説します。 概要 Agent Development Kit(ADK)とは ADK のコンポーネント LLM Agent 概要 実装例 ソースコードの実行 Runner と非同期処理 Workflow Agents 概要 実装例 実行結果 詳細のロギング Tools 概要 関数の記述 要約のスキップ 概要 Agent Development Kit(ADK)とは Agent Development Kit(ADK) は、AI エージェントの開発、デプロイ、評価を効率化するために Google が開発したオープンソースのフレームワークです。2025年7月現在、Python および Java 向けのライブラリとして公開されています。 ADK を利用することで、開発者は通常のソフトウェア開発と同じような感覚で、モジュール化された再利用可能なコンポーネントを組み合わせて AI エージェントを開発できます。ADK は Google の生成 AI モデル Gemini や Vertex AI などのエコシステムに最適化されていますが、特定のモデルやデプロイ環境に依存しない設計思想を持っており、高い柔軟性と拡張性を備えています。 参考 : Agent Development Kit ADK のコンポーネント ADK でアプリを開発する際、以下のようなコンポーネントを記述します。 Agents タスクを実行する主体。LLM の推論能力を活用して自律的に動作する LLM Agent と、事前に定義された手順に従って動作する Workflow Agent がある。 Tools エージェントがタスクをこなすために利用するプログラム等。外部 API の呼び出しや計算、データベース検索など、特定の処理を行う。 参考 : Agents 参考 : Tools LLM Agent 概要 LLM Agent は、LLM の持つ推論能力を利用して、タスクを達成するために思考したり、どの Tool をどの順番で、どのようなパラメータで呼び出すかなどを自律的に判断するエージェントです。 ADK では基本的に、この LLM Agent を組み合わせて AI エージェントアプリケーションを開発しますので、最も基本的なコンポーネントであるといえます。 参考 : LLM Agent 実装例 LLM Agent を定義する際は、主に以下の要素を指定します。 属性 説明 instruction エージェントの役割、振る舞い、タスクの進め方などを自然言語で記述した指示書 model 使用するモデル(gemini-2.5-flash など) tools エージェントが利用可能なツール(道具)。Python の関数や他のエージェントなど 以下は、都市ごとの現在時刻を返す簡単な Tool を持つ LLM Agent の Python サンプルコードです。このエージェントに「東京の天気は?」と質問すると、LLM は get_weather ツールを city="東京" という引数で呼び出すべきだと判断(Reasoning)し、実行します。そして、Tool から返された「晴れです。」という結果(Observation)を元に、最終的な回答を生成します。 import asyncio import datetime from google.adk.agents import LlmAgent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types def get_time (city: str ): ''' # 概要 指定された都市の現在時刻を取得します。 # 引数 city (str): 対象の都市名 (Tokyo / Los Angels / London) ''' print (f "--- Tool: get_weather (city: {city}) ---" ) if "Tokyo" in city: tz = datetime.timezone(datetime.timedelta(hours= 9 )) elif "Los Angels" in city: tz = datetime.timezone(datetime.timedelta(hours=- 7 )) elif "London" in city: tz = datetime.timezone(datetime.timedelta(hours= 0 )) else : tz = None if tz: now = datetime.datetime.now(tz) else : now = None message = { "city" : city, "datetime" : now } return message # LLM Agentの定義 time_agent = LlmAgent( model= "gemini-2.5-flash" , name= "time_agent" , instruction= """ あなたは時刻案内をするエージェントです。 ユーザーから尋ねられた都市の現在時刻を答えてください。 利用可能なツールを使って情報を取得し、最終的な回答を生成してください。 """ , tools=[get_time] ) # runner の定義 APP_NAME = "My Agent App" SESSION_SERVICE = InMemorySessionService() RUNNER = Runner( agent=time_agent, app_name=APP_NAME, session_service=SESSION_SERVICE, ) async def stream_agent_events (query: str , user_id: str , session_id: str ): ''' # 概要 エージェントを実行します。 # 引数 query (str): エージェントに投げかけるクエリ(プロンプト) user_id (str): ユーザー ID session_id (str): セッション ID ''' # 既存セッションがなければ新規作成 session = await SESSION_SERVICE.get_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) if not session: await SESSION_SERVICE.create_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) # ユーザークエリを所定の形式で格納 content = types.Content(role= 'user' , parts=[types.Part(text=query)]) # エージェントの実行 async for event in RUNNER.run_async(user_id=user_id, session_id=session_id, new_message=content): parts = event.content.parts message = event.content.parts[ 0 ].text if message: yield (f "--- Message: {message}" ) return async def main (): """ エージェントを実行し、ストリーミングされたメッセージを出力するメイン関数 """ user_id= "test_user" session_id= "test_session" query= "東京の現在時刻は?" # async for を使って非同期ジェネレータを処理 async for message in stream_agent_events(query=query, user_id=user_id, session_id=session_id): print (message) # スクリプトのエントリーポイント if __name__ == "__main__" : asyncio.run(main()) ソースコードの実行 ADK で記述したエージェントは、以下で紹介されているように、ADK に組み込まれた動作テスト用 Web UI を使って動作確認することができます。 参考 : Quickstart 参考 : ADKのSequential agentsを使って実装するマルチエージェント - G-gen Tech Blog ADK のテスト用 Web UI あるいは、以下の記事のように Vertex AI Agent Engine にデプロイして、リモートから呼び出して実行することもできます。 参考 : Agent Development Kitでエージェントを開発してAgent Engineにデプロイしてみた - G-gen Tech Blog しかし今回の記事では、Cloud Run などにホストされたアプリケーションに組み込むことを想定して、異なる方法で実行します。 まずは、前述のソースコードを main.py として保存します。 実行環境には、 pip install google-adk で ADK をインストールします。必要に応じて venv を用意してください。 さらに、以下のようなコマンドを実行して、環境変数を定義します。これらの環境変数は、ADK が Gemini モデルを呼び出す先の API エンドポイントを決めるのに必要です。 .env ファイルなどに書き込んでおき、実行前に source .env コマンドを実行する方法で変数を定義しても構いません。実際の動作環境では、Cloud Run service のリビジョンに環境変数で定義する想定です。 export GOOGLE_GENAI_USE_VERTEXAI = " TRUE " export GOOGLE_CLOUD_PROJECT = " my-project " export GOOGLE_CLOUD_LOCATION = " global " 上記を実施したうえで main.py を実行すると、以下のように出力されます。 $ python main.py --- Tool: get_weather ( city: Tokyo ) --- --- Message: 東京の現在時刻は 2025 年 7 月 21 日 9 時 36 分です。 Runner と非同期処理 前述のソースコードの関数 stream_agent_events は、 asyncio.run によって非同期実行されています。 asyncio は Python の標準ライブラリであり、並行処理を実現するための機能です。 参考 : Runtime 参考 : Build Your First Intelligent Agent Team: A Progressive Weather Bot with ADK Runner は、エージェントを動かすためのエンジンです。run_async でプロンプトを渡して実行すると、イベントを順次返します。このソースコードでは非同期関数 stream_agent_events の中で Runner を実行しており、エージェントにより生成された結果は yield によって順次、呼び出し元に返されて print されます。 これにより、複数のエージェントによって長い処理が行われる場合でも、処理の進行状況をユーザーに知らせることができます。 Workflow Agents 概要 Workflow Agents は、あらかじめ定義された順番でサブエージェント(子エージェント)を呼び出すためのエージェントです。Workflow Agents の動作は決定論的、つまり事前に定義したとおりに動くものであり、必ず指定した順番でサブエージェントが実行されます。モデルの指定も存在しません。 参考 : Workflow Agents Workflow Agents には以下の種類があります。 名称 説明 Sequential Agents サブエージェントを指定した順番で順次実行 Parallel Agents サブエージェントを並列で実行 Loop Agents サブエージェントを指定した順番で順次実行。指定条件が満たされるまで繰り返す Workflow Agents は、その制御性の高さから以下のようなユースケースに適しています。 顧客からの問い合わせを定型的なプロセスで処理する 例: 内容判断 → チケット起票 → 担当者割り当て 決まった手順で行われるデータ処理やバッチ処理の自動化 ビジネスプロセスオートメーション(BPA) 実装例 サブエージェントを順次実行する Sequential Agents の実装例を以下に示します。 import asyncio import datetime import logging from google.adk.agents import LlmAgent, SequentialAgent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.adk.tools import google_search from google.genai import types def get_time (city: str ): ''' # 概要 指定された都市の現在時刻を取得します。 # 引数 city (str): 対象の都市名 (Tokyo / Los Angels / London) ''' print (f "--- Tool: get_weather (city: {city}) ---" ) if "Tokyo" in city: tz = datetime.timezone(datetime.timedelta(hours= 9 )) elif "Los Angels" in city: tz = datetime.timezone(datetime.timedelta(hours=- 7 )) elif "London" in city: tz = datetime.timezone(datetime.timedelta(hours= 0 )) else : tz = None if tz: now = datetime.datetime.now(tz) else : now = None message = { "city" : city, "datetime" : now } return message # 時刻案内エージェント time_agent = LlmAgent( model= "gemini-2.5-flash" , name= "time_agent" , instruction= """ あなたは時刻案内をするエージェントです。 tools を使ってユーザーが住んでいる都市の現在時刻を取得します。 """ , tools=[get_time], output_key = "city_and_datetime" ) # 雑学エージェント trivia_agent = LlmAgent( model= "gemini-2.5-flash" , name= "time_agent" , instruction= """ # 役割 あなたは雑学を披露するエージェントです。 ユーザーが住んでいる国にとって、今日がなんの日か(その国の祝日、記念日など)を調べて回答します。 どうしても特別な日でないときは、最も近い祝日や記念日などを返してください。 # ユーザーが住んでいる国と日付 {city_and_datetime} """ , tools=[google_search] ) # シーケンシャルエージェント root_agent = SequentialAgent( name= "root_agent" , sub_agents=[time_agent, trivia_agent], description= "本日日付を取得し、次にその日に関する雑学を披露する" , ) # runner の定義 APP_NAME = "My Agent App" SESSION_SERVICE = InMemorySessionService() RUNNER = Runner( agent=root_agent, app_name=APP_NAME, session_service=SESSION_SERVICE, ) async def stream_agent_events (query: str , user_id: str , session_id: str ): ''' # 概要 エージェントを実行します。 # 引数 query (str): エージェントに投げかけるクエリ(プロンプト) user_id (str): ユーザー ID session_id (str): セッション ID ''' # 既存セッションがなければ新規作成 session = await SESSION_SERVICE.get_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) if not session: await SESSION_SERVICE.create_session(app_name=APP_NAME, user_id=user_id, session_id=session_id) # ユーザークエリを所定の形式で格納 content = types.Content(role= 'user' , parts=[types.Part(text=query)]) # エージェントの実行 async for event in RUNNER.run_async(user_id=user_id, session_id=session_id, new_message=content): parts = event.content.parts message = event.content.parts[ 0 ].text if message: yield (f "--- Message: {message}" ) return async def main (): """ エージェントを実行し、ストリーミングされたメッセージを出力するメイン関数 """ user_id= "test_user" session_id= "test_session" query= "私は東京在住です。" # async for を使って非同期ジェネレータを処理 async for message in stream_agent_events(query=query, user_id=user_id, session_id=session_id): print (message) # # ロギングを設定(必要に応じてコメントを外す) # logging.basicConfig( # level=logging.DEBUG, # format='%(asctime)s - %(levelname)s - %(name)s - %(message)s' # ) # スクリプトのエントリーポイント if __name__ == "__main__" : asyncio.run(main()) 実行結果 出力は以下のようになります。 $ python sequential.py --- Tool: get_weather ( city: Tokyo ) --- --- Message: 現在の時刻は、 2025 年 7 月 21 日 9 時 40 分です。 --- Message: 東京にお住まいのあなたにとって、 2025 年 7 月 21 日は「海の日」です。 海の日とは、海の恩恵に感謝し、海洋国家である日本の繁栄を願う国民の祝日です。 毎年 7 月の第 3 月曜日と定められており、 2025 年は 7 月 21 日がこれに当たります。 世界で唯一、「海の日」を国民の祝日としているのは日本だけです。 time_agent と trivia_agent の情報の受け渡しに使われている output_key については、以下の記事も参照してください。 参考 : ADKのSequential agentsを使って実装するマルチエージェント - G-gen Tech Blog 詳細のロギング 前述のソースコード内でコメントアウトしているロギング設定の行から # を削除してコメントでなくすると、ADK の処理の詳細が標準出力に出力されます。エージェントがどのような順番で呼び出され、またどのようなプロンプトで呼び出されたのかがわかるため、デバッグやチューニングのときに役立ちます。 以下は、一部を省略していますが、詳細なロギング出力の結果です。 2025-07-21 01:11:24,627 - DEBUG - asyncio - Using selector: EpollSelector 2025-07-21 01:11:24,926 - INFO - google_adk.google.adk.models.google_llm - Sending out request, model: gemini-2.5-flash, backend: GoogleLLMVariant.VERTEX_AI, stream: False 2025-07-21 01:11:24,926 - INFO - google_adk.google.adk.models.google_llm - LLM Request: ----------------------------------------------------------- System Instruction: あなたは時刻案内をするエージェントです。 tools を使ってユーザーが住んでいる都市の現在時刻を取得します。 You are an agent. Your internal name is "time_agent". ----------------------------------------------------------- Contents: {"parts":[{"text":"私は東京在住です。"}],"role":"user"} ----------------------------------------------------------- Functions: get_time: {'city': {'type': <Type.STRING: 'STRING'>}} ----------------------------------------------------------- 〜〜〜〜〜(略)〜〜〜〜〜 --- Tool: get_weather (city: Tokyo) --- 2025-07-21 01:11:27,100 - INFO - google_adk.google.adk.models.google_llm - Sending out request, model: gemini-2.5-flash, backend: GoogleLLMVariant.VERTEX_AI, stream: False 2025-07-21 01:11:27,101 - INFO - google_adk.google.adk.models.google_llm - LLM Request: ----------------------------------------------------------- System Instruction: あなたは時刻案内をするエージェントです。 tools を使ってユーザーが住んでいる都市の現在時刻を取得します。 You are an agent. Your internal name is "time_agent". ----------------------------------------------------------- Contents: {"parts":[{"text":"私は東京在住です。"}],"role":"user"} {"parts":[{"function_call":{"args":{"city":"Tokyo"},"name":"get_time"}}],"role":"model"} {"parts":[{"function_response":{"name":"get_time","response":{"city":"Tokyo","datetime":"2025-07-21T10:11:26.994246+09:00"}}}],"role":"user"} ----------------------------------------------------------- Functions: get_time: {'city': {'type': <Type.STRING: 'STRING'>}} ----------------------------------------------------------- 〜〜〜〜〜(略)〜〜〜〜〜 LLM Request: ----------------------------------------------------------- System Instruction: # 役割 あなたは雑学を披露するエージェントです。 ユーザーが住んでいる国にとって、今日がなんの日か(その国の祝日、記念日など)を調べて回答します。 どうしても特別な日でないときは、最も近い祝日や記念日などを返してください。 # ユーザーが住んでいる国と日付 東京の現在時刻は2025-07-21T10:11:26.994246+09:00です。 You are an agent. Your internal name is "time_agent". ----------------------------------------------------------- Contents: {"parts":[{"text":"私は東京在住です。"}],"role":"user"} {"parts":[{"function_call":{"args":{"city":"Tokyo"},"name":"get_time"}}],"role":"model"} {"parts":[{"function_response":{"name":"get_time","response":{"city":"Tokyo","datetime":"2025-07-21T10:11:26.994246+09:00"}}}],"role":"user"} {"parts":[{"text":"東京の現在時刻は2025-07-21T10:11:26.994246+09:00です。"}],"role":"model"} {"parts":[{"text":"Continue processing previous requests as instructed. Exit or provide a summary if no more outputs are needed."}],"role":"user"} ----------------------------------------------------------- Functions: ----------------------------------------------------------- シーケンシャルにエージェントが呼び出されており、またシステムインストラクションに指定した output_key である {city_and_datetime} が正しく反映されていることもわかります。 Tools 概要 Tools は、LLM Agent が道具として使うプログラムです。Tools には以下のような種類があります。 名称 説明 Function tools コーディングされた関数を実行する。外部処理を呼び出したり、計算処理を行わせる等。また Agent-as-a-Tool ではエージェントから他のエージェントを tool として呼び出し可能。 Build-in tools ADK に組み込みの Tool。Google 検索実行ツール、コード生成・実行ツール、Vertex AI Search での検索実行ツール、BigQuery ツールなど。例えば自然言語の指示に基づいて BigQuery へクエリするといった処理を、コードを書くことなく実現できる。 Third party tools CrewAI や LangChain などで定義された Tools を実行。 Google Cloud tools Apigee API Hub、Application Integration、MCP Toolbox for Database などを呼び出し。 MCP tools エージェントから MCP server を呼び出し。 LLM Agent は Tools を呼び出すかどうか、またどういったパラメータで呼び出すかを自律的に判断し、実行します。これにより、ADK アプリケーションは LLM が持つ能力を超えて、さまざまなタスクを行うことができます。 参考 : Tools 関数の記述 LLM が適切に Tools を呼び出すためには、例えば Function tools においては、適切な方法で関数を記述することが重要です。 参考 : Function tools - Best Practices わかりやすい関数名、引数名、Tool 名 LLM が適切に判断して Tools を呼び出すためには、関数名や引数名、Tool 名などを、LLM が理解しやすい 明確でわかりやすい名称 にする必要があります。一般的すぎる名称は避け、例えばその関数が何をするものなのか明確になるよう、 動詞_目的語() のような名称とします。 Docstring を記述する 関数の Docstring (関数の説明)を適切に記載することが重要です。LLM はこれらを読み取り、Tools を呼び出すべきかどうか、またどのような引数を与えるべきかを判断します。 引数はシンプルに Tools の関数の引数は少なめに、シンプルにします。複雑すぎると、LLM が関数を適切に使用できません。また、データ型もカスタムのものより str や int などシンプルなものが望ましいです。 戻り値は辞書型 Tools の実行結果を LLM が適切に使用できるよう、 戻り値のフォーマット も重要です。Python においては辞書型(dictionary)、Java においては Map 型で返すのが理想的です。 要約のスキップ 先程の2つのサンプルソースコードでは、簡単な Function tools を使って現在時刻を取得しました。 通常、Function tools 等が実行されると、tool の実行結果は LLM に渡され、LLM はそれを解釈して最終回答を生成します。しかし、例えば tool の実行結果をそのままユーザーに返したい場合や、あるいは処理時間短縮のために tool の実行結果を LLM に解釈させずに次のエージェントに渡したいケースもあります。 その場合、 要約をスキップ させることで、LLM による解釈をスキップして tool の実行結果をそのまま LLM Agent の最終回答とさせることができます。 先程の Sequential agents のサンプルコードの tool 関数定義を、以下のように修正します。変更点は、ToolContext を import した点と、関数の引数に tool_context: ToolContext を追加した点、また tool_context.actions.skip_summarization = True を追加した点です。 # 〜〜〜〜〜(略)〜〜〜〜〜 from google.adk.tools import google_search, ToolContext # 〜〜〜〜〜(略)〜〜〜〜〜 def get_time (city: str , tool_context: ToolContext): ''' # 概要 指定された都市の現在時刻を取得します。 # 引数 city (str): 対象の都市名 (Tokyo / Los Angels / London) ''' # ツールの結果は要約されずそのままアウトプットとして扱われる tool_context.actions.skip_summarization = True print (f "--- Tool: get_weather (city: {city}) ---" ) if "Tokyo" in city: tz = datetime.timezone(datetime.timedelta(hours= 9 )) elif "Los Angels" in city: tz = datetime.timezone(datetime.timedelta(hours=- 7 )) elif "London" in city: tz = datetime.timezone(datetime.timedelta(hours= 0 )) else : tz = None if tz: now = datetime.datetime.now(tz) else : now = None message = { "city" : city, "datetime" : now } return message これにより、関数が return した結果は LLM によって解釈されず、そのまま time_agent の最終回答として、次のエージェントに渡されます。 しかしこのとき、ロギングを詳細に出力していると、次に実行されたエージェント trivia_agent のシステムインストラクションで、output_key が反映されていないことに気が付きます。詳細ログは以下のようになりました。 ----------------------------------------------------------- System Instruction: # 役割 あなたは雑学を披露するエージェントです。 ユーザーが住んでいる国にとって、今日がなんの日か(その国の祝日、記念日など)を調べて回答します。 どうしても特別な日でないときは、最も近い祝日や記念日などを返してください。 # ユーザーが住んでいる国と日付 You are an agent. Your internal name is "time_agent". ----------------------------------------------------------- # ユーザーが住んでいる国と日付 の下には、本来 {city_and_datetime} があるため、tool が返した辞書型のデータ( city と datetime )が入っているべきです。しかし、要約をスキップした場合は、output_key が次のエージェントに渡されません。これは、output_key に値が代入されるのは LLM による最終回答生成後であるためであると考えられます。要約をスキップした場合は output_key に値が入りません。 しかしこのような状況でも、エージェント trivia_agent は以下のような回答を生成しました。 東京にお住まいのあなたにとって、2025年7月21日は「海の日」です。海の日とは、「海の恩恵に感謝するとともに、海洋国日本の繁栄を願う日」として制定された国民の祝日です。 この日は毎年7月の第3月曜日と定められており、2025年は7月21日がこれに当たります。 また、海の日以外にも、7月21日には「日本三景の日」、「神前結婚記念日」、「自然公園の日」、「烏骨鶏の日」といった様々な記念日があります。 これは、LLM Agent は output_key で情報を渡されなくても、これまで実行された LLM Agent や Tools の実行結果をコンテキストとして保持しており、そのコンテキストに基づいて生成を行っているためであると考えられます。詳細ロギングを確認すると、trivia_agent の実行時に以下のようなログが出力されていました。 2025-07-21 01:35:40,257 - INFO - google_adk.google.adk.models.google_llm - LLM Request: ----------------------------------------------------------- System Instruction: # 役割 あなたは雑学を披露するエージェントです。 ユーザーが住んでいる国にとって、今日がなんの日か(その国の祝日、記念日など)を調べて回答します。 どうしても特別な日でないときは、最も近い祝日や記念日などを返してください。 # ユーザーが住んでいる国と日付 You are an agent. Your internal name is "time_agent". ----------------------------------------------------------- Contents: {"parts":[{"text":"私は東京在住です。"}],"role":"user"} {"parts":[{"function_call":{"args":{"city":"Tokyo"},"name":"get_time"}}],"role":"model"} {"parts":[{"function_response":{"name":"get_time","response":{"city":"Tokyo","datetime":"2025-07-21T10:35:40.174769+09:00"}}}],"role":"user"} ----------------------------------------------------------- Functions: ----------------------------------------------------------- Contents: のブロックの中にある function_response という行が、関数の実行結果です。 # ユーザーが住んでいる国と日付 の直下にあるべき output_key は空文字列になっているものの、Contents として含まれている情報を LLM Agent がコンテキストとして使って生成を行っていることがわかります。output_key を使ったほうが、より複雑なプロンプトで役割やタスク、背景、フォーマットを指定する際に効果的であると考えられますが、output_key を使わなくても、ある程度の精度で他のエージェントや tools の出力結果がコンテキストとして使われることがわかります。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-genの山田です。BigQueryの保存済みクエリ機能を使うと、クエリエディタで記述した SQL を保存して他のユーザーと共有することができます。SQL をプロジェクトにアップロードしようとした際に [プロジェクトにアップロードする] > [SQL クエリ] のメニューがグレーアウトして選択できない事象が起きました。この事象の原因と対処法を解説します。 事象 原因 対処法 概要 Dataform API の有効化 IAM ロールが正しく設定されていること クエリの移行 事象 BigQuery のコンソール画面でクエリエディタを開き、SQL クエリをプロジェクトにアップロードしようとしたところ、以下の図のように [プロジェクトにアップロードする] > [SQL クエリ] のメニューがグレーアウトし、選択できない状態でした。 原因 原因は、BigQuery の保存済みクエリの仕様変更にあります。 従来の保存済みクエリは、 Dataform を基盤とした新しい保存済みクエリへ移行される予定です。これは、2025年2月と6月に Google Cloud から「Transition from classic saved queries to new saved queries」という件名のメールで案内されています。この新しい保存済みクエリを利用するには、対象プロジェクトで Dataform API を有効化し、ユーザーに適切な IAM 権限 を付与する必要があります。 今回の事象は、この Dataform API が有効になっていなかったために発生しました。 2025年6月現在、2025年3月に予定されていた移行は延期されており、サポート終了時期は公開されていません。2025年末までに新たな情報が更新される予定です。 参考 : 保存済みクエリの概要 - 従来の保存したクエリ 対処法 概要 新しい保存済みクエリを使用するには以下の条件を満たしている必要があります。 Dataform API の有効化 IAM ロールが正しく設定されていること Dataform API の有効化 SQL クエリをアップロードしたいプロジェクトで Dataform API が有効になっていることを確認します。Google Cloud コンソールで [API とサービス] > [ライブラリ] へ移動し、「Dataform API」を検索して有効化してください。 参考 : Dataform で SQL ワークフローを作成して実行する - 始める前に IAM ロールが正しく設定されていること 新しい保存済みクエリの閲覧や編集には、適切な IAM ロールが必要です。クエリは Dataform のリソースとして保存されるため、Dataform 関連の権限が付与されているか確認してください。 BigQuery の新しい保存済みクエリを操作するには、操作者アカウントがプロジェクトに対して以下の IAM ロールを持っている必要があります。 操作内容 必要なIAMロール(いずれか一つ) クエリの作成 BigQuery ジョブユーザー( roles/bigquery.jobUser ) コード作成者 ( roles/dataform.codeCreator ) クエリの編集 BigQuery ジョブユーザー( roles/bigquery.jobUser ) コード編集者( roles/dataform.codeEditor ) クエリの表示 BigQuery ジョブユーザー( roles/bigquery.jobUser ) コード閲覧者( roles/dataform.codeViewer ) 参考 : 保存済みクエリを作成する - 必要な権限 クエリの移行 従来の保存済みクエリは、以下の公式ドキュメントを参考に、新しい保存済みクエリに移行することができます。2025年6月現在では、従来の保存済みクエリの廃止時期は未定ですが、早めの移行が推奨されます。 参考 : 保存済みクエリを管理する - 従来の保存済みクエリを移行する 山田 剛史 (記事一覧) クラウドソリューション部 クラウドサポート課 2025年6月にG-genに入社。IT基盤領域やグループウェアが得意。Google Workspace や Google Cloud を日々勉強中。
アバター
G-genの福井です。Cloud Storage バケットへのアクセスを送信元 IP アドレスに基づいて制御する IP フィルタリング機能の概要と設定方法、そして VPC Service Controls との違いについて解説します。 はじめに Cloud Storage の IP フィルタリングとは 機能の概要 ユースケース VPC Service Controls との違い 機能比較 使い分けのポイント 制限事項 設定方法 前提条件 必要な権限 IP フィルタリング設定用 JSON バケット作成時にフィルタリング設定 既存バケットにフィルタリング設定 フィルタリング ルールを取得 フィルタリング ルールを無効化 IPフィルタリングのバイパス設定 概要 ユースケース 設定方法 運用の注意点 はじめに Cloud Storage は、高い耐久性とスケーラビリティを持つオブジェクトストレージサービスであり、その用途は多岐にわたります。様々なネットワーク環境からアクセスが可能であるため、意図しないリクエストを防ぐためのアクセス制御が重要です。 Google Cloud は IAM や VPC Service Controls といった多様なセキュリティ機能を提供しています。その中でも、送信元のパブリック IP アドレスに基づいてアクセスをシンプルに制御したい、という要件に応えるのが当記事で解説する IP アドレスフィルタリング機能 です。 当記事では、IP アドレスフィルタリング機能の概要から、類似機能である VPC Service Controls との違い、使用上の注意点、そして具体的な設定手順までを解説します。 Cloud Storage の IP フィルタリングとは 機能の概要 Cloud Storage の IP フィルタリングは、バケットへのアクセスを 送信元の IP アドレスに基づいて制御する 機能です。 この機能を有効にすると、許可設定した IP アドレスからのリクエストのみが許可されます。許可設定していない IP アドレスからのリクエストは、ステータスコード 403 Forbidden で拒否されます。 このフィルタリングは、バケット単位で設定し、そのバケット内の全オブジェクトに適用されます。制御できるアクセス元は以下の通りです。 アクセス元の種類 説明 パブリック IP インターネット経由でのアクセスを、送信元のグローバル IP アドレスで制御します。 VPC ネットワーク VPC ネットワーク内からのアクセスを、その VPC ネットワークで予約された IP アドレスで制御します。 この機能の重要な点は、Cloud Storage の認証システムの前に評価されることです。つまり、たとえ有効な認証情報を持っていたとしても、許可されていない IP アドレスからのリクエストはバケットに到達する前にブロックされます。 参考 : IP アドレス フィルタリングの概要 ユースケース この機能は、特定のネットワーク環境からのアクセスのみに制限したい場合に有効です。 ユースケース 説明 特定の拠点からのアクセス制限 本社や支社のオフィス、あるいは特定のデータセンターの固定 IP アドレスからのみ、バケットへのアクセスを許可したい場合に使用します。 特定のアプリケーション環境からのアクセス制限 Google Cloud の VPC ネットワーク内で稼働するアプリケーションからのアクセスのみに限定したい場合に使用します。これにより、意図しない他のリソースからのアクセスをネットワークレベルで防ぐことができます。 多層的なセキュリティの実現 IAM による認証・認可に加え、ネットワークレベルでのアクセス制御を組み合わせることで、認証情報が万が一漏洩した際の情報流出リスクを低減し、より強固なセキュリティを実現します。 VPC Service Controls との違い Cloud Storage へのアクセスをネットワークレベルで制御する機能として、IP アドレスフィルタリングの他に VPC Service Controls があります。両者は似ているようで、その目的と機能は大きく異なります。 機能比較 特徴 IP アドレスフィルタリング VPC Service Controls 目的 送信元 IP に基づくシンプルなアクセス制御 サービス境界(Perimeter)を作成し、境界の外から中へのアクセスを防いだり、逆に境界の中から外へのデータ流出等を防ぐ 適用範囲 Cloud Storage のバケット単位 単一または複数のプロジェクトをサービス境界に含めることが可能。組織レベルでのデータガバナンスを実現する 主な制御要素 送信元のパブリック IP または VPC 送信元のネットワークロケーション(VPC, オンプレミス)、ID、デバイスなど、複数のコンテキスト 設定の複雑さ シンプル 。許可したい IP のリストを定義するのみ 高度 。サービス境界、アクセスレベル、ブリッジなどの設計が必要 使い分けのポイント どちらの機能を選択するかは、セキュリティ要件によって決まります。 セキュリティ要件 推奨される機能 「特定のオフィスの固定 IP からのみアクセスさせたい」など、要件が シンプル な場合 IP アドレスフィルタリング IP アドレスだけでなく、ユーザー ID やデバイス情報なども含めた 多角的なアクセス制御 が必要な場合 VPC Service Controls Cloud Storage だけでなく、BigQuery など他のサービスも含めて、組織として データ持ち出しを厳密に防ぎたい 場合 VPC Service Controls 基本的には、特定の IP アドレスからのアクセスをシンプルに制限したい場合は IP アドレスフィルタリングを、より広範で強力なデータ保護境界を構築したい場合は VPC Service Controls を選択します。 blog.g-gen.co.jp 制限事項 IP アドレスフィルタリング機能には、使用する上で制限があります。 制限事項 内容 許可される IP CIDR ブロックの最大数 パブリックネットワークと VPC ネットワークを合わせて、最大 200 個の IP CIDR ブロックを指定できます。 許可される VPC ネットワークの最大数 最大 25 個 の VPC ネットワークを指定できます。 リージョンエンドポイントのサポート リージョンエンドポイントは、Private Service Connect を使用する場合にのみサポートされます。 一部 Google Cloud サービスとの連携 BigQuery のように、データのインポート/エクスポートで Cloud Storage を使用するサービスからのアクセスが制限されます。サービスの中断を避けるため、これらのサービスがアクセスするバケットでは IP フィルタリングの使用は推奨されません。 App Engine からのアプリケーション App Engine アプリケーションが Cloud Storage のデータにアクセスする場合は、VPC を介して使用することが推奨されます。 Cloud Shell のサポート Cloud Shell からのアクセスはサポートされていません。 参考 : 制限事項 設定方法 ここからは、実際に IP アドレスフィルタリング機能を設定する手順を解説します。 2025年7月現在、Google Cloud コンソールからの設定には対応していません。 当記事では gcloud コマンドを使った手順を紹介します。 前提条件 IP フィルタリングの設定には、Google Cloud CLI バージョン 526.0.0 以降が必要です。古いバージョンの CLI を使用して、IP フィルタリングの設定を行うと、以下のエラーが発生します。 Found invalid JSON/YAML for the IP filter rule. エラーが発生した場合は、以下のコマンドでバージョンを確認し、必要に応じて更新してください。 # バージョン確認 gcloud version | head -n 1 # バージョン更新 gcloud components update --version = 526 . 0 . 0 必要な権限 IP アドレスフィルタリングの設定には、以下のIAM権限が必要です。 操作 権限 IP フィルタリング ルールを使用してバケットを作成 storage.buckets.create storage.buckets.setIpFilter バケットの IP フィルタリング ルールを更新 storage.buckets.update storage.buckets.setIpFilter バケットの IP フィルタリング ルールを取得 storage.buckets.get storage.buckets.getIpFilter バケット IP フィルタリングを無効 storage.buckets.update storage.buckets.setIpFilter これらの権限を取得する最も簡単な方法は、対象プロジェクトまたはバケットに対して ストレージ管理者 ( roles/storage.admin )のロールを付与することです。この事前定義ロールには、上記の権限が含まれています。また、これらの権限を持つカスタムロールを個別に作成することも可能です。 IP フィルタリング設定用 JSON IP フィルタリングの設定は、バケットの新規作成時、または既存のバケットに対して行います。いずれのシナリオでも、設定内容を記述した JSON ファイルをコマンドで読み込ませて設定します。 特定のパブリック IP 範囲 指定したパブリック IPv4 アドレス範囲からのアクセスを許可し、VPC からのアクセスをブロックする設定です。 { " mode ": " Enabled ", " publicNetworkSource ": { " allowedIpCidrRanges ": [ " 192.0.2.0/24 " ] } , " allowCrossOrgVpcs ": false , " allowAllServiceAgentAccess ": false } 特定の VPC ネットワーク範囲 指定した VPC の IPv4 アドレスからのアクセスを許可し、パブリック IP からのアクセスをブロックする設定です。 { " mode ": " Enabled ", " vpcNetworkSources ": [ { " network ": " projects/[PROJECT_ID]/global/networks/[NETWORK_NAME] ", " allowedIpCidrRanges ": [ " 192.0.2.0/24 " ] } , ] , " allowCrossOrgVpcs ": false , " allowAllServiceAgentAccess ": false } 設定項目の解説 項目 説明 mode フィルタリングのモードを指定します。 Enabled : IP フィルタリングを有効にし、設定されたルールに基づいてリクエストを評価します。 Disabled : フィルタリングを無効にし、すべてのリクエストを許可します(ルールは保持されます)。 publicNetworkSource パブリック IP アドレスからのアクセスに関するルールを定義するオブジェクトです。 allowedIpCidrRanges バケットへのアクセスを許可するパブリックな IPv4 または IPv6 の CIDR 範囲のリストです。(例: ["192.0.2.0/24", "2001:db8::/32"] ) vpcNetworkSources VPC ネットワークからのアクセスに関するルールを定義するオブジェクトのリストです。 network VPC ネットワークの名前です。 PROJECT_ID は、VPC ネットワークが存在するプロジェクト ID NETWORK_NAME は、バケットへのアクセスを許可する VPC ネットワークの名前 allowCrossOrgVpcs 組織(Organization)をまたいだ VPC ネットワークからのアクセスを許可するかどうかを指定します。 true : 組織をまたいだアクセスを許可します。 false : バケットと同じ組織内の VPC に限定します。(デフォルト) allowAllServiceAgentAccess Google Cloud のサービスエージェントからのアクセスを、IP フィルタリングの設定に関わらずすべて許可するかどうかを指定します。 true : 他の Google Cloud サービスがサービスエージェントを使ってバケットにアクセスすることを許可します。 false : 許可しません。 参考 : Create a bucket with IP filtering rules - Bucket IP filtering configurations バケット作成時にフィルタリング設定 gcloud alpha storage buckets create gs:// [ BUCKET_NAME ] --ip-filter-file =[ IP_FILTER_CONFIG_FILE ] BUCKET_NAME には新規に作成するバケット名、 IP_FILTER_CONFIG_FILE にはIPフィルタリング設定用JSONのファイルパスを指定します。 参考 : IP フィルタリング ルールのあるバケットを作成する 既存バケットにフィルタリング設定 gcloud alpha storage buckets update gs:// [ BUCKET_NAME ] --ip-filter-file =[ IP_FILTER_CONFIG_FILE ] BUCKET_NAME には IP フィルタリングを設定するバケット名、 IP_FILTER_CONFIG_FILE にはIPフィルタリング設定用JSONのファイルパスを指定します。 参考 : 既存のバケットで IP フィルタリング ルールを作成または更新する フィルタリング ルールを取得 gcloud alpha storage buckets describe gs:// [ BUCKET_NAME ] --format =" default(ip_filter_config) " BUCKET_NAME には IP フィルタリングを取得するバケット名を指定します。 参考 : バケット IP フィルタリング ルールを取得する フィルタリング ルールを無効化 gcloud alpha storage buckets update gs:// [ BUCKET_NAME ] --clear-ip-filter BUCKET_NAME には IP フィルタリングを無効にするバケット名を指定します。 参考 : バケット IP フィルタリング ルールを無効にする IPフィルタリングのバイパス設定 概要 Cloud Storage の IP アドレスフィルタリングにおいて バイパス設定 を行うと、特定の IAM プリンシパル(ユーザー、サービスアカウントなど)は、 送信元 IP アドレスに関わらず 、バケットの作成、削除、構成に関する IP フィルタリング制限の対象から除外されます。 ユースケース ユースケース 説明 バケット ロックアウト IP フィルタリングの設定を誤って追加し、バケットにアクセスできなくなった場合 予期しない IP 変更 ネットワークの変更により IP アドレスが予期せず変更され、ロックアウトされた場合 設定方法 IAM 権限 storage.buckets.exemptFromIpFilter をプリンシパルに付与します。この権限はカスタムロールを使用して権限を付与します。 カスタムロールの作成 gcloud iam roles create ip_filter_bypasser \ --project =[ PROJECT_ID ] \ --title =" Custom IP Filter Bypasser " \ --description =" Cloud Storage IPフィルタリングをバイパスする " \ --permissions = storage.buckets.exemptFromIpFilter PROJECT_ID には、Google Cloud プロジェクト ID を指定します。 IAM ポリシーへのバインディング 作成したカスタムロールを対象のプリンシパル(この例ではユーザーアカウント)に付与します。 gcloud projects add-iam-policy-binding [ PROJECT_ID ] \ --member =" user:[USER_EMAIL] " \ --role =" projects/[PROJECT_ID]/roles/ip_filter_bypasser " PROJECT_ID には、Google Cloud プロジェクト ID、 USER_EMAIL には、カスタムロールを付与するユーザーのメールアドレスを指定します。 運用の注意点 storage.buckets.exemptFromIpFilter 権限は非常に強力です。この権限を持つプリンシパルの認証情報が漏洩した場合、IP フィルタリングによる保護が無効化されてしまいます。 使用にあたっては 最小権限の原則 を遵守し、本当に必要なプリンシパルにのみ、必要最小限の期間だけ付与するようにしてください。恒久的な権限としてではなく、 Privileged Access Manager(PAM) を使用して、期間限定で付与する運用が理想的です。 参考 : IP フィルタリング ルールをバイパスする 参考 : Privileged Access Manager(PAM)を解説! 福井 達也 (記事一覧) カスタマーサクセス課 エンジニア 2024年2月 G-gen JOIN 元はアプリケーションエンジニア(インフラはAWS)として、PM/PL・上流工程を担当。G-genのGoogle Cloudへの熱量、Google Cloudの魅力を味わいながら日々精進
アバター