生成AIの進歩でText to SQLが現実的に? 実証実験準備編
この記事について
顧客データ活用を支援するインキュデータでは、Treasure Data CDPの導入支援を行っています。私たちは「データの民主化」を実現するため、生成AIによるSQL生成を活かしたデータとの対話の実証実験を進めています。
本記事は2024年に実施した、実証実験の技術的な内容を紹介します。
取り巻く環境については、前回の記事を合わせてご確認ください。
生成AIの進歩でText to SQLが現実的に? 概要編
また、社内の検証だけで無く、お客様に対しての実証実験も行っています。
インキュデータ、化粧品会社イプサにおける生成AIを用いた顧客データ抽出の実証実験を実施
実証実験の概要
実証実験では、日常的で簡単なデータ確認と分析を自然言語で実施可能かという観点で行いました。
概念図
Treasure Data CDPに対して、オープンソースのVanna.AIとAzureのOpenAI(GPT-4o)を組み合わせた実証実験環境を構築しました。
システム構成図
Vannaとは?
Vannaは、リトリーバル・オーグメンテーション(RAG)を利用して、データベースに対する正確なSQLクエリを生成するためのPythonパッケージです。大規模言語モデル(LLM)を活用し、データベース操作を簡単かつ効果的に実現します。
Vannaは、2つのシンプルなステップで動作します:
- データに基づいてRAG「モデル」をトレーニングする。
- 質問を行い、その質問に基づいて生成されたSQLクエリをデータベースに自動的に実行する。
カスタマイズ
Vannaをベースに処理のカスタマイズを行いました。
- Treasure Data CDPのPythonライブラリの導入
- 実験当時の埋め込みモデルの精度が良くなく、システム内部では一律英語で処理するように変更
- Treasure Data CDP独自の関数を活用できるようにナレッジ部分の改修
実証実験での最終的な処理フロー
プロンプトフロー
- SQL指示書作成プロンプト
- ユーザーの質問をSQLの指示書に変換
- SQL生成プロンプト
- 指示書に基づいてSQLを生成
- SQLエラーチェック(空チェック)
- 生成されたSQLの構文エラーを検出(LIMIT 0で実行)
- SQLレビュープロンプト
- SQLがユーザーの質問に適切に答えているかレビュー
- SQL修正プロンプト(必要な場合)
- レビューで問題が指摘された場合、SQLを修正
- SQLエラーチェック(空チェック)
- 修正されたSQLの構文エラーを再度チェック
- SQLレビュープロンプト(必要な場合)
- 修正されたSQLを再度レビュー
- SQL実行
- 最終的なSQLを実際のデータに対して実行
補足事項
- 3-7のステップは、SQLが適切になるまで複数回繰り返される可能性があります。
- 「SQLコード修正プロンプト」は、主に3-7の過程で使用されます。
- 最終的なSQLチェック(7番目の「SQLチェック」)は、エラーチェックとレビューの組み合わせで行われます。
この流れにより、生成されたSQLが構文的に正確で、ユーザーの質問に適切に答えるものになることを確保しています。また、各ステップでのチェックと修正により、SQLの品質を段階的に向上させることができます。
主要なプロンプトの紹介
さまざまなプロンプトを組み合わせて構成しています。
主要なプロンプトを紹介します。
SQL指示書作成プロンプト
SQL指示書作成プロンプトは、ユーザーの質問をSQLの指示書に変換するためのプロンプトです。
-
目的:
ユーザーの入力を改善し、SQLをコーディングするための指示書や仕様書を作成すること。 -
出力形式:
JSONフォーマットで出力され、以下の要素を含みます:- 最終結果のカラム
- レビューコメント
- 改善された最終結果のカラム
- 処理手順
- 処理手順に対するレビューコメント
- 改善された処理手順
- SQL指示書
-
主な手順:
a. ユーザーの質問に基づいて、最終結果のカラムリストを生成
b. 生成されたカラムリストをレビュー
c. レビューコメントに基づいてカラムリストを改善
d. SQLの処理手順や手続きを生成
e. 生成された処理手順をレビュー
f. レビューコメントに基づいて処理手順を改善
g. 改善されたカラムリストと処理手順を考慮して、SQL指示書を生成 -
特記事項:
- 出力は英語で行う
- SQL専門家ではなく、SQLコードを直接書かない
- 必要に応じて、処理の詳細にノートを含める(例:WHERE句の条件、使用可能な関数、結合とテーブルキーに関する注意事項など)
-
コンテキスト:
プロンプトには、ユーザーの質問に関連する以下のような情報が含まれることがあります:- 過去に実行されたSQL例
- 関連するドキュメンテーション
- データベースのスキーマ情報(DDL)
- SQLの指示に関するヒント
このプロンプトを使用することで、ユーザーの質問をより具体的かつ構造化されたSQL指示書に変換し、その後のSQL生成プロセスを支援します。
SQL生成プロンプト
SQL生成プロンプトは、ユーザーの質問やSQL指示書に基づいてSQLクエリを生成するためのプロンプトです。
-
目的:
ユーザーの質問や指示書に基づいて、実行可能で適切なSQLクエリを生成すること。 -
システムメッセージの主な内容:
- AIの役割:TreasureData SQL(PrestoまたはHive)の専門家としての設定
- 現在の日時情報
- 初期プロンプト(設定されている場合)
-
入力情報:
- ユーザーの質問(日本語と英語)
- 関連するドキュメンテーション
- データベースのスキーマ情報(DDL)
- 過去に実行された類似のSQL例
- SQLのヒントやベストプラクティス
- SQL指示のヒント
-
主な手順:
a. 入力された質問や指示書を理解
b. 関連する情報(ドキュメント、スキーマ、過去のSQL例など)を参照
c. SQLクエリの構造を設計
d. 必要な処理手順を組み込む
e. SQLのベストプラクティスやヒントを適用
f. 実行可能なSQLクエリを生成 -
出力:
生成されたSQLクエリ -
特記事項:
- SELECTステートメントのみを生成(セキュリティ上の理由)
- LIMITの使用が必須(大規模データ処理の制限のため)
- 特定の禁止ワードをチェック
- 必要に応じて、中間的なSQLの実行と結果の利用
-
後処理:
- 生成されたSQLのタイポ修正
- SQLの実行可能性テスト(LIMIT 0での実行)
- レビューコメントの生成と必要に応じた修正
このプロンプトを使用することで、ユーザーの質問や指示書に基づいて、データベースの特性を考慮した適切なSQLクエリを生成し、さらに実行可能性や品質を確保するための後処理も行います。
SQLエラーチェック(空チェック)
SQLエラーチェック(空チェック)は、生成されたSQLの実行可能性を事前に確認するプロセスです。
-
目的:
生成されたSQLが構文的に正しく、実行可能であることを確認すること。 -
実装方法:
LIMIT 0を使用して行われます。 -
主な手順:
a. 元のSQLにLIMIT 0を追加または既存のLIMITを0に変更
b. 修正されたSQLを実行
c. 実行結果を分析 -
返り値の構造:
以下の情報を含む辞書を返します:- status: 実行結果のステータス("success" または "error")
- sql: 実行されたSQL(LIMIT 0が追加されたもの)
- message: エラーメッセージ(エラーが発生した場合)
- df: 実行結果のDataFrame(成功した場合、通常は空)
-
エラーハンドリング:
- SQLの実行中に例外が発生した場合、statusを"error"に設定し、エラーメッセージを保存
-
利点:
- 実際のデータを取得せずにSQLの構文エラーを検出可能
- データベースへの不要な負荷を避けられる
- セキュリティリスクを軽減(データを実際に取得しないため)
-
使用例:
- SQL生成後の自動チェック
- SQLの修正プロセスにおける各ステップでの確認
- ユーザーに結果を返す前の最終チェック
-
注意点:
- LIMIT 0によりデータは返されないため、データに依存するエラー(例:存在しない列の参照)は検出できない
- 一部のクエリ(特定の集計関数を使用するものなど)では、LIMIT 0が意図した通りに機能しない可能性がある
このプロセスにより、実際にデータを取得せずにSQLの基本的な実行可能性を確認し、エラーを早期に検出できます。これにより、ユーザーエクスペリエンスの向上とシステムの効率性・安全性の確保に貢献します。
SQLレビュープロンプト
SQLレビュープロンプトは、生成されたSQLが適切にユーザーの質問に答えているかを確認し、必要に応じて改善するためのプロンプトです。
-
目的:
生成されたSQLがユーザーの質問に正確に答えているか、明らかな間違いがないかをレビューすること。 -
入力情報:
- ユーザーの元の質問
- レビュー対象のSQL
- 関連するコンテキスト(ドキュメンテーション、スキーマ情報など)
- SQLのヒント
- これまでのSQLの実行履歴
-
出力形式:
JSONフォーマットで以下の情報を含む:- SQLに関連するコンテキストや制約条件のリスト
- SQLで修正すべき問題点のリスト
- フィードバック
- レビューコメント
- SQLを修正すべきかどうかの判断("Yes" または "No")
-
主な手順:
a. 提供された情報から、SQLに関連するコンテキストと制約条件を抽出
b. SQLをレビューし、問題点や改善点をリストアップ
c. SQLがユーザーの質問に適切に答えているかを評価
d. フィードバックを生成し、SQLの修正が必要かどうかを判断 -
評価の観点:
- SQL構文の正確性
- ユーザーの質問との整合性
- 必要なデータの網羅性
- パフォーマンスの考慮
- データベースの制約やベストプラクティスの遵守
-
特記事項:
- レビューは明らかな間違いのみを指摘
- SQLの
LIMIT
句は、たとえ不適切でも必要とされる - 出力は英語で行う
-
レビュー結果の利用:
- SQLの修正が必要と判断された場合、修正プロセスに進む
- 修正が不要と判断された場合、そのSQLを最終的な出力として使用
-
実装上の注意点:
- レビュープロセスは一定回数まで繰り返し可能
- SQLが実行可能テストを通過した後にのみ実行される
このプロンプトを使用することで、生成されたSQLの品質を確保し、ユーザーの質問により適切に答えるSQLを提供できます。また、人間の介入なしに自動的にSQLを改善するプロセスの一部として機能します。
SQL修正プロンプト
SQL修正プロンプトは、レビューの結果、問題があると判断されたSQLを改善するためのプロンプトです。
-
目的:
レビューで指摘された問題点を解決し、ユーザーの質問により適切に答えるSQLに修正すること。 -
システムメッセージの主な内容:
- AIの役割:指定されたSQLダイアレクト(例:TreasureData SQL)の専門家としての設定
- 現在の日時情報
- SQLを実行可能かつユーザーの質問に適切に答えるものに修正するための指示
-
入力情報:
- ユーザーの元の質問
- 修正が必要なSQL
- SQLの実行履歴(成功したSQL、エラーメッセージ等)
- 関連するドキュメンテーション
- データベースのスキーマ情報(DDL)
- SQLのヒントやベストプラクティス
- 過去に実行された類似のSQL例
- レビューコメント
-
出力形式:
JSONフォーマットで以下の情報を含む:- 考慮すべき情報のリスト
- SQLを修正するためのTODOリスト
- SQLの修正が必要な部分のリスト
- 修正されたSQL
-
主な手順:
a. 提供されたすべての情報から、SQL修正に必要な情報を抽出
b. 抽出した情報に基づいて、修正すべき点のTODOリストを作成
c. SQLの具体的な修正箇所をリストアップ
d. 上記の情報を考慮してSQLを修正 -
特記事項:
- SQLの基本的な処理内容を変更せず、ユーザーの質問への適合性と実行可能性の向上に焦点を当てる
- SQLのコメントがある場合、英語に翻訳し元のコメントの後ろに括弧付きで追加
-
LIMIT
句は必ず含める(大規模データ処理の制限のため)
-
後処理:
- 修正されたSQLのタイポチェックと修正
- 修正されたSQLの実行可能性テスト(LIMIT 0での実行)
- 必要に応じて再度のレビューと修正
-
実装上の注意点:
- 修正プロセスは一定回数まで繰り返し可能
- 各修正後に実行可能性テストとレビューを行い、問題が解決されるまで繰り返す
このプロンプトを使用することで、レビューで指摘された問題を解決し、ユーザーの質問により適切に答えるSQLに修正できます。また、修正プロセスを段階的に行い、各ステップの結果を記録することで、透明性と追跡可能性を確保しています。
SQL実行
SQL実行処理は、生成・修正・検証されたSQLを実際のデータベースに対して実行するプロセスです。
-
目的:
生成されたSQLをTreasure Dataに対して実行し、結果を取得すること。 -
主な手順:
a. SQLの前処理
b. クエリの実行
c. 結果の取得とDataFrame化
d. 結果のポストプロセス(カラムの削除やマスキング) -
SQLの前処理:
- Prestoエンジンを使用する場合、SQLの末尾のセミコロンを削除
-
クエリ実行:
- pytdクライアントを使用してSQLを実行
-
結果の取得:
- 実行結果をPandasのDataFrameに変換
- 結果が列情報を含む場合と含まない場合で異なる処理を実施
-
ポストプロセス:
- 特定のカラムの削除
- 特定のカラムのマスキング
- SQLの列の系統(lineage)に基づいた追加の削除やマスキング
-
列の系統(lineage)の分析:
- SQLLineageライブラリを使用して、入力列と出力列の関係を分析
- 個人情報に関連する列の特定と適切な処理(削除またはマスキング)
-
特記事項:
- 削除やマスキングの対象となる列は、クラス初期化時に指定
- 数値のみで構成される文字列列は、個人情報に関連する可能性があるとして特別に扱われる
-
エラーハンドリング:
- SQL実行時のエラーは例外としてキャッチされ、呼び出し元に伝播
-
セキュリティ対策:
- 個人情報や機密情報に関連する列の自動的な削除やマスキング
- 集計されたデータ(数値型)は通常保持される
この処理により、生成されたSQLを安全に実行し、必要なデータを取得しつつ、個人情報や機密情報を適切に保護できます。また、SQLの列の系統を分析することで、派生した列にも適切な処理を適用し、データの整合性と機密性を維持しています。
RAG(リトリーバル・オーグメンテーション)
5つのドキュメントを学習データとして準備しました。
ビジネスロジック
社内用語や商品の説明、業界用語の情報を入れています。
ユーザーからの質問を正しく理解するために非常に重要です。
SQL指示書Tips
テーブルやSQLを理解して、分析をする際に注意することを記載しています。
たとえば、無料サンプルを除外する方法や社内の分析でよく使う手法などを登録しています。
過去SQL
実際に過去分析で構築したSQLを入れています。
ユーザーの質問内容とSQL全文を入れています。
SQLの中にはコメント形式で説明を付与して、理解しやすくしています。
テーブル定義書
CREATE TABLE形式で、実際のテーブル情報を入れています。
コメントで、日本語での列名やサンプルデータも入れています。
SQL Tips
Treasure Data CDP独自の関数の情報を主に入れています。
UNIX_TIMESTAMPではなく、TD_TIME_PARSEを使うなどの指示です。
まとめ
今回は実証実験に向けて構築や準備した内容を紹介しました。
次回はこの実証実験を実際に行った際の出来事や改善点と結果から考える今後の展望を紹介します。ぜひご期待ください。
Discussion