[GWSStudio100本ノック] BigQueryにある売上情報をChatからさらに深堀するエージェントを作成してみた

 2025.12.13 Yudai Imai

はじめに

本記事は、Google Workspace Studio(旧Flows)の実践ノウハウを100本紹介する連載「Google Workspace Studio活用方法100本ノック」の一つとなります。  

今回は、以前ご紹介した「BigQueryにある売上情報を分析した定期レポートをChatに連携するエージェントを作成してみた」をさらに拡張し、Google Chatから特定のキーワードで質問すれば、その場でBigQueryに対して追加クエリを実行し、深堀り結果を返してくれるインタラクティブな仕組みを作ります。定期レポートに加えて、気になる数字をChat上で即確認できるため、営業会議中の突発的な質問にも迅速に対応できます。BigQueryへのSQLクエリの実行処理はGoogle Apps Script(GAS)で実装し、Workspace Studioから呼び出す構成とします。GASの具体的な作り方は別の番外編記事で詳しく解説しますので、併せてご参照ください。

GASの作り方はこちらのリンクから確認してください。今回のブログを実現するにはこのGASの作成とWorkspace Studioへのインストールを先んじて実施しておく必要があるため、番外編のブログを先に実施しておいてください。

難易度 上級者向け
実現すること Chatで特定のコマンドを送ると、BigQueryの売上データに対してSQLを実行し、要約結果を返信くれるようになるため、速度感をもって分析を実施することができる
想定する対象者 営業企画・BI担当・営業マネージャーで、会議中に追加の数字をすぐ知りたい人
利用サービス Google Chat, BigQuery, Google Apps Script

ユースケース

今回作成するエージェントの代表的なユースケースとしては以下のようなことが考えられると思います。

  • 営業会議での追加分析
    • Chatで「売上調査依頼」などの特定の文言を入力すると、BigQueryから最新の売上ランクを取得し、そのまま会議中に共有することができます。
  • 地域別の動向を即確認
    • 対象地域の前月比やトレンドグラフ(テキストサマリー)を生成し、マネージャーが判断材料を得られるようになります。
  • 予実差分の追跡
    • 想定売上と実績との差をその場で照会し、必要に応じて追加のクエリを投げて深堀りが可能に。Slackへの転送やDocs出力にも派生することも可能です。

前提条件

今回のエージェントを作成するための前提条件は以下となります。Google Workspace Studioは2025年12月時点ではそれまではFlowsという名前で提供されていたサービスからリネームされたサービスかつまだ提供されて間もないため、このブログの内容が最新ではなくなる可能性があることをご了承ください。
  • 利用環境:Google Workspace Studioにアクセスできるユーザーであること。
  • 利用アプリ:BigQueryに接続するための権限が必要となります。そして、通知先のGoogle Chatスペース(またはDM)が事前に用意されていること。Google Apps Scriptが作成できる環境が存在しており、番外編のGASの構築とWorkspace Studioへのインストールが完了していること。
  • 社内ルール:情報管理ルールを確認済みであること。

エージェントの全体図

今回作成したエージェントは7ステップの少し複雑な構成となっています。

スターターとして「When I get a chat message」を設定し、特定のスペースで特定の文言が入った投稿を検知したタイミングでエージェントが起動します。

続くアクションでは、まず「Ask Gemini」ステップでBigQueryに存在している売上情報のテーブルに対して実行するSQLを発行し、その結果を「Decide」ステップで正しいSQL構文となっているかの判定処理を実行します。そして、「Check if」ステップで正しいSQL構文であることを確認してから、GASで構築した「Run SQL Query」ステップでSQLを実行し、さらに「Ask Gemini」ステップでSQLの実行結果をもとにしたインサイトを生成し、「Post in a space」ステップで分析結果を連携するような作りとなっています。

構築手順

今回作成したエージェントの構築手順は以下のようになっています。

Starter

Starterで「When I get a chat message」を選択します、そして、Spacesには「営業部」、Message hasには特定の文言を検知するようにしたいため「売上調査依頼」を入力し、それ以外の項目はデフォルトのままとしました。

Actions

最初のActionsでは「Ask Gemini」を選択します。Enter a promptの欄には以下のプロンプトを入力してください。[]で囲まれている内容はVariablesから設定するようにしてください。Sources Gemini can useはデフォルトの「Web, Workspace, and connected apps」のままとします。本当はAsk Gemにしたいと考えていたのですがどうしてもSQLの生成がうまくできなかったので、Ask Geminiで実装しました。

あなたはGoogle BigQueryのエキスパートであり、コスト意識の高いデータエンジニアです。
ユーザーの自然言語の質問を、以下のテーブルに対する最適化されたSQLクエリ(標準SQL)に変換してください。

**対象テーブル:**
`bigquery-public-data.iowa_liquor_sales.sales`

**スキーマ情報:**
- 時間軸: `date` (DATE型)
- 売上金額: `sale_dollars` (FLOAT64) ※唯一の売上指標
- 数量: `bottles_sold` (INT64) / `volume_sold_liters` (FLOAT64)
- 場所: `city`, `county`, `zip_code`, `store_name`
- 商品: `category_name`, `item_description`, `vendor_name`

**生成ルール(違反時は解雇):**
1. **期間フィルタ:** 期間指定がない場合は `date >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 YEAR)` 等で直近データに絞ること。全期間スキャン禁止。
2. **集計必須:** 明細出力(SELECT *)禁止。必ずGROUP BYと集計関数(SUM等)を使用すること。
3. **行数制限:** 必ず `LIMIT 100` を付与すること。
4. **安全性の確保:** `SELECT` 文のみ許可。SQL文の末尾は必ずセミコロン ; で終わらせてください。それ以降の文字は一切生成しないでください。更新・削除系は禁止。

**出力フォーマット(厳守):**
- **SQL文のRawテキストのみ**を出力してください。
- Markdownコードブロック(```sql ... ```)は**使用禁止**です。
- 会話、解説、注釈は一切含めないでください。システムエラーの原因になります。

**ユーザーの質問:**
[Step1: Message text]


**テーブルのDDL情報:**
CREATE TABLE `bigquery-public-data.iowa_liquor_sales.sales`
(
 invoice_and_item_number STRING OPTIONS(description="Concatenated invoice and line number associated with the liquor order. This provides a unique identifier for the individual liquor products included in the store order."),
 date DATE OPTIONS(description="Date of order"),
 store_number STRING OPTIONS(description="Unique number assigned to the store who ordered the liquor."),
 store_name STRING OPTIONS(description="Name of store who ordered the liquor."),
 address STRING OPTIONS(description="Address of store who ordered the liquor."),
 city STRING OPTIONS(description="City where the store who ordered the liquor is located"),
 zip_code STRING OPTIONS(description="Zip code where the store who ordered the liquor is located"),
 store_location GEOGRAPHY OPTIONS(description="Location of store who ordered the liquor. The Address, City, State and Zip Code are geocoded to provide geographic coordinates. Accuracy of geocoding is dependent on how well the address is interpreted and the completeness of the reference data used."),
 county_number STRING OPTIONS(description="Iowa county number for the county where store who ordered the liquor is located"),
 county STRING OPTIONS(description="County where the store who ordered the liquor is located"),
 category STRING OPTIONS(description="Category code associated with the liquor ordered"),
 category_name STRING OPTIONS(description="Category of the liquor ordered."),
 vendor_number STRING OPTIONS(description="The vendor number of the company for the brand of liquor ordered"),
 vendor_name STRING OPTIONS(description="The vendor name of the company for the brand of liquor ordered"),
 item_number STRING OPTIONS(description="Item number for the individual liquor product ordered."),
 item_description STRING OPTIONS(description="Description of the individual liquor product ordered."),
 pack INT64 OPTIONS(description="The number of bottles in a case for the liquor ordered"),
 bottle_volume_ml INT64 OPTIONS(description="Volume of each liquor bottle ordered in milliliters."),
 state_bottle_cost FLOAT64 OPTIONS(description="The amount that Alcoholic Beverages Division paid for each bottle of liquor ordered"),
 state_bottle_retail FLOAT64 OPTIONS(description="The amount the store paid for each bottle of liquor ordered"),
 bottles_sold INT64 OPTIONS(description="The number of bottles of liquor ordered by the store"),
 sale_dollars FLOAT64 OPTIONS(description="Total cost of liquor order (number of bottles multiplied by the state bottle retail)"),
 volume_sold_liters FLOAT64 OPTIONS(description="Total volume of liquor ordered in liters. (i.e. (Bottle Volume (ml) x Bottles Sold)/1,000)\""),
 volume_sold_gallons FLOAT64 OPTIONS(description="Total volume of liquor ordered in gallons. (i.e. (Bottle Volume (ml) x Bottles Sold)/3785.411784)\"")
)
OPTIONS(
 description="Sales Dataset"
);

次のDecideステップでは、Step1で生成するSQLの構文が基準を満たしているかどうかを確認する処理としています。Enter a promptの欄には以下のプロンプトを入力してください。[]で囲まれている内容はVariablesから設定するようにしてください。

あなたはGoogle BigQuery用のSQLバリデータ(判定機)です。
入力されたテキストが、以下の「承認基準」をすべて満たしているかを厳密に判定してください。

# 承認基準
1. コマンド制限: `SELECT` 文のみ許可(`WITH`句は可)。`UPDATE`, `DELETE`, `DROP`, `GRANT`, `EXECUTE` 等は即座に拒否。
2. 安全装置: `LIMIT` 句が必ず含まれていること。
3. 純粋性: SQLコード以外のテキスト(Markdown、会話文)が含まれていないこと。

# 出力形式
- すべての基準を満たす場合: TRUE
- ひとつでも基準を満たさない場合: FALSE

# 判定対象テキスト
[Step2: Content created by Gemini]

次のCheck ifステップではStep3の判定結果を確認します。以下の画像のようにStep3: Decisionがis trueという設定になっていることを確認してください。

次のRun SQL Queryステップでは、GASからインストールした独自のステップを実行する必要があります。ステップの中からBigQuery Runnerの欄にあるRun SQL Queryを選択してください。そして、SQL Queryの欄にVariablesから「Step2: Content created by Gemini」を設定してください。

そして、SQLを実行した後の内容をもとにした分析結果を生成するステップとなる「Ask Gemini」のステップを作成します。Enter a promptの欄には以下のプロンプトを入力してください。[]で囲まれている内容はVariablesから設定するようにしてください。

あなたは、データに基づき意思決定を支援するプロフェッショナルなBIアナリストです。
ユーザーの質問に対し、提供された「データ取得結果」を用いて、簡潔かつ洞察に満ちた回答を作成してください。

**入力変数:**
- **ユーザーの質問:** ​[Step1: Message text]
- **処理ステータス:** ​[Step5: Execution status]
- **取得データ:** ​[Step5: Query results in JSON format]

**回答生成ルール:**

**ケース1:処理ステータスが失敗の場合**
- 以下の定型文のみを出力し、終了してください。
  「申し訳ありません。現在データの取得処理に一時的な問題が発生しています。しばらく時間をおいてから、再度お試しください。」

**ケース2:処理ステータスが成功だが、取得データが空("[]" や 空白)の場合**
- 以下のトーンで回答してください。
  「条件に一致するデータは見つかりませんでした。指定された期間や都市名などの条件を変更して、再度ご質問いただけますか?」

**ケース3:処理ステータスが成功かつ、有効なデータがある場合**
- 以下の構成で回答を作成してください。
  1. **結論:** 質問に対する直接的な答え(数値や傾向)を最初に述べる。
  2. **詳細:** 必要に応じてMarkdownの表形式で上位のデータを提示する。
  3. **洞察:** データから読み取れる特筆すべき傾向(急増、突出した数値など)を一言添える。
- 注意: JSONの生データやSQL文は絶対にユーザーに見せないこと。自然な日本語で説明すること。

最後のPost in a spaceステップでは、ここまでのステップの結果を返すようにします。Spaceには受け取ったChatのスペースへ返信するため、VariablesからStep1:Space IDを設定します。MessageにはVariablesからStep6: Content created by Geminiを設定します。

実行テスト

作成したエージェントを有効化します。エージェントの下部に存在している「Turn on」のボタンを押してエージェントを有効化します。

そして、営業部のChatスペースで売り上げの調査依頼を出してみます。Chatに「売上調査依頼。2025年10月と2025年9月の売上変動額が最も大きかったのはBLACK HAWK郡だった。売上が良かった製品の内訳を知りたいので調査してください。」と入力してみました。

そうすると1分くらいで以下回答が出てきました。まだ不安定のため回答が出てこないこともありますが、プロンプトの調整をすることで改良していくことができると考えています。

まとめ

定期レポートだけでは見えない突発的な分析ニーズに応えるには、Chatから直接データを深堀りできる仕組みが有効です。Workspace StudioとBigQueryを組み合わせて、キーワードに応じたSQLを実行し、Geminiで読みやすい要約に整えて返すことで、営業チームが気になる数字をその場で確認できるようになりました。

将来的な展望としてはコマンドのバリエーションを増やしたり、権限管理・ログ記録を組み込むことで、さらに安全で便利な「対話型データ分析エージェント」へ進化させていきましょう。


BACK TO LIST

   

Recent post最新記事

Contentsコンテンツ