2025年8月28日

【BigQuery】AI.GENERATE_TABLE 関数を使用して、画像から構造化データを生成してみた


Content
こんにちは。

本記事では、2025年4月にプレビューとして発表された AI.GENERATE_TABLE 関数を試してみようと思います。
AI.GENERATE_TABLE 関数は、既存の ML.GENERATE_TEXT 関数(BigQuery から生成AIを呼び出してテキストを生成できる関数)を拡張した関数で、出力を非構造化データとしてではなく、構造化データとして取得することが可能です。

従来の ML.GENERATE_TEXT 関数でも、ある程度プロンプトの書き方次第で出力形式を制御することは可能でしたが、より確実にデータを標準化し、後続の処理に利用することができます。
生成AIの出力を確実に制御できることで、後続のアウトプットの品質向上が期待できるため、非常に嬉しい機能かと思います。

検証の流れ

今回は、AI.GENERATE_TABLE 関数 を使用して画像から情報を抽出し、構造化データとして取得してみようと思います。

主な流れは以下です。
1.Cloud Storage に画像をアップロード【Cloud Storage】
2.オブジェクトテーブルを作成【BigQuery】
3.リモートモデルを作成【BigQuery】
4.AI.GENERATE_TABLE 関数を使用して、構造化データを生成【BigQuery】

※今回の検証では、必要な権限付与、API有効化、接続の作成については、手順から割愛しております。こちらの詳細につきましては、AI.GENERATE _TABLE 関数を使用して構造化データを生成する をご参照ください。
※接続、オブジェクトテーブル、リモートモデルは、同じロケーションに作成してください。
※今回作成しているリモートモデル(Gemini 2.5 Flash)は、検証時点(2025年8月)で使用可能なロケーションに制限があります。
※検証のキャプチャは、検証時点(2025年8月)のものです。

【参考】
AI.GENERATE_TABLE の概要: BigQuery で生成 AI モデルから構造化データを作成

実際に AI.GENERATE_TABLE 関数 を試してみる

では、実際にやってみようと思います。

1.Cloud Storage に画像をアップロード【Cloud Storage】
Cloud Storage 内にバケットとフォルダを作成し、画像をアップロードします。
今回は、バケット「ai-generate-table-test-bucket」、フォルダ「images」を作成し、以下画像をアップロードしています。

▼ 東京都(東京タワー)の画像

▼ 京都府(清水寺)の画像

▼ 都道府県とは無関係の犬の画像

 

2.オブジェクトテーブルを作成【BigQuery】
BigQuery から画像データにアクセスするため、オブジェクトテーブルを作成します。
オブジェクトテーブルとは、Cloud Storage 内にある非構造化データの読み取り専用テーブルで、オブジェクトテーブルを作成することによって、Cloud Storage 内の非構造化データにアクセスすることができます。
今回は、「image_table」というテーブルを作成しています。

CREATE OR REPLACE EXTERNAL TABLE `ai_generate_table_test_dataset.image_table`
WITH CONNECTION `us.bq_vertexai`
OPTIONS(
object_metadata = 'DIRECTORY',
uris = ['gs://ai-generate-table-test-bucket/images/*']); -- Cloud Storage のパス

▼ 作成したオブジェクトテーブルの中身

 

3.リモートモデルを作成【BigQuery】
Gemini 2.5 Flash に接続するため、BigQuery 内にリモートモデルを作成します。
今回は、「gemini25flash」というモデルを作成しています。

CREATE OR REPLACE MODEL `ai_generate_table_test_dataset.gemini25flash`
REMOTE WITH CONNECTION `us.bq_vertexai`
OPTIONS (endpoint = 'gemini-2.5-flash');

 

4.AI.GENERATE_TABLE 関数を使用して、構造化データを生成【BigQuery】
AI.GENERATE_TABLE 関数 を使用して画像から情報を抽出し、構造化データとして取得します。
「画像から都道府県を認識し、その名前、大まかな歴史、観光名所を日本語で出力してください。画像が都道府県でない場合は何も出力しないでください。」というプロンプトと、出力形式を指定します。
・prefecture(都道府県、文字列)
・brief_history(大まかな歴史、文字列)
・attractions(観光名所、文字列の配列)
この形式はスキーマと呼ばれ、スキーマを定義する構文は、BigQuery の CREATE TABLE コマンドと同様です。

SELECT
prefecture,
brief_history,
attractions,
uri
FROM
AI.GENERATE_TABLE(
MODEL ai_generate_table_test_dataset.gemini25flash, -- 作成したリモートモデル
(SELECT
('画像から都道府県を認識し、その名前、大まかな歴史、観光名所を日本語で出力してください。画像が都道府県でない場合は何も出力しないでください。', ref) AS prompt, -- プロンプト
uri
FROM
ai_generate_table_test_dataset.image_table), -- 作成したオブジェクトテーブル
STRUCT(
'prefecture STRING, brief_history STRING, attractions ARRAY<STRING>' AS output_schema)) -- 出力形式(スキーマ)
ORDER BY
uri;

▼ 出力結果
あらかじめ定義したスキーマからなるテーブルが作成されました。
画像自体も正しく認識され、都道府県、大まかな歴史、観光名所が取得できていそうです。また、配列であっても問題なく出力されています。

実際に AI.GENERATE_TABLE 関数 を試してみる(イレギュラー編)

次は、あえてプロンプトをスキーマと一致させなかった場合の出力を確認してみようと思います。
出力形式(スキーマ)は変更せず、プロンプトのみ以下に変更してみます。
【変更前】
画像から都道府県を認識し、その名前、大まかな歴史、観光名所を日本語で出力してください。画像が都道府県でない場合は何も出力しないでください。
【変更後】
画像から都道府県を認識し、その都道府県の人口を日本語で出力してください。画像が都道府県でない場合は何も出力しないでください。

▼ 出力結果
今回の場合は、プロンプトで指定した「人口」の情報は取得されず、スキーマに従って情報が取得されているようでした。

ML.GENERATE_TEXT 関数 との構文の違い

最後に、公式ドキュメントより、それぞれの構文の違いを見ていこうと思います。
ML.GENERATE_TEXT 関数
AI.GENERATE_TABLE 関数

一番のポイントとなる、出力形式(スキーマ)の指定以外、大きな違いはありませんでした。
細かい差分でいうと、AI.GENERATE_TABLE 関数は、以下パラメータがありませんでした。
・GROUND_WITH_GOOGLE_SEARCH
・FLATTEN_JSON_OUTPUT

▼ ML.GENERATE_TEXT 関数

ML.GENERATE_TEXT(
MODEL `PROJECT_ID.DATASET.MODEL`,
{ TABLE `PROJECT_ID.DATASET.TABLE` | (QUERY_STATEMENT) },
STRUCT(
[MAX_OUTPUT_TOKENS AS max_output_tokens] # 出力トークンの上限
[, TOP_P AS top_p] # Top-P(ランダム性を制御)
[, TEMPERATURE AS temperature] # 温度(ランダム性を制御)
[, FLATTEN_JSON_OUTPUT AS flatten_json_output] # JSON コンテンツのフラット化の設定
[, STOP_SEQUENCES AS stop_sequences] # 停止シーケンス
[, GROUND_WITH_GOOGLE_SEARCH AS ground_with_google_search] # Google 検索によるグラウンディングの設定(Gemini 1.5 Pro および Gemini 1.5 Flash のみ対応)
[, SAFETY_SETTINGS AS safety_settings] # 安全フィルタの設定
[, REQUEST_TYPE AS request_type]) # リクエストの種類
)

▼ AI.GENERATE_TABLE 関数

AI.GENERATE_TABLE(
MODEL `PROJECT_ID.DATASET.MODEL`,
{ TABLE `PROJECT_ID.DATASET.TABLE` | (QUERY_STATEMENT) },
STRUCT(
OUTPUT_SCHEMA AS output_schema # 出力形式(スキーマ)
[, MAX_OUTPUT_TOKENS AS max_output_tokens] # 出力トークンの上限
[, TOP_P AS top_p] # Top-P(ランダム性を制御)
[, TEMPERATURE AS temperature] # 温度(ランダム性を制御)
[, STOP_SEQUENCES AS stop_sequences] # 停止シーケンス
[, SAFETY_SETTINGS AS safety_settings] # 安全フィルタの設定
[, REQUEST_TYPE AS request_type]) # リクエストの種類
)

まとめ

従来の ML.GENERATE_TEXT 関数 から大きな変更を加えず、構造化データを生成できるのは便利だなと思いました。
また、ML.GENERATE_TEXT 関数 の場合は、プロンプトで出力形式を制御したとしても、その後テーブル形式にするためには加工が必要になりますが、その加工が不要になる点も嬉しいですね。

なかなか BigQuery のアップデートに追いつけていないので、引き続き検証していきたいと思います。

最後まで読んでいただき、ありがとうございました。

2025年8月28日 【BigQuery】AI.GENERATE_TABLE 関数を使用して、画像から構造化データを生成してみた

Category Google Cloud

ご意見・ご相談・料金のお見積もりなど、
お気軽にお問い合わせください。

お問い合わせはこちら