🤖

Antigravity で飼い慣らす!BigQuery 分析自動化エージェント オーケストレーション

に公開

Ho-ho-ho! Mario です。

Google Cloud Experts Advent Calendar 2025 Day 24 の記事です。

データ分析にお悩みの方向けに、AIエージェント「Antigravity」と「BigQuery」を組み合わせることで、データ抽出から分析、そしてレポート作成までを一気通貫で自動化する手法の紹介をします。
また、ADK にちょっとハードルを感じている方にも、Antigravity を使うことによってエージェント オーケストレーションの構築も容易になるんだよってことをお伝えしていきます。

最近は BigQuery に対して自然言語で問い合わせてデータ分析を行うこともできるようになってきましたが、分析設計や評価、レポート生成などを行おうとすると、独自に ADK で構築する必要があり、慣れていない方にとってはハードルが高かったように思います。

この記事を読むことで、ADK をもっと身近に感じてもらえると嬉しいです。


1. はじめに:なぜ「分析レポート自動生成」なのか

データ分析における「説明・レポート作成」のコスト

データ分析の現場では、SQLを書いて集計値を取得する時間以上に、「その数字が何を意味するか」を解釈し、他者に伝わる形にまとめる時間が多くかかります。
グラフ作成、要約文の執筆、考察の追加……これらは非常に重要ですが、定型的な作業も多く、分析者の負荷を高める要因となっています。

ADK と BigQuery を組み合わせる意義

ADK では単にチャットで答える LLM 機能だけでなく、ツール(Tool)を使用して外部システムを操作できる AIエージェントも作れます。
BigQuery と連携させることで、以下のようなワークフローが実現します。

  1. 問いを投げる: 例「先月の売上傾向を知りたい」
  2. SQL生成・実行: エージェントがテーブル構造を理解し、クエリを書いて実行
  3. 結果の解釈: 返ってきたデータを読み取り、傾向を分析
  4. レポート化: 「背景・結果・考察」の構成で文章化

人間は「何を分析したいか(What)」に集中し、「どうやってデータを出すか(How)」と「どうまとめるか」を AI に任せる。これが本記事の狙いです。

本記事で何ができるようになるか

  • Antigravity エージェントを使って BigQuery の公開データを分析できる
  • 自然言語だけで SQL を生成・実行し、エラー修正まで自動化するやり方がわかる
  • 分析結果を元に、そのまま報告に使える品質のレポートを生成できる

2. 実装するシステムの全体像

分析対象データ

Google が一般公開している Google Analytics 4 (GA4) のEコマースサンプルデータを使用します。

  • データセット: bigquery-public-data.ga4_obfuscated_sample_ecommerce
  • 内容: Google ブランドの商品を販売する EC サイトGoogle Merchandise Store の、2020 年 11 月 1 日から 2021 年 1 月 31 日までの 3 か月間の難読化した BigQuery イベント エクスポート データのサンプル。

プロジェクト構成

単一のスクリプトではなく、役割ごとにエージェントをモジュール化し、それらをメインのワークフローが統括する構成を採用しました。

dev/
├── workflow.py            # オーケストレーター(全体の指揮役)
├── bq_client.py           # BigQuery接続用クライアント
├── agents/                # 各専門エージェントの定義
│   ├── planner.py         # 計画立案エージェント
│   ├── sql_generator.py   # SQL生成エージェント
│   ├── data_analyst.py    # データ分析エージェント
│   ├── chart_generator.py # グラフ生成エージェント
│   └── reporter.py        # レポート執筆エージェント
└── requirements.txt       # 依存ライブラリ(google-adk, xhtml2pdf等)

今回構築したシステムは、こちらのリポジトリに置いておきます。

各コンポーネントの役割

このシステムは、workflow.py を実行するだけで、以下の5つのエージェントが連携してレポートを完成させます。

  1. Planner (planner.py):
    • ユーザーの曖昧な依頼(例:「売れ行きの悪い商品の対策を考えて」)を噛み砕き、具体的な分析手順(「下位10商品を特定」「販売タイミングを分析」など)に変換します。
  2. SQL Generator (sql_generator.py):
    • Planner の計画に基づき、BigQuery のスキーマ(テーブル定義)に適合する正確な SQL クエリを生成します。
  3. System Execution:
    • (エージェントではありませんが重要なステップ)
    • 生成された SQL を自動実行し、結果を CSV データとして取得します。ここでエラーが出ても自動修復を試みます。
  4. Data Analyst (data_analyst.py):
    • 取得した生データ(CSV)を読み込み、ビジネス的な洞察(「週末の深夜に売上が集中している」「この商品は認知不足の可能性がある」など)を抽出します。
  5. Chart Generator (chart_generator.py):
    • データの特徴に合わせて、可視化に最適なグラフ(棒グラフ、折れ線グラフなど)を Python (Seaborn/Matplotlib) で自動生成し、画像ファイルとして保存します。
  6. Reporter (reporter.py):
    • ユーザーの依頼、SQL、分析結果、グラフ画像を統合し、最終的なレポート(Markdown および PDF)を執筆・出力します。

エージェントオーケストレーションの流れ

今回は、単一のエージェントではなく、役割分担された複数のエージェントが連携するワークフローを構築しました。各エージェントは独立して動作しますが、workflow.py がバケツリレーのように情報を渡していくことで、一気通貫の自動化を実現しています。

詳細な処理フロー図(Mermaid)

この一連の流れを Python スクリプトでオーケストレーションすることで、ワンクリックでレポート生成まで完了します。
このアーキテクチャにより、例えば「グラフのデザインだけ変えたい」場合は chart_generator.py を、「レポートの口調を変えたい」場合は reporter.py を修正するだけで済み、保守性が高いのが特徴です。

3. 事前準備

必要なGoogle Cloud環境

本ハンズオンを進めるには以下が必要です。

  • Google Cloud プロジェクト(課金有効化済み)
    • bigquery-public-data へのクエリには料金が発生しますが、サンドボックス環境や無料枠の範囲内でも少量なら試せます(今回はスキャン量が少ないクエリを心がけます)。
  • BigQuery API の有効化
  • Vertex AI API の有効化(エージェントの頭脳として Gemini モデルを使用するため)

Searvice Account の用意

以下のロールを付与したサービスアカウントを用意します。(環境により別の権限が必要となる場合があります)

  • BigQuery Job User(ジョブ実行のため)
  • Vertex AI User(Gemini モデル利用のため)

BigQuery公開データセットの概要

使用する bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_* は、日次でテーブルが分かれているシャーディングテーブルです(例: events_20210131)。

今回分析に使うテーブルとカラムの簡単な説明

主に以下のカラムに注目します。

  • event_name: イベント名(session_start, view_item, purchase など)
  • traffic_source.source: 流入元(google, direct, t.co など)
  • traffic_source.medium: メディア(organic, referral, cpc など)
  • ecommerce.purchase_revenue: 購入金額

4. オーケストレーションの構築過程

執筆時点ではプロンプトを調整しながら構築していきましたが、おそらく以下のプロンプトでも再現度高く一発で今回のシステムが構築できると思います。

# BigQuery Analysis Multi-Agent System Reproduction Prompt

You are an expert AI Architect. Your task is to reproduce a multi-agent system for BigQuery analysis and report generation in Python. The system orchestrates multiple specialized agents (Planner, SQL Generator, Data Analyst, Chart Generator, Reporter) to answer user questions using Google's Agent Development Kit (ADK).

## Project Goal
Build a Python-based CLI application that accepts a natural language query, analyzes data from Google BigQuery (specifically `bigquery-public-data.ga4_obfuscated_sample_ecommerce`), and produces a professional PDF report containing the analysis, SQL query, insights, and a visualization chart.

## Technology Stack
- **Language**: Python 3.12+
- **Agent Framework**: `google-adk` (using `LlmAgent`, `FunctionTool`, `InMemoryRunner`)
- **LLM**: Google Gemini (`google-genai`, `gemini-2.5-flash`)
- **Data Analysis**: `google-cloud-bigquery`, `pandas`
- **Visualization**: `matplotlib`, `seaborn`
- **Reporting**: `markdown` (MD to HTML), `xhtml2pdf` (HTML to PDF)
- **Environment**: `python-dotenv`

## Directory Structure
Create the following file structure:
- `dev/`
  - `agents/`: Contains individual agent definitions.
    - `planner.py`
    - `sql_generator.py`
    - `data_analyst.py`
    - `chart_generator.py`
    - `reporter.py`
  - `workflow.py`: Main orchestration script.
  - `bq_client.py`: BigQuery client helper.
  - `requirements.txt`: Project dependencies.

## Implementation Details

### 1. Requirements (`requirements.txt`)
Include the following libraries:
  google-cloud-bigquery
  pandas
  python-dotenv
  google-genai
  google-cloud-aiplatform
  google-adk
  markdown
  xhtml2pdf
  matplotlib
  seaborn

### 2. BigQuery Client (`dev/bq_client.py`)
Create a helper function `get_bq_client()` that returns an authenticated `bigquery.Client`. It should handle `ADC` (Application Default Credentials) or Service Account credentials if provided via environment variables.

### 3. Agent Definitions (`dev/agents/*.py`)
Each agent file should expose a `create_<agent_name>_agent(model_name)` function returning an `LlmAgent`.
*   **Planner (`planner.py`)**: breakdowns complex user requests into extraction plans.
*   **SQL Generator (`sql_generator.py`)**: Writes BigQuery Standard SQL based on the plan.
*   **Data Analyst (`data_analyst.py`)**: Analyzes CSV data returned from BigQuery and extracts insights.
*   **Chart Generator (`chart_generator.py`)**:
    *   Tool: `generate_chart(data_csv, chart_type, x_col, y_col, filename, hue_col, title)`
    *   Logic: Uses `seaborn` to plots Bar, Line, or Scatter charts and saves to PNG.
    *   Robustness: Handle empty DataFrames gracefully.
*   **Reporter (`reporter.py`)**: Compiles all outputs (User Query, SQL, Data Summary, Insights, Chart Path) into a formatted Markdown report.

### 4. Workflow Orchestration (`dev/workflow.py`)
This is the core script. Implement `main()` with the following logic:
1.  **Setup**: Load `.env`, set `GOOGLE_GENAI_USE_VERTEXAI='1'`, create `Report/` directory.
2.  **Sequential Execution**:
    *   **Step 1 (Planner)**: Run Planner Agent with user request.
    *   **Step 2 (SQL Gen)**: Run SQL Generator with the plan.
    *   **Step 3 (Execute)**: Execute the generated SQL using `bq_client` (System step, not agent). Save result as CSV string.
    *   **Step 4 (Analyst)**: Run Data Analyst with CSV data.
    *   **Step 4.5 (Chart)**: Run Chart Generator (or use a manual fallback script if data volume is high) to create `Report/sales_chart.png`.
    *   **Step 5 (Reporter)**: Run Reporter Agent to generate final Markdown text including the chart image `![Chart](absolute/path/to/chart.png)`.
3.  **Output Generation**:
    *   Save Markdown to `Report/report_YYYYMMDD_HHMMSS.md`.
    *   **PDF Generation**: Implement `save_as_pdf(markdown_text, filename)`:
        *   Convert Markdown to HTML using `markdown`.
        *   Apply **Custom CSS** for PDF:
            *   Set Page Size to A4 with **3cm margins**.
            *   Font: Use **Meiryo** or **Arial Unicode MS** for Japanese support. Attempt to look for these system fonts; if missing, consider downloading `IPAexGothic`.
            *   Styling: `word-wrap: break-word`, `table { width: 100% }`, `img { width: 80% }`.
        *   Use `xhtml2pdf.pisa.CreatePDF` to generate the PDF directly (do not save intermediate HTML).

## Important Constraints
*   **Japanese Support**: The system must support Japanese text in both input/output and PDF compilation (requiring correct font configuration).
*   **Robustness**: Agents should handle potential errors (e.g., empty data).
*   **Deterministic Paths**: Use absolute paths for chart images to ensure the PDF engine finds them.


試行①:エージェントに最初に与えるプロンプト

ある程度土台が構築できたら、まずは「データセットの中身が見えているか」を確認するだけのプロンプトを送ります。

プロンプト例:

あなたはデータ分析アシスタントです。
Google Cloudのプロジェクト`YOUR_PROJECT_ID`を使用します。

以下の公開データセットにあるテーブルのスキーマ情報を取得して、
どのようなカラムがあるか教えてください。

データセット: bigquery-public-data.ga4_obfuscated_sample_ecommerce
対象テーブル(例): events_20210131

ポイント:

  • プロジェクトIDYOUR_PROJECT_IDを明示する(クエリ実行時の課金プロジェクトとして必要)。
  • 具体的なテーブル名を1つ指定する(ワイルドカードで全テーブルを見ると時間がかかるため)。
  • 「スキーマ情報を取得して」と指示することで、いきなり SELECT * をして大量データを読み込むのを防ぐ。

試行②:エージェントに分析設計をさせる

環境確認ができたら、実際の分析タスクを投げます。
「とりあえず分析して」のような曖昧な指示よりも、**「目的」「期間」「見たい指標」**を明確に伝えると、より精度の高い SQL が生成されます。
また、いきなりSQLを書かせるのではなく、まずは「どのような分析ができそうか?」をエージェントに壁打ち相手になってもらうのも有効です。

プロンプト例(分析の提案を求める場合):

ECサイトの売上要因を特定したいと考えています。
ga4_obfuscated_sample_ecommerce データセットのカラム定義に基づき、
分析すべき「切り口(Dimension)」と「指標(Metric)」の組み合わせ案を3つ提案してください。

これに対して、エージェントは「流入元別のCVR分析」「曜日・時間帯別の購入傾向」「商品カテゴリ別の閲覧・購入率」などを提案してくれます。
そこから良さそうなものを選んで、次のステップ(具体的な指示)に進みます。

試行③:日本語で分析目的を与える

次に「流入チャネルごとの売上貢献度」を分析してみます。

プロンプト例:

2021年1月のデータ(events_202101*)を使用してください。
流入元(traffic_source.source)とメディア(traffic_source.medium)の組み合わせごとに、以下の指標を集計してください。

1. セッション数(ユニークユーザー数で代用可)
2. 購入完了数(event_name = 'purchase')
3. コンバージョン率(CVR)
4. 総売上(purchase_revenue の合計)

売上の多い順にトップ10を表示してください。

指標・期間・切り口の指定方法

  • 期間: _TABLE_SUFFIX を使うか、テーブル明示指定かを意識させる(今回はワイルドカード指定 events_202101* を推奨)。
  • 指標: GA4 は user_pseudo_id でユニークユーザーを数えるのが一般的です。
  • 切り口: sourcemedium はセットで見ることが多いです。

試行④:BigQueryでクエリを実行し結果を確認する

実際に生成されるSQL例:
Antigravity は、プロンプトとスキーマ情報を元にクエリを生成して実行します。例えば試行③の例では以下のようなクエリが生成されました。
(GA4特有の event_params のネスト構造などもよしなに処理してくれる場合が多いですが、複雑な場合は修正を指示します)

SELECT
  traffic_source.source,
  traffic_source.medium,
  COUNT(DISTINCT user_pseudo_id) AS users,
  COUNTIF(event_name = 'purchase') AS purchases,
  safe_divide(COUNTIF(event_name = 'purchase'), COUNT(DISTINCT user_pseudo_id)) AS cvr,
  SUM(ecommerce.purchase_revenue) AS total_revenue
FROM
  `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_202101*`
GROUP BY
  1, 2
ORDER BY
  total_revenue DESC
LIMIT 10

クエリ実行結果の読み取り:
実行が成功すると、Antigravity は以下のような JSON 形式の結果を受け取ります。

source medium users purchases cvr total_revenue
(direct) (none) 12000 250 0.02 15000.0
google organic 8000 120 0.015 8000.0
... ... ... ... ... ...

数値の妥当性をチェックする観点
ここで「数字が出たからOK」とせず、**「CVR 2% は妥当か?」「Revenue が NULL になっていないか?」**などをエージェントに確認させると良いでしょう。
「CVRが高すぎる/低すぎる気がするけど、計算式は合ってる?」と問いかけると、COUNT の分母分子の定義を再確認してくれます。

試行⑤:分析結果をレポート文章に変換する

データが得られたら、いよいよレポート作成です。
エンジニア視点ではなく、ビジネスユーザー(マーケティング担当など)が読んで分かる言葉に変換するよう指示します。

エージェントへのレポート生成プロンプト例

プロンプト例:

先ほどの集計結果をもとに、マーケティング担当者向けの分析レポートを作成してください。
以下の構成で書いてください。

1. **サマリ**: もっとも売り上げに貢献しているチャネルはどこか。
2. **詳細**: direct, organic, referral などのチャネルごとの特徴。CVRの違いについても言及すること。
3. **ネクストアクション提案**: データを元に、今後どこに予算を投下すべきか、または改善すべき点はどこか。

専門用語(source/mediumなど)はなるべく「流入元」「メディア」などの日本語を使い、平易な表現にしてください。

非エンジニア向けの説明文生成
ここで重要なのは、**「数字の羅列」ではなく「意味の抽出」**です。
Antigravity は LLM の能力を使って、「Direct(直接流入)からの購入が過半数を占めており、ロイヤリティの高いユーザーが多いと推測されます」といった定性的な解釈を加えてくれます。

傾向・示唆・注意点の書き分け

  • 傾向: データから読み取れる客観的事実(「Google検索からの流入は多いがCVRが低い」)
  • 示唆: そこから考えられること(「購買意欲の低い層まで広く集客できている可能性がある」)
  • 注意点: データの制約(「今回は1月のみのデータなので季節要因を含む可能性がある」)

これらを書き分けるよう指示すると、レポートの信頼性がグッと上がります。

試行⑥:レポートの出力形式を整える

最後に、出力されたテキストをそのまま共有できる形に整形します。
「Markdown形式で出力して」と指示すれば、見出しや箇条書きを使った読みやすいフォーマットで返してくれます。

Markdown形式での整形
以下のような指示を加えると、よりドキュメントらしくなります。

  • 「タイトルを付けてください」
  • 「重要な数値は太字にしてください」
  • 「3行程度の要約(Executive Summary)を冒頭に入れてください」

見出し・箇条書き・要約の工夫
Antigravity は対話の履歴を覚えているので、「さっきのレポート、ちょっと長すぎるから要約して」や「もっと詳細な表を追加して」といった修正指示も簡単です。
最終的に出力された Markdown テキストをコピーして、Qiita や Zenn、社内 Wiki に貼り付けたり、PDF を共有すれば完了です。

5. 実際に使って分かったこと

Antigravityを用いた分析の良い点

  • 初動が爆速: テーブル定義を調べて SELECT * して...という下準備が不要。
  • シンタックスエラーとおさらば: SQL のカンマ忘れや型不一致のエラーが出ても、エージェントが勝手に直して再実行してくれる。
  • 文脈理解: 「CVR」と書くだけで purchases / users のことだと理解してくれる。

うまくいかなかった点・注意点

  • コスト管理: SELECT * は避けるように言っても、たまにスキャン量の多いクエリを書こうとすることがあります。「スキャン量が1GBを超える場合は実行前に許可を求めて」とシステムプロンプト(または最初の指示)に入れておくと安全(かも)。
  • ハルシネーション: 非常に稀ですが、存在しないカラムを使おうとすることがあります。必ず実行前にSQLを確認するか、エラー後の自動修正を見守る必要がある。

人間が介在すべきポイント

「どんな課題を見つけたいか(要件定義)」と「出てきた数字がビジネス的に正しいか(検算・解釈)」は人間が責任を持つべきです。
SQLを書く作業は AI に任せられますが、**「なぜその数字を出す(した)のか」**というストーリー作りは人間の仕事です。

6. 応用アイデア

定期レポート自動生成への応用

プロンプトをテンプレート化しておけば、「先月のデータで同じレポートを作って」と言うだけで毎月の定例作業が終わります。

別データセットへの展開

今回は GA4 データでしたが、売上DB、ログDB、気象データなど、BigQuery にあるデータなら何でも同じ手順で分析可能です。

チームや教育用途での活用可能性

SQL に不慣れな新卒メンバーやマーケターでも、Antigravity を介すことで擬似的にデータ分析が可能になります。「どんなクエリを書いたの?」とエージェントに聞いて学習することもできます。

7. まとめ

Avtigravity × BigQuery を組み合わせることで、データ分析のボトルネックだった**「SQL作成」と「レポート文章化」**のコストを劇的に下げることができます。

これからのデータ分析は、「複雑なSQLを書けるスキル」よりも、**「適切な問いを立て、AIエージェントに的確な指示を出すスキル」**が重要になってくるでしょう。
ぜひ、お手元の BigQuery 環境で、あなただけの「AIデータアナリスト」を育ててみてください。

※ 本記事は 2025年12月時点の情報に基づいています。Antigravity や Google Cloud の仕様変更にご注意ください。

それでは皆さん、よいお年を!

Discussion