本記事について
Autonomous Databaseで使用することの出来る機能、
Select AIを使えば自然言語を使用してデータを問い合せることが可能
Select AIで大規模言語モデル(LLM)を使用することで、
ユーザーが入力したテキスト(自然言語)をSQLに変換し、
データベース内のデータを問合せることが出来る
本記事では実際にSelect AIを用いてデータベースへの問い合わせを行う
OCI生成AIサービスのAPIキー取得
Select AIでは、2024年9月時点で、
OpenAI、Cohere、Azure OpenAI Service、OCI Generative AI Service、およびGoogle GeminiをAIプロバイダーとして使用することが出来る
本記事では、
OCI生成AIサービスをAIプロバイダーとして使用する
↓ OCIコンソールにアクセスして、
右上のプロファイルからユーザー設定を選択
↓ 左下のリソースからAPIキーを選択し、APIキーの追加をクリック
↓ APIキー・ペアの生成(デフォルト)を選択し、
秘密キーのダウンロードをした上で作成
秘密キーは後程使用するので大切に保管しておきます
↓ 構成ファイルのプレビューも後程使用しますので、
コピーしメモを取っておきます
環境設定
Select AIはADBの機能なので、使用にはADBインスタンスが必要です
予め用意しておきましょう
ユーザーの作成と権限の付与
先ずはユーザーの作成と、権限の付与を行います
Database ActionsのSQLワークシートから、
チュートリアルを行うユーザーを作成し、必要なロールを付与する
以下のSQLを実行し、
- SELECT_AI_USERというユーザーを作成、必要なロールを付与
- SELECT AI機能の利用に必要なDBMS_CLOUD_AIパッケージの実行権限を付与
- Database ActionsにSELECT_AI_USERとしてサインインするため、RESTを有効化
GRANT DWROLE, UNLIMITED TABLESPACE TO select_ai_user IDENTIFIED BY Welcome12345#;
GRANT EXECUTE ON DBMS_CLOUD_AI TO select_ai_user;
-- REST ENABLE
BEGIN
ORDS_ADMIN.ENABLE_SCHEMA(
p_enabled => TRUE,
p_schema => 'SELECT_AI_USER',
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'select_ai_user',
p_auto_rest_auth=> TRUE
);
commit;
END;
/
これでユーザーの作成と、権限の付与が完了
確認用コマンド
SELECT USERNAME
FROM ALL_USERS
WHERE USERNAME = 'SELECT_AI_USER'
ORDER BY USERNAME
;
データセットの準備
次に、使用するデータセットをADB上にロードする
↓ Database Actionsから一度サインアウト
↓ 先程作成したSELECT_AI_USERユーザーとしてサインイン
以下の様に入力
- ユーザー名:select_ai_user
- パスワード:Welcome12345#
↓ Data Studioタブのデータ・ロードをクリック
↓ 今回はExcelファイルをADB上にロードしたいので、データのロードを選択
↓ 以下サイトからHIGHSCHOOLS.xlsxをダウンロードし、
ダウンロードしたExcelファイルをアップロード
↓ アップロードしたファイルのデータ・ロードの設定を編集
ペンのアイコンをクリックし、編集画面を開く
↓ 表の名前をHIGHSCHOOLSに変更し、閉じるボタンをクリック
↓ 表の名前がHIGHSCHOOLSと変更されている事を確認し、開始ボタンをクリック
↓ HIGHSCHOOLS.xlsx内のデータがロードされ、HIGHSCHOOLS表が作成された
これでデータ・セットの準備が完了
SQL Developerの設定とビューの作成
先程まで使用していたDatabase Actions内のSQLやAPEXではSELECT AI文を直接実行することをサポートしていない
この為、DBMS_CLOUD_AIパッケージのGENERATEファンクションを使用する必要がある
そのため本記事では、
SQL Developerを使用して、データベースに接続する
作成したADBにSQL Developerから接続します。
ユーザは、SELECT_AI_USER
接続が完了したら、SQL Developer上で以下のクエリを実行し、HIGHSCHOOLS表とその中身を確認する
-- HIGHSCHOOLS表の列一覧を表示
SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE, DATA_DEFAULT
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 'HIGHSCHOOLS'
ORDER BY COLUMN_ID;
-- HIGHSCHOOLS表に格納されているデータ一覧を表示
SELECT * FROM HIGHSCHOOLS;
HIGHSCHOOLS表にある列とその中のデータを確認する事ができる
↓ HIGHSCHOOLS表内には列が多く、今回は使用しない列もあるため、ビューを作成し使用する列を制限する
今回はhighschools_viewという名前のビューを作成し、使用する
CREATE VIEW highschools_view AS
SELECT
BOROUGH,
SCHOOL_NAME,
INTEREST,
TOTAL_STUDENTS,
GRADUATION_RATE,
COLLEGE_CAREER_RATE,
SAFE,
SEATS,
APPLICANTS,
LATITUDE,
LONGITUDE,
LANGUAGE_CLASSES,
ADVANCED_PLACEMENT_COURSES,
SCHOOL_SPORTS,
OVERVIEW_PARAGRAPH,
ACADEMIC_OPPORTUNITIES,
ADVANCEDPLACEMENT_COURSES,
EXTRACURRICULAR_ACTIVITIES,
PSAL_SPORTS_BOYS,
PSAL_SPORTS_GIRLS,
ADDTL_INFO1
FROM
HIGHSCHOOLS;
クレデンシャルの作成
DBMS_CLOUD.CREATE_CREDENTIALプロシージャを使用して、OCI生成AIサービスに接続するためのクレデンシャルを作成する
以下の通りにOCID等を置き換え、プロシージャを実行する
OCI生成AIサービスを利用可能なOCIユーザのAPIキーの情報を設定する:
- credential_name:任意(本記事ではOCI_GENAI_CREDとしています)
- user_ocid:先ほどメモを取った構成ファイルを参照し、ユーザーのOCIDを入力
- tenancy_ocid:先ほどメモを取った構成ファイルを参照し、使用しているテナンシーのOCIDを入力
- private_key:先程取得した秘密キーの内容をコピー&ペースト
- fingerprint:先ほどメモを取った構成ファイルを参照し、フィンガープリントを入力
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OCI_GENAI_CRED',
user_ocid => 'ocid1.user.oc1..axxxxxxxxxxxxxxxxq',
tenancy_ocid => 'ocid1.tenancy.oc1..aaxxxxxxxxxxxxa',
private_key => '-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiGQEFA<中略>1D3iheu1ct50SB0aIQz9Ow==
-----END PRIVATE KEY-----',
fingerprint => 'xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx'
);
END;
/
これでクレデンシャルを作成する事が出来た
このクレデンシャルは、この後プロファイルを作成する際に繰り返し使用しますので、credential_nameをメモしておく
プロファイルの作成
DBMS_CLOUD_AI.CREATE_PROFILEプロシージャを使用して、AIプロファイルを作成
- プロファイル名:GENAI_COHERE_COMMAND_R(任意)
- provider:oci(本記事ではOCI生成AIサービスをAIプロバイダーとして使用)
- credential_name:OCI_GENAI_CRED(先ほど作成したクレデンシャル名を指定)
- model:cohere.command-r-08-2024(プロバイダーをOCIとし、モデルを指定しない場合は、meta.llama-3-70b-instructが使用されます)
- oci_apiformat:COHERE(OCIチャットモデルを使用し、Cohereのモデルを指定する場合はoci_apiformatとしてCOHEREと指定)
- region: us-chicago-1(このregionパラメータを指定することで、指定したリージョンのOCI GenAIサービスを利用します。指定しない場合、デフォルトではChicagoリージョンのエンドポイントが使用されます。)
- object_list:このプロファイルで使用するスキーマ・オブジェクトの所有者(本チュートリアルではselect_ai_user)とオブジェクト名(本チュートリアルではhighschools_view)を指定
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE_COMMAND_R',
'{
"provider": "oci",
"credential_name": "OCI_GENAI_CRED",
"model":"cohere.command-r-08-2024",
"oci_apiformat":"COHERE",
"region": "us-chicago-1",
"object_list": [
{"owner": "select_ai_user", "name": "highschools_view"}
]
}'
);
END;
/
これでAIプロファイルが作成完了
SELECT AIを試してみる
コメント無しの場合
DBMS_CLOUD_AI.SET_PROFILEプロシージャを使用して、
セッションで使用するAIプロファイルとして、
先程作成したGENAI_COHERE_COMMAND_Rを指定する
EXEC DBMS_CLOUD_AI.SET_PROFILE('GENAI_COHERE_COMMAND_R');
先ずは、高校は全部で何校あるか聞いてみる
SELECT AI 高校は全部で何校ありますか;
↓ 結果は427と返ってきました。
highschools_view内に何校分データが格納されているのか確認してみます。
SELECT COUNT(*) FROM highschools_view;
↓ highschools_view内には427校分データが格納されているので、正しい結果が返ってきたことが分かる
次に、マンハッタン市内にある高校の総数を聞いてみる
SELECT AI マンハッタン市内に高校は全部で何校ありますか;
↓ マンハッタン市内には少なくとも1校以上高校があるはずなので、期待される結果は返ってきませんでした
showsqlオプションを使用して、どの様なSQLが生成されているのか確認する
SELECT AI showsql マンハッタン市内に高校は全部で何校ありますか;
以下のようなSQLが返ってきた
WHERE句でBOROUGHを’Manhattan’と指定していますが、
HIGHSCHOOLS表の中はカタカナで’マンハッタン’と記載がある為、
WHERE句が上手く機能していない
RESPONSE
--------------------------------------------------------------------------------------------------------------------------------
SELECT COUNT(*) AS "Total High Schools in Manhattan"
FROM "SELECT_AI_USER"."HIGHSCHOOLS_VIEW"
WHERE UPPER(BOROUGH) = 'MANHATTAN'
表、列、ビューにコメントを追加することで、
LLMに追加の情報を与えることが出来る
BOROUGH列にコメントを追加し、
カタカナで’マンハッタン’と指定しても正しくSQLが生成されるように調整をする
コメント有りの場合
先程作成したビューの列にコメントを追加し、
LLMが日本語でWHERE句の条件を指定してくれるようにメタデータを補足する
学校名やスポーツ名、言語名などの名詞は
「日本語で格納されています。」等コメントで補足をします。
COMMENT ON COLUMN highschools_view.BOROUGH IS '高校が所在する地区。カタカナで地区名が格納されています。';
COMMENT ON COLUMN highschools_view.SCHOOL_NAME IS '高校の名称。日本語で学校名が格納されています。';
COMMENT ON COLUMN highschools_view.INTEREST IS '学校の特色';
COMMENT ON COLUMN highschools_view.TOTAL_STUDENTS IS '総生徒数';
COMMENT ON COLUMN highschools_view.GRADUATION_RATE IS '卒業率';
COMMENT ON COLUMN highschools_view.COLLEGE_CAREER_RATE IS '大学への進学率';
COMMENT ON COLUMN highschools_view.SAFE IS '学校の安全性評価';
COMMENT ON COLUMN highschools_view.SEATS IS '提供されている座席数';
COMMENT ON COLUMN highschools_view.APPLICANTS IS '入学希望者数';
COMMENT ON COLUMN highschools_view.LATITUDE IS '学校の緯度';
COMMENT ON COLUMN highschools_view.LONGITUDE IS '学校の経度';
COMMENT ON COLUMN highschools_view.LANGUAGE_CLASSES IS '提供される言語クラス。日本語で言語名が格納されています。';
COMMENT ON COLUMN highschools_view.ADVANCED_PLACEMENT_COURSES IS '提供される上級コース。日本語でコース名が格納されています。';
COMMENT ON COLUMN highschools_view.SCHOOL_SPORTS IS '学校で提供されるスポーツ。カタカナでスポーツ名が格納されています。';
COMMENT ON COLUMN highschools_view.OVERVIEW_PARAGRAPH IS '学校の概要';
COMMENT ON COLUMN highschools_view.ACADEMIC_OPPORTUNITIES IS '学問的な機会';
COMMENT ON COLUMN highschools_view.ADVANCEDPLACEMENT_COURSES IS '提供されるAdvanced Placementコース';
COMMENT ON COLUMN highschools_view.EXTRACURRICULAR_ACTIVITIES IS '課外活動';
COMMENT ON COLUMN highschools_view.PSAL_SPORTS_BOYS IS '男子PSALスポーツ。カタカナでスポーツ名が格納されています。';
COMMENT ON COLUMN highschools_view.PSAL_SPORTS_GIRLS IS '女子PSALスポーツ。カタカナでスポーツ名が格納されています。';
COMMENT ON COLUMN highschools_view.ADDTL_INFO1 IS '追加情報';
コメントを追加したので、新たにプロファイルを作成
プロファイル名をGENAI_COHERE_COMMAND_R_COMMENTSとし、
LLMに送信するメタデータにコメントを含めるために
"comments":“true"を追加する
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE_COMMAND_R_COMMENTS',
'{
"provider": "oci",
"credential_name": "OCI_GENAI_CRED",
"model":"cohere.command-r-08-2024",
"oci_apiformat":"COHERE",
"region": "us-chicago-1",
"comments":"true",
"object_list": [
{"owner": "select_ai_user", "name": "highschools_view"}
]
}'
);
END;
/
DBMS_CLOUD_AI.SET_PROFILEプロシージャを使用して、
セッションで使用するAIプロファイルとして
GENAI_COHERE_COMMAND_R_COMMENTS を指定する
EXEC DBMS_CLOUD_AI.SET_PROFILE('GENAI_COHERE_COMMAND_R_COMMENTS');
再度、マンハッタン市内にある高校の総数を聞いてみる
SELECT AI マンハッタン市内に高校は全部で何校ありますか;
結果が返ってきた
生成されたSQLも確認してみます
showsqlオプションを使用して、どの様なsqlクエリが生成されているのか確認する
SELECT AI showsql マンハッタン市内に高校は全部で何校ありますか;
以下のようなSQLが返ってきました
WHERE句の条件がカタカナで’マンハッタン’と正しく指定されています
RESPONSE
-----------------------------------------------------------------------------------------------------------------------------------------
SELECT
COUNT(*) AS "Total High Schools in Manhattan"
FROM
"SELECT_AI_USER"."HIGHSCHOOLS_VIEW"
WHERE
UPPER(BOROUGH) = 'マンハッタン'
他にも質問をしてみる
SELECT AI 中国語の授業がある高校一覧;
↓ 高校名が表示されました
コメントを付けてLLMに送信するメタデータを補足すると、
結果の精度が向上する様子が確認できる
パラメータ
SELECT AIでは使用出来るactionパラメータがいくつかある
以下が使用可能なパラメータです
- runsql - 結果セットを返す(指定しない時のデフォルト)
- showsql - 生成されたSQLを返す
- narrate - 会話形式で結果を返す
- chat - 一般的なAIチャット(データベースへの問合せは行わず、LLMから直接レスポンスを生成する)
- explainsql - 生成されたSQLを自然言語で説明
いくつかのパラメータを実際に試す
先ずはrunsqlパラメータを試す
SELECT AI runsql 大学進学率が90%以上の高校;
SELECT AI runsql 大学進学率が90%以上の高校はどこですか。またその高校の進学率はいくつですか;
-- runsqlはデフォルトのパラメータなので、以下のクエリと結果が同じになります
-- SELECT AI 大学進学率が90%以上の高校;
大学進学率が90%以上の高校一覧が表示された
次はnarrateを試す
SELECT AI narrate 大学進学率が90%以上の高校;
runsqlを指定した時と同じ結果ですが、
それが自然言語で表示された
生成されたSQLの実行結果がAIプロバイダに送信され、自然言語でのサマリーが生成される
次はchatを試す
SELECT AI chat 大学進学率が90%以上の高校はどこですか;
これまではデータベース上のデータをもとにしたレスポンスが返って来ましたが、
今回はインターネット上の情報をもとにLLMが生成したレスポンスが返ってきた
参考ドキュメント
OCI チュートリアル
https://oracle-japan.github.io/ocitutorials/adb/
























