
Contents
このブログは、実際にCodatumのテンプレートを確認しながら読んでいただくことができます!
ぜひこちらのテンプレートを参照の上、手を動かしなら読んでみてください。
Codatumのダッシュボードは、チャートやテキストなどを自由度高く掲載することができるため、用途にあったバラエティ豊かな活用をいただくことができます。
ダッシュボードにテキストサマリを掲載することで、グラフだけでは読み取りにくい傾向や背景がユーザーに伝わりやすくなります。

ただ、このサマリーを人が手動で書いている場合、更新の手間がかかるだけでなく、ユーザーがパラメータを変更してデータの対象を切り替えても、文章の方はその操作についてこられません。
企業を絞り込んだのに、サマリーは全社データを前提にした内容のまま。担当者が定期的に書き直さない限り、グラフとテキストの間にズレが生まれてしまいます。
そこで、この記事では、BigQueryを介してVertex AIを呼び出し、ユーザーがパラメータで指定したデータに応じて、サマリーそのものをその場で生成する方法を紹介します。
BigQuery以外のコネクションでも、対応するAI機能があれば同じ考え方で実現できます。
※Vertex AIのセットアップについては、こちらの記事にてご紹介しています
テキストパネルで、生成したサマリーを表示する
Codatumには、Markdown記法のテキストを表示するための「テキストパネル」というチャートタイプがあります。今回は、このテキストパネルをAIが生成した文章の表示先として使います。

やることは大きく分けて4つです。
Vertex AIをセットアップする
BigQueryにモデルを作成する
集計データをモデルに渡す
テキストパネルチャートで生成結果を表示する
この流れを組んでおくと、ユーザーがパラメータを変更してクエリが再実行されるたびに、その時点で表示されているデータに応じたサマリーが自動的に生成されます。
クエリの実行に合わせてサマリも書き変わるため、データの更新に合わせて、手動で更新することなく、最新・最適なサマリを閲覧することができます。
実装例:Chicago Taxi Tripデータで検証する
ここからは、BigQueryのパブリックデータセット「Chicago Taxi Trips」を使った実装例を掲載します。
企業(Company)と支払い方法(Payment Type)をパラメータとして切り替えると、その都度対象データに応じたサマリーが生成され、表示が変わります。
モデルの作成

まず、Vertex AIのモデルをBigQuery上に作成します。この作業はBigQueryのクエリエディタ側でも実行できます。
CREATE OR REPLACE MODEL `codatum-example.example.vertex_ai`
REMOTE WITH CONNECTION `us.vertex_ai_test`
OPTIONS(
ENDPOINT = 'gemini-2.5-flash'
)クエリが完了すると、BigQueryのexampleデータセットにvertex_aiモデルが追加されます。
データの集計
次に、サマリーの元になるデータを集計します。ここでは、月次で企業ごと・支払い方法ごとの乗車回数、乗車時間、乗車距離、乗車料金を集計し、企業名と支払い方法はCodatumのパラメータ機能でユーザー側から変更できるようにします。
ただし、対象テーブルが数億行規模でパーティション/クラスタリングが無い場合、絞り込み条件を集計クエリのWHERE句にそのまま入れると、パラメータを切り替えるたびに生データ全体への高コストなスキャンが発生してしまいます。そこで集計はあらかじめ1回だけ実行し、月次×企業×支払い方法の粒度で小さな中間テーブルに保存しておき、Codatum側のパラメータはこの軽量なテーブルに対してのみ絞り込みを行うようにします。

① 事前集計(BigQueryコンソール等で単発、または定期実行。Codatumの外で実行)
CREATE OR REPLACE TABLE `your-project.your_dataset.monthly_company_payment_summary` AS
SELECT
DATE_TRUNC(trip_start_timestamp, month) as month,
company,
payment_type,
COUNT(DISTINCT unique_key) as trip_count,
SUM(trip_seconds) / 60 as total_trip_min,
AVG(trip_seconds) / 60 as average_trip_min,
MAX(trip_seconds) / 60 as max_trip_min,
MIN(trip_seconds) / 60 as min_trip_min,
SUM(trip_miles) as total_trip_miles,
AVG(trip_miles) as average_trip_miles,
MAX(trip_miles) as max_trip_miles,
MIN(trip_miles) as min_trip_miles,
SUM(fare) as total_fare,
AVG(fare) as average_fare,
MAX(fare) as max_fare,
MIN(fare) as min_fare
FROM
`bigquery-public-data.chicago_taxi_trips.taxi_trips`
WHERE trip_start_timestamp >= '2017-01-01' AND trip_start_timestamp < '2018-01-01' -- 2017年のデータ
AND trip_seconds != 0 AND fare != 0 AND trip_miles != 0 -- 外れ値除外
AND trip_seconds < 21600
GROUP BY month, company, payment_type② Codatum側のSQLブロック(Codatum上で書くSQL。パラメータで動くのはここだけ)
templateのnotebookではcompany_payment_aggとして作成しています。
SELECT
*
FROM
`your-project.your_dataset.monthly_company_payment_summary`
WHERE
CASE {Company} WHEN '' THEN TRUE ELSE company = {Company} END
AND CASE {PaymentType} WHEN '' THEN TRUE ELSE payment_type = {PaymentType} END
ORDER BY
monthAIモデルへのデータの受け渡し
Codatumでは、SQLブロックの結果を別のSQLブロックから参照できます。この特性を使って、「集計」「JSON化」「配列結合」「プロンプト組み立て」「AI呼び出し」を役割ごとに分けて管理します。1本の複雑なクエリにまとめてしまうより、後から見直しやすくなります。

①集計データを1行ずつJSON化
「集計データ」は、「データの集計」セクションで作成したSQLブロックを示しています。
SELECT
TO_JSON_STRING(STRUCT(
month, company, payment_type, trip_count,
total_trip_min, average_trip_min, max_trip_min, min_trip_min,
total_trip_miles, average_trip_miles, max_trip_miles, min_trip_miles,
total_fare, average_fare, max_fare, min_fare
)) AS row_json
FROM
集計データ②行ごとのJSONを1つの配列に結合
SELECT
CONCAT('[', STRING_AGG(row_json, ','), ']') AS all_json
FROM
JSON化した集計データ③プロンプトを組み立てる
SELECT
CONCAT(
'以下のデータは月次のCompany別、PaymentType別のシカゴタクシー乗車データのサマリーです。',
'月ごとの推移も含めて傾向を日本語でMarkdown形式のレポートとして要約してください。',
'総乗車回数などの概要を説明した後、特徴的な項目を複数セクションに分けて説明してください。',
'Markdown全体をコードブロックで囲わないでください。見出しや箇条書きなど、markdownの色々な要素を使ってください。',
'生成したサマリーで完結させ、追加で編集はしません(追加の分析提案は可)。コードは埋め込まないでください。',
'対象企業は', CASE WHEN {Company} = '' THEN '全社' ELSE {Company} END, 'で、',
'対象の支払い方法は', CASE WHEN {PaymentType} = '' THEN '全て' ELSE {PaymentType} END, 'です。',
'インプットデータ: ', all_json
) AS prompt
FROM
配列化したJSONデータ④AIモデルを呼び出す
SELECT
ml_generate_text_llm_result AS output
FROM
ML.GENERATE_TEXT(
MODEL `codatum-example.example.vertex_ai`,
(SELECT prompt FROM プロンプト),
STRUCT(
0.3 AS temperature,
1000 AS max_output_tokens,
TRUE AS flatten_json_output
)
)プロンプトの書き方次第で、生成されるサマリーの安定度は大きく変わります。
何を説明してほしいか、どの粒度で書いてほしいかを具体的に指定するほど、毎回のブレが小さくなります。
テキストパネルチャートの追加

最後に、チャートタイプの選択画面から「テキストパネル」を選び、生成結果を表示するブロックとして追加します。
テキストパネルは1行目の値を表示する仕様のため、複数のテキストデータが存在する場合は、そのうち1件しか表示されません。生成結果は1行に集約した状態で渡すようにしてください。
運用時の注意点
AIが生成したMarkdownが、コードブロックなどで全体を囲われた状態になっていると、テキストパネル側で正しく展開できません。
プロンプトの中で「Markdown全体を囲う必要はない」旨を明示し、AIの出力がそのままMarkdownとして展開される形にしておく必要があります。
まとめ
人が書くテキストサマリーは、ユーザーのパラメータ操作や、更新されたデータにリアルタイムについてくることができないため、グラフとテキストの間にズレを生みやすいというデメリットがあります。
BigQuery経由でVertex AIを呼び出し、集計結果をその場でサマリーに変換してテキストパネルに表示する形にすると、ユーザーがパラメータを変えるたびに、その時点のデータに合ったサマリーが自動的に生成されます。
BigQuery以外のコネクションでも、AI関連の機能に対応していれば同じ構成で実現できます。
まずは自社のデータで、集計・JSON変換・生成・表示という4つのステップを組んでみてください!


