FURYU Tech Blog - フリュー株式会社

フリュー株式会社の開発者が技術情報を発信するブログです。

【GCP】Vertex AI × Gemini × BigQueryでレポーティング自動化

みなさまこんにちは。
プリ・ピクトリンクのデータ分析業務をしている堀江です。

データ分析チームは毎週・毎月、事業のKPIレポートを作成して全体に発信しているのですが、プロのめんどくさがり屋の私としては「見るデータは毎回ほぼ同じだし、作るのもそれなりに手間だし、もうAIがやってくんないかな〜」と思っていたので、実際に試してみました。

GCPのサービスを使ってシンプルな構成で実現できたので、今回は仕組みや工夫したポイント、やってみた感想を紹介します。

最終成果イメージ

最初に、最終成果の例を載せておきます。
事業のKPIに関する数値をもとにAIに分析してもらい、最終的に以下のようなレポートになるよう目指しました。中身の数値や内容はダミーです。

2025年6月分 月次レポート

皆さんお疲れ様です!6月の利用状況を共有します。
今月は新規ユーザー数が好調だった一方、継続率に課題が見られました。

【全体サマリー】
・利用者数:12,340人(前月比 +3.2%、前年比 +8.5%)
・新規登録者数:1,230人(前月比 +6.5%、前年比 +14.7%)
・離脱者数:842人(前月比 -2.1%、前年比 -4.8%)

【ポジティブな変化】
・若年層の新規登録が増加し、全体の伸びをけん引しました🎉

【注目したい点】
・一部セグメントで初月離脱が増えており、定着率に改善の余地があります💭

【まとめ】
新規獲得は順調ですが、離脱傾向への対応が今後のカギになりそうです🔑

このように、冒頭の軽いあいさつからはじまり、「概要→定量サマリー→ポジ/ネガコメント→まとめ」という流れを想定しています。ポイントは、サマリー部分には正確な数値を入れること、数値を見て客観的に評価してもらうこと、の二点です。

全体構成

このレポートを毎月自動で出すために、以下のような構成を考えました。

  • BigQuery:KPIデータの集計先
  • GCS(Cloud Storage):設定ファイルやSQLを保管
  • Vertex AI Notebook(Python環境):SQL実行、分析、Gemini呼び出し
  • Gemini(2.5 Pro):自然言語でのレポート生成
  • Slack:最終レポートの送信先

コード(シンプルな例)

以下は構成を簡略化したコード例です。

from vertexai.generative_models import GenerativeModel
from google.cloud import bigquery, storage
import pandas as pd, requests, json
from datetime import datetime

# GCSのファイル読み込み
client = storage.Client()
def load_gcs_file(bucket, path):
    return client.bucket(bucket).blob(path).download_as_text()

bucket = "sample_bucket"
config = json.loads(load_gcs_file(bucket, "config/config.json"))
sql = load_gcs_file(bucket, "sql/sample_query.sql")

# BigQueryでデータ取得
bq = bigquery.Client()
df = bq.query(sql).to_dataframe()
df["report_month"] = pd.to_datetime(df["report_month"])

latest = df["report_month"].max()
prev = df["report_month"].sort_values().unique()[-2]

cur = df[df["report_month"] == latest]["value"].sum()
prev_val = df[df["report_month"] == prev]["value"].sum()
rate = round((cur - prev_val) / prev_val * 100, 1) if prev_val else 0.0

# Geminiにレポート生成を依頼
prompt = f"""
今月の数値は {cur:,} 件で、前月比 {rate}% の変化です。
以下のテンプレートでSlack通知文を出力してください。
・明るく元気な口調で
・太字や下線は使わず、絵文字を適度に使用
・数値はカンマ区切り
"""

message = GenerativeModel("gemini-2.5-pro").generate_content(prompt).text.strip()
requests.post(config["slack_webhook"], json={"text": message})

このサンプルでは、BigQuery Notebook上でSQLを実行 → 結果を集計 → Geminiでレポート文を生成 → Slackに送信という一連の流れを実現しています。Notebookのスケジュール実行機能を使えば、設定ひとつで毎月レポートが自動的にSlackに届くようになります。

Geminiに渡すデータについて、数値には属性情報を3軸(例:年齢×性別×地域など)ほど付け、属性ごとの傾向を分析してもらえるようにしました。

工夫したポイント

レポーティングをAIに任せるにあたって、いろいろと試行錯誤したので、工夫した点を二点抜粋してまとめておきます。

1. 数値がぶれる問題
当初は「AIにSQLを書かせて、その結果から当月の実績・前月比・前年比を自動で書かせる」ことを目指していましたが、正直かなり難易度が高かったです。
毎回実行するたびに出力結果が微妙に変わってしまい、安定性ゼロ。レポーティングのたびにブレるので、運用に乗せるのは厳しいと感じました。
この課題、AI分析を試したことがある人なら一度は経験があるかもしれません。

解決策:SQLは固定、計算はPythonで
毎月見ている定型の数値であれば、わざわざAIにSQLを生成させる必要はないと判断し、SQLはあらかじめGCS上に保存しておく方式に切り替えました。
目的は「レポートを作ること」であって「SQLを自動で書いてもらうこと」ではない、と割り切った感じです。
(当初は「できたらすごそうだな〜」という気持ちが先行してました)

同様に、計算もAIには任せないことにしました。
年月ごとの実績ならまだしも、属性(年齢・性別・地域など)が絡むと精度がガクッと落ち、明らかにおかしな数値になることが多発したためです。
そのため、実績値・前年比・前月比はすべてPythonであらかじめ計算し、その結果だけをプロンプトに渡すようにしました。

Before:

report_month, age, prefecture, gender, value
2024-04, 18, 東京都, 女性, 782
2024-05, 25, 大阪府, 男性, 837
2024-06, 42, 福岡県, 女性, 282

After

2024-04, 東京都×女性×18歳 実績値:782 前年比:90% 前月比:102%
2024-05, 大阪府×男性×25歳 実績値:837 前年比:100% 前月比:101%
2024-06, 福岡県×女性×42歳 実績値:282 前年比:98% 前月比:99%

全体集計も同様に前処理してから渡すことで、安定したレポート生成ができるようになりました。

2. 施策情報・ドメイン知識のインプット
単にKPIの数字だけを渡すだけだと、「何が良くて、何が悪いのか」といった分析に深みが出ません。
そこで、GCSにドメイン知識最近行った施策などのテキストファイルを保存し、プロンプトにそれらを含めることで、文脈を補う工夫をしました。

ただ、今回のデータには「どのユーザーがどの施策を経験したか」といった情報はなかったため、施策に紐づいた分析まではあまり行えませんでした。
今後、施策の効果を絡めた分析をしたい場合は、ユーザー属性への施策情報の付与が必要だと感じています。


その他にも細かい工夫は色々ありますが、最終的には「AIに何をさせたいか」を明確にしながら、1つずつ丁寧に指示を追加していくことで、理想に近いアウトプットが得られるようになりました。
実際にプロンプトに記載していた注意点は、最初はシンプルでしたが、試行錯誤を重ねるうちに以下のようにかなり細かくなっていきました👇

【分析の注意点】

  • ドメイン知識や施策情報を活用してください
  • 評価コメントでは、各数値を前月比や前年比からポジティブ/ネガティブな傾向を自然に評価してください
  • 直近1年のデータを見て、変化してきている傾向や季節要因による影響があれば、それを含めて分析してください
  • 伸び率(前年比・前月比)が高くても、元の実数(母数)が小さい場合は過度に評価しないようにしてください
  • 実数が多いセグメントも評価の際にバランスよく注目してください
  • 属性が「その他」に分類されているユーザーは、属性情報が不明なケースが多く、分析における重点対象ではありません。分析や評価では深く掘り下げないでください。

レポーティングの評価、どうする?

「数値を正確に出す」という点に関しては、前述の工夫(SQLや前処理を人間が担う)で、かなり安定してきました。
一方で、最初に掲げていた「レポート作成の手間を削減できるか?」という観点では、まだ課題が残っていると感じています。
人間であれば「過去の傾向」「季節要因」「ドメイン知識」を前提にしたうえで、数値の変動や注目ポイントを瞬時に判断できますが、AIにはその文脈をすべてプロンプトやインプットデータとして明示する必要があります。
しかも、仮に情報を全て渡せたとしても、AIが本当に重要な変化を適切にピックアップできるとは限りません。
そういった意味では、まだまだ人間の判断力や経験に頼る部分が多く、現時点ではAIはあくまで補助的な役割にとどまる印象です。

ただ、「異常値を検出して知らせる」だけであれば、もうAIに完全に任せてもいいかもしれません。
実際に出力されたレポートを読んでいて、「え、ここの数値ってこんなに変化してたの?」と気づかされる場面が何度かあり、そうした気づきを得られるのは有益でした。

色々やってみましたが、現時点では「運用に完全に乗せるにはまだ少し手がかかるけど、補助的なレポートとしては十分役立つ」くらいの立ち位置で使うのがちょうどいいかもしれません。

この構成の良かったところ

最後に、今回の構成で特に便利だと感じた点をまとめます。

  • 設定ファイル・テンプレート・SQLをGCSに置いておけば、Notebook側のコードはシンプルに保てる
  • GCP上で完結する
    • 認証まわりの設定がほぼ不要
    • 手元でトークン発行など一切なし
  • Notebookのスケジュール実行を使えば、毎月自動でSlackにレポートが届くため、集計や報告の作業が実質ゼロに

「まず自動レポートを試してみたい」というフェーズにおいては、かなり取り組みやすい構成だと感じました。

さいごに

全自動でレポートを作ってもらえたらどれだけ楽か…という気持ちで始めた取り組みでしたが、思ったよりちゃんと働いてくれたので感動しました。
これからもいい感じの手抜きを目指して、AIくんに頑張ってもらいたいです。