データ定義の要約をSQLとLLMで自動生成する

## 概要
SQL（BigQuery QL） から Google の言語モデルにデータのサマリを渡して、データに関する解説文を出力させます

データエンジニアがよく知らないデータセットであっても、生成AIがデータから詳細な定義ドキュメントを生成してくれます。今回は単純にテーブルスキーマを読ませて推測させた例ですが、モデルのチューニング、プロンプトへのデータの渡し方次第で人間以上にリッチで正確な解説文を生成可能です


## 前提

* Google BigQuery に入っているデータについて実行
* BigQuery のSQLで、Google の言語モデルに対して問い合わせる
* サンプルのクエリ程度であれば基本的に無料の範囲（クエリのデータ参照量による）


## 手順

### 1. 権限設定
クエリ実行を行うユーザに、次のロールを付与します
- [Vertex AI User](https://cloud.google.com/vertex-ai/docs/general/access-control?hl=ja#aiplatform.user)

https://cloud.google.com/bigquery/docs/generate-text-tutorial?hl=ja#grant-permissions



### 2. BigQuery Connection API の有効化
* [BigQuery Connection API を有効化](https://console.cloud.google.com/apis/api/bigqueryconnection.googleapis.com/credentials)する

![スクリーンショット 2024-05-11 13.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35755/3e4845ae-b202-beb8-a90b-17a0b61ad9d5.png)



https://cloud.google.com/bigquery/docs/reference/bigqueryconnection/rest




### 3. クラウドリソース接続の作成
* Google BigQuery のSQL文から、Google Cloud にある言語モデルなどのMLモデルに接続できるようにします 
* 設定者に適切な権限を付与して、下記手順を実行します
  * [コンソールでの手順](https://cloud.google.com/bigquery/docs/create-cloud-resource-connection?hl=ja#console)
  * [terraformでの手順](https://cloud.google.com/bigquery/docs/create-cloud-resource-connection?hl=ja#terraform)

https://cloud.google.com/bigquery/docs/create-cloud-resource-connection?hl=ja

 
### 4. Vertex AI リモートモデルへの接続を作成
エンドポイントにはいくつかの言語モデルを選択可能です、下記ドキュメントを参考に用途に合わせたモデルを選択します。

https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models?hl=ja

次のようなSQLを実行することでモデルを定義できます
例:テキスト用 PaLM 2 32k を選択した例
```sql
CREATE OR REPLACE MODEL `target-project.model.test_model`
REMOTE WITH CONNECTION `target-project.asia-northeast1.test_model`
OPTIONS (ENDPOINT = 'text-bison-32k@latest');
```

https://cloud.google.com/bigquery/docs/bigquery-ml-remote-model-tutorial?hl=ja#:~:text=%E6%8E%A5%E7%B6%9A%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E3%81%AB,%E4%BD%9C%E6%88%90%5D%20%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%97%E3%81%BE%E3%81%99%E3%80%82



### ５. モデルによる推論
次のようなSQLで、プロンプトを組み立てて渡すと回答として生成された文章が得られます
プロンプトで指示した通り、テーブル定義を読み取って、適切なテーブル定義をマークダウンの表で出力してくれます

#### users テーブルの解説を生成する例
```sql
SELECT *
FROM
  ML.GENERATE_TEXT(
    MODEL `target-project.models.test_llm`,
    (
      SELECT
        CONCAT('Please summarize the table definition based on the following JSON, presenting the summary with headings for the table overview and column descriptions, in Markdown format and in Japanese : ', TO_JSON_STRING(array_agg(t))) AS prompt
      FROM (
        SELECT
          table_name,
          ARRAY_AGG(STRUCT(column_name, data_type)) AS columns
        FROM
          `target-project.dataset.INFORMATION_SCHEMA.COLUMNS`
        WHERE
          table_name = 'users'
        GROUP BY
          table_name
      ) AS t
    ),
    STRUCT(
      0.2 AS temperature,
      8000 AS max_output_tokens,
      TRUE AS flatten_json_output)
  )
```

#### 生成されるプロンプト

```sql
Please summarize the table definition based on the following JSON, presenting the summary with headings for the table overview and column descriptions, in Markdown format and in Japanese : 
[{""table_name"":""users"",""columns"":
 [{""column_name"":""user_id"",""data_type"":""STRING""},
 {""column_name"":""location_id"",""data_type"":""INT64""},
 {""column_name"":""created_at"",""data_type"":""TIMESTAMP""},
 {""column_name"":""updated_at"",""data_type"":""TIMESTAMP""}]]
```

#### 出力例

マークダウン形式のテキスト
```sql
## ユーザーテーブルの概要

このテーブルは、ユーザーに関する情報を格納しています。

### カラムの説明

| カラム名 | データ型 | 説明 |
|---|---|---|
| user_id | STRING | ユーザーの一意キー |
| job_id | INT64 | ユーザーの職業を表すキー、 ... | 
| location_id | INT64 | ユーザーの現住所を表すキー、 ... | 
| created_at | TIMESTAMP | ユーザーが作成された日時 |
| updated_at | TIMESTAMP | ユーザー情報が更新された日時 |
```

表示例
![スクリーンショット 2024-04-29 17.03.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35755/be358d21-4732-cbf7-cc01-c13e958cafc0.png)


### 6. データセットの全テーブルに対して実行

上記がうまくいけば、所定のデータセットの全テーブルに対して実行します
プログラムで回してクエリ実行しても良いですし何でもOKですが、ここではSQLで実行する例を載せておきます

#### 指定データセットで、全テーブルをループして推論結果を書き出すSQL例
（BigQuery のコンソールから下記クエリを実行して結果を取得できます）
```sh
DECLARE target_dataset STRING;
DECLARE target_table_name STRING;
DECLARE query STRING;
DECLARE tables ARRAY<STRING>;

-- table type 1:TABLE
-- https://cloud.google.com/bigquery/docs/information-schema-tables?hl=ja
SET tables = ( 
  SELECT ARRAY_AGG(table_id)
  FROM `target-project.target_dataset.__TABLES__`
  WHERE type = 1 );

FOR table IN ( select * from UNNEST(tables) ) DO
  SET target_table_name = table.f0_;
  SET query = CONCAT(
    "SELECT * FROM",
    "  ML.GENERATE_TEXT(",
    "    MODEL `target-project.model.test_model`,",
    "    (",
    "      SELECT",
    "        CONCAT('Please summarize the table definition based on the following JSON, presenting the summary with headings for the table overview and column descriptions, in Markdown format and in Japanese : ', TO_JSON_STRING(array_agg(t))) AS prompt",
    "      FROM (",
    "        SELECT table_name, ARRAY_AGG(STRUCT(column_name, data_type)) AS columns",
    "        FROM `target-project.target_dataset.INFORMATION_SCHEMA.COLUMNS`",
    "        WHERE table_name = '",target_table_name,"'",
    "        GROUP BY table_name",
    "      ) AS t",
    "    ),",
    "    STRUCT(",
    "      0.2 AS temperature,",
    "      8000 AS max_output_tokens,",
    "      TRUE AS flatten_json_output)",
    "  );");
  EXECUTE IMMEDIATE query;
END FOR;
```

以上

出力結果はマークダウンのテキストなので、GitHubなど任意の場所に展開して参照すると良いでしょう





### 応用
今回はシンプルな例ですが、プロンプトやモデルの選択によって精度を上げることができます

- プロンプト次第（引き渡す情報の組み立て次第）で出力結果は改善できる
- 中身のデータをそれぞれSELECTしてサマリすけば、もっとリッチな解説文が出力できる
- データ定義について、たとえばデータをINSERTしているプログラムコードなどを学習させたモデルを使用すれば、よりリッチな出力にできる

定期実行とドキュメンテーションの自動化

- ドキュメンテーションの自動化：GitHub Actions などから定期的にクエリ実行し、実行結果のマークダウンテキストをGitHubに登録する
- [Dataplex / DataCatalog](https://cloud.google.com/data-catalog/docs/concepts/overview?hl=ja) のカスタムエントリなどで、データのメタデータを登録／更新して検索可能にする



## おわりに  

SQLを書かなくても自然言語でリクエストするだけで、期待する分析結果を得られる時代が来ました。ただ当面は、AIの分析結果が本当に正しいのか、人間の検証するプロセスがひきつづき必要になりそうです。

すべての分析をAIが行ってくれるまでのあいだ、SQLでデータ分析を行う人がちょっと便利になる方法として書き残しておきます。

## 参考資料

https://cloud.google.com/blog/ja/products/ai-machine-learning/llm-with-vertex-ai-only-using-sql-queries-in-bigquery