🍎

BigQuery×Geminiでスクレイピングデータの週次レポートを自動生成する

に公開

はじめに

これは「GitHub Trendingデータ基盤構築編」シリーズの続編です。

前回の記事では、GitHub TrendingをスクレイピングしてDataflowで整形し、BigQueryに構造化データとして蓄積するパイプラインを構築しました。

今回はその続きとして、BigQueryに蓄えたデータをGeminiに渡して週次技術トレンドレポートを自動生成するところまでを紹介します。BigQueryに蓄えたデータを生成AIでうまく活用できないかという試みでした。

前回記事:https://zenn.dev/acntechjp/articles/970c2d3063ab80

やりたいこと

シンプルに以下の流れを実現します。

  1. BigQueryから直近7日分の急上昇リポジトリを抽出
  2. 結果をJSONにしてGeminiに渡す
  3. 人が読める週次レポート(Markdown)を生成

アーキテクチャは次のような構成です。

  • Dataflow: GitHub生データをクレンジングしてBigQueryにロード
  • BigQuery: 期間・言語・スター数などで集計・フィルタ
  • Gemini: JSON+プロンプトから週次レポートを生成

つまり「BigQueryのSELECT結果を、そのままLLMに食べさせる」という形になります。

BigQuery: データの切り出し

まずLLMに渡すデータをSQLで準備します。設計方針は以下の通りです。

  • 対象期間: 直近7日間
  • 優先順位: today_stars(本日増加分)→ stars(総スター数)
SELECT
  article_id,
  source,
  title,
  url,
  author,
  description,
  stars,
  today_stars,
  language,
  collected_at,
  tags
FROM tech_trends.raw_articles_dedup
WHERE DATE(collected_at) BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
  AND CURRENT_DATE()
ORDER BY today_stars DESC NULLS LAST,
         stars       DESC NULLS LAST
LIMIT 50;

ポイントは、ランキングや期間の切り方をSQL側で完結させることです。LLMに「このテーブルからいい感じに選んで」と丸投げすることもできますが、ロジックがブラックボックスになり結果がぶれやすいため、集計とフィルタはBigQueryに寄せています。

PythonでBigQueryとGeminiをつなぐ

データ取得からレポート生成までを1本のスクリプトで実装しました。

BigQueryからデータ取得

from google.cloud import bigquery
import json

bq = bigquery.Client()

query = """
SELECT ※ここに上記のSQLを入れる
;
"""

rows = list(bq.query(query))
data = [dict(row) for row in rows]

# TIMESTAMP型をJSON化するためdefault=strを指定
json_data = json.dumps(
    data,
    ensure_ascii=False,
    indent=2,
    default=str,
)

Geminiにプロンプトを投げる

プロンプトでは「どんな構成のレポートを出してほしいか」を明確に指定しました。
※実際はもう少し長いプロンプトで指示しています。

from google import genai
from google.genai.types import HttpOptions

client = genai.Client(
    vertexai=True,
    project="YOUR_GCP_PROJECT_ID",
    location="asia-northeast1",
    http_options=HttpOptions(api_version="v1"),
)

prompt = f"""
あなたは技術トレンドを分析するアナリストです。
以下は過去7日間のGitHub Trendingデータ(Dataflowでクレンジング済み)です。

【出力項目】
1. 今週のサマリ(マネージャー向け、3〜5行)
2. 技術トレンド概要(言語別・カテゴリ別)
3. 急上昇リポジトリ(today_stars重視)
4. 注目リポジトリ3つ+理由
5. 今後の学習・ウォッチ対象

【データ項目】stars, today_stars, language, tags, description

【出力形式】日本語、箇条書きと短い段落、エンジニア〜マネージャーレベル

--- JSONデータ ---
{json_data}
"""

response = client.models.generate_content(
    model=model="gemini-2.5-pro",
    contents=prompt,
)

print(response.text)

LLMには「集計」ではなく「解釈と説明」を任せるイメージです。

生成されたレポートの例

実際に出力されたレポートテキストをMDファイルでPDF化したもの(抜粋)です。
BigQueryで計算した数値とdescription/tagsを組み合わせて、LLMが適切にまとめています。



役割分担の整理

今回の構成を通して、各コンポーネントの役割分担が明確になりました。

Dataflow

  • GitHub生データのクレンジング
  • 重複排除、フィールド正規化
  • LLMが読みやすいテーブルをBigQueryに用意

BigQuery

  • 期間・指標・言語などでフィルタ・集計
  • どの行をLLMに見せるかを決定
  • 数値の計算・集計はすべてこちらで完結

Gemini(LLM)

  • BigQueryの結果(JSON)+descriptionを入力
  • カテゴリ分類・要約・サマリの生成
  • 人間が読むレポートに仕上げる

LLMに生ログをそのまま投げるのではなく、事前に構造化・正規化されたテーブルに落としておくことが重要です。

まとめ

DataflowでBigQueryに蓄えたGitHub TrendingデータをGeminiに渡して週次レポートを自動生成する方法を紹介しました。

ポイントは以下の3点です。

  • 集計とフィルタはBigQueryで完結させる
  • LLMは「定量結果の解釈と文章化」に特化させる
  • データを事前に構造化しておくことで結果が安定する

応用先としては、各種トレンド分析、業務レポートの自動生成など様々あるように思います。

「Dataflow / BigQueryでデータを整え、最後の説明だけをLLMに任せる」というパターンは汎用性が高く、さまざまな場面で転用できそうです。

GCPでデータパイプラインと生成AIを組み合わせたい方の参考になれば幸いです。

おまけ:Claude opus4.5にこの件でパワポを作らせたらさらに洗練されていました。手直しも数えるほどしか発生せず。すごい。

Accenture Japan (有志)

Discussion