はじめに
この記事は、Oracle Cloud(OCI) で提供されている Autnomous AI Database(ADB)の Select AI 機能の使い方について、少し深掘りしています.
対象者
この記事は下記のような人を対象にしています.
- Oracle DB は、オンプレミスで使っている.
- Oracle Cloud の基本操作は、知っている.
- ADB を使ったことがある.
- Select AI を深く試してみたい.
目次
- 事前準備(ADBの作成から Select AI の実行まで)
- ADB の作成
- PC(macbook) への Oracle Client の install
- sqlplus からの ADB への接続
- Select AI を使用できるようにする
- Select AI の復習
- Select AI Action で使える機能
- 各 Action の実行例
- 余談
- 参考記事・ドキュメント
事前準備(ADBの作成から接続まで)
以下の 4 つは、別の記事にまとめているのでそちらを参照ください。
[Oracle Cloud] ADB で Select AI を試してみる
- ADB の作成
- PC(macbook) への Oracle Client の install
- sqlplus からの ADB への接続
- Select AI を使用できるようにする
Select AI の復習
事前準備完了の状態では、以下のように Select AI が実行できます。
duke@mac ~ % selectAI % sqlplus ai_user/Welcome12345#@aidb1_high
SQL>
SQL> select username from user_users;
USERNAME
--------------------------------------------------------------------------------
AI_USER
SQL>
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('SELECT_AI_PROFILE');
PL/SQLプロシージャが正常に完了しました。
SQL>
SQL> desc highschools;
名前 NULL? 型
----------------------------------------- -------- ----------------------------
BOROUGH VARCHAR2(64)
SCHOOL_NAME VARCHAR2(256)
NEIGHBORHOOD VARCHAR2(64)
INTEREST VARCHAR2(64)
METHOD VARCHAR2(64)
TOTAL_STUDENTS NUMBER
GRADUATION_RATE NUMBER
ATTENDANCE_RATE NUMBER
COLLEGE_CAREER_RATE NUMBER
SAFE NUMBER
SEATS NUMBER
APPLICANTS NUMBER
DBN VARCHAR2(64)
LATITUDE NUMBER
LONGITUDE NUMBER
LANGUAGE_CLASSES VARCHAR2(4000)
ADVANCED_PLACEMENT_COURSES VARCHAR2(4000)
SCHOOL_SPORTS VARCHAR2(4000)
FAQ_URL VARCHAR2(64)
OVERVIEW_PARAGRAPH VARCHAR2(4000)
ACADEMIC_OPPORTUNITIES VARCHAR2(4000)
ADVANCEDPLACEMENT_COURSES VARCHAR2(4000)
DIADETAILS VARCHAR2(4000)
EXTRACURRICULAR_ACTIVITIES VARCHAR2(4000)
PSAL_SPORTS_BOYS VARCHAR2(4000)
PSAL_SPORTS_GIRLS VARCHAR2(4000)
ADDTL_INFO1 VARCHAR2(4000)
SQL> select count(*) from highschools;
COUNT(*)
----------
427
SQL>
SQL> select ai 高校の総数は ;
Total_High_Schools
------------------
427
SQL>
Select AI Action で使える機能
Select AI は、以下のような文法で実行します.
SELECT AI action natural_language_prompt
action で指定するパラメタの一覧は、以下.
| Action パラメタ | 説明 |
|---|---|
| runsql | デフォルトのアクション. プロンプトから生成されたSQLの実行結果を表示する. |
| showsql | プロンプトから生成されたSQL文を表示する. |
| explainsql | プロンプトから生成されたSQL文の内容を説明する. |
| narrate | SQLの実行結果を自然言語で説明する. |
| showprompt | プロンプトを SQL に変換(NL2SQL)するために LLM に渡す情報を表示する. |
| chat | ADB のデータは参照することなく、LLMに直接プロンプトを送信する. |
| summarize | ADBのデータには参照することなく、テキストの内容の概要を生成する. |
| feedback | プロンプトに対して適切な SQL が生成されたかどうかを feedback する. 間違っていれば、その点を指摘することで次からの SQL に反映される |
| translate | プロンプトを翻訳するための翻訳サービス. LLM に渡す前の SQL を表示する. |
| agent | プロンプトに対して SQL を返すのではなく、エージェントチームに自然な処理を依頼する. |
各 Action の実行例
- runsql, showsql の実行例
runsql は、プロンプトから自然言語の質問文を投げて、結果を得ます.
showsql は、その時に生成された SQL 文を返します.
SQL> select ai 高校の生徒の総数を教えて;
TOTAL_STUDENTS
--------------
300209
SQL> select ai runsql 高校の生徒の総数を教えて;
TOTAL_STUDENTS
--------------
300209
SQL>
SQL> select ai showsql 高校の生徒の総数を教えて;
RESPONSE
-------------------------------------------------------------------------------
SELECT SUM(h."TOTAL_STUDENTS") AS total_students
FROM "AI_USER"."HIGHSCHOOLS" h
SQL>
- explainsq の実行例
生成された SQL 文の説明をしてくれます.
SQL> select ai showsql 高校の生徒の総数を教えて;
RESPONSE
-------------------------------------------------------------------------------
SELECT SUM(h."TOTAL_STUDENTS") AS total_students
FROM "AI_USER"."HIGHSCHOOLS" h
SQL>
SQL> select ai explainsql 高校の生徒の総数を教えて;
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Oracle SQL Query
'''sql
SELECT SUM(h."TOTAL_STUDENTS") AS total_students
FROM "AI_USER"."HIGHSCHOOLS" h
'''
### Detailed Explanation
- **SELECT Clause**: Uses the `SUM()` aggregate function on the `"TOTAL_STUDENTS"` column to calculate the total number of students across all high schools in the table. The result is aliased as `total_students` for readability.
- **FROM Clause**: References the table `"AI_USER"."HIGHSCHOOLS"` with an alias `h` to make the query concise and readable.
- **Overall Purpose**: This query sums the `"TOTAL_STUDENTS"` values from all rows in the `"HIGHSCHOOLS"` table, providing the total student count for high schools. No WHERE clause is needed as the question asks for the overall total without filters. The query follows Oracle SQL syntax, with case-se
nsitive table and column names enclosed in double quotes, and uses a table alias for clarity. No string comparisons are involved, so no UPPER() functions are applied. This is adapted from the provided example structure (e.g., using SUM on a numeric column with aliasing), but tailored to the `"TOTAL_
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
STUDENTS"` column based on the question's intent.
SQL>
- narrate の実行例
実行された SQL 文の結果を自然言語で回答してくれます.
SQL>
SQL> select ai narrate 高校の生徒の総数を教えて;
RESPONSE
--------------------------------------------------------------------------------
高校の生徒の総数は300209人です。
SQL>
- showprompt の実行例
LLM に渡される SQL プロンプトの実態を表示してくれます.
SQL> select ai showprompt 高校の生徒の総数を教えて;
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[
{
"role" : "SYSTEM",
"content" :
[
{
"type" : "TEXT",
"text" : "### Oracle SQL tables with their properties:\n # CREATE TABLE \"AI_USER\".\"HIGHSCHOOLS\" (\"EXTRACURRICULAR_ACTIVITIES\" VARCHAR2(4000), \"DIADETAILS\" VARCHAR2(4000), \"ADVANCEDPLACEMENT_COURSES\" VARCHAR2(4000), \"ACADEMIC_OPPORTUNITIES\" VARCHAR2(4000), \"OVERVIEW_PARAGRAPH\" V
ARCHAR2(4000), \"FAQ_URL\" VARCHAR2(64), \"SCHOOL_SPORTS\" VARCHAR2(4000), \"ADVANCED_PLACEMENT_COURSES\" VARCHAR2(4000), \"LANGUAGE_CLASSES\" VARCHAR2(4000), \"LONGITUDE\" NUMBER, \"LATITUDE\" NUMBER, \"DBN\" VARCHAR2(64), \"APPLICANTS\" NUMBER, \"SEATS\" NUMBER, \"SAFE\" NUMBER, \"COLLEGE_CAREER_R
ATE\" NUMBER, \"ATTENDANCE_RATE\" NUMBER, \"GRADUATION_RATE\" NUMBER, \"TOTAL_STUDENTS\" NUMBER, \"METHOD\" VARCHAR2(64), \"INTEREST\" VARCHAR2(64), \"NEIGHBORHOOD\" VARCHAR2(64), \"SCHOOL_NAME\" VARCHAR2(256), \"BOROUGH\" VARCHAR2(64), \"ADDTL_INFO1\" VARCHAR2(4000), \"PSAL_SPORTS_GIRLS\" VARCHAR2(
4000), \"PSAL_SPORTS_BOYS\" VARCHAR2(4000))\n"
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
}
]
},
{
"role" : "USER",
"content" :
[
{
"type" : "TEXT",
"text" : "\n\nGiven an input Question, create a syntactically correct Oracle SQL query to run. Pretty print the SQL query. \n - Pay attention to using only the column names that you can see in the schema description.\n - Be careful to not query for columns that do not exist. Also, pay attent
ion to which column is in which table.\n - Please double check that the SQL query you generate is valid for Oracle Database.\n - Consider table name, schema name and column name to be case sensitive and enclose in double quotes. - Only use the tables listed below. \n - If the table definition inclu
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
des the table owner, you should include both the owner name and user-qualified table name in the Oracle SQL. - DO NOT keep empty lines in the middle of the Oracle SQL.\n - DO NOT write anything else except the Oracle SQL.\n - Always use table alias and easy to read column aliases. \n\nFor string com
parisons in WHERE clause, CAREFULLY check if any string in the question is in DOUBLE QUOTES, and follow the rules: \n - If a string is in DOUBLE QUOTES, use case SENSITIVE comparisons with NO UPPER() function.\n - If a string is not in DOUBLE QUOTES, use case INSENSITIVE comparisons by using UPPER()
function around both operands of the string comparison.\nNote: These rules apply strictly to string comparisons in the WHERE clause and do not affect column names, table names, or other query components.\n\nUse the examples below in two ways: \n- If the question matches an user_prompt in examples,
return the corresponding SQL query exactly as shown.\n- If the question is different, use the following examples as a reference. Learn their structure, aliasing, and casing rules when generating new queries. Here are examples of previous successful queries for similar questions that you can refer to
and learn from: \n[{\"user_prompt\":\"中学校の生徒数を教えて\",\"sql_query\":\"SELECT SUM(h.\\\"APPLICANTS\\\") AS applicants\\nFROM \\\"AI_USER\\\".\\\"HIGHSCHOOLS\\\" h\"}]\n\nQuestion: 高校の生徒の総数を教えて"
}
]
}
]
SQL>
- chat, summarize の実行例
ADB にはアクセスしないで、直接 LLM に問い合わせて回答を得ます.
chat では、普通の質問を投げて回答を得ます.
summarize では、長文や object storage に保存したファイルなどを参照させてサマリーを作ります.
SQL> select ai chat 高校の生徒の総数を教えて;
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### クエリの解釈
あなたのクエリ「高校の生徒の総数を教えて」は、どの国や地域の高校を指しているかが指定されていないため、曖昧です。日本語のクエリであることから、日本国内の高校(高等学校)を想定して回答します。もし他の国(例: 世界全体や米国)を指している場合は、追加で指定してください。
### 日本国内の高校生総数
- **最新データ(2022年度、文部科学省「学校基本調査」より)**: 日本の高等学校(全日制・定時制・通信制を含む)の生徒総数は約2,499,000人です。
- 内訳: 全日制約2,300,000人、定時制約150,000人、通信制約49,000人。
- **傾向**: 生徒数は年々減少傾向にあり、2023年度の推定値も同程度(約2,400,000人前後)。詳細は文部科学省の公式サイト(mext.go.jp)で最新データを確認できます。
### 世界全体の高校生総数(参考)
- UNESCOの推定(2020年データ): 世界の高等教育段階(高校相当)の生徒総数は約1.5億人(約150,000,000人)。これは国によって定義が異なるため、概算です。
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
データは変動する可能性があるため、信頼できるソースから最新情報を取得することをおすすめします。追加の詳細が必要ですか?
SQL>
SQL>
SQL> select ai summarize '### クエリの解釈 あなたのクエリ「高校の生徒の総数を教えて」は、どの国や地域の高校を指しているかが指定されていないため、曖昧です。日本語のクエリであることから、日本国内の高校(高等学校)を想定して回答します。もし他の国(例: 世界全体や米国)を指している場合は、追加で指定してください。 ### 日本国内の高校生総数 - **最新データ(2022年度、文部科学省「学校基本調査」より)**: 日本の高等学校(全日制・定時制・通信制を含む)の生徒総数は約2,499,000人です。 - 内訳: 全日制約2,300,000人、定時制約150,000人、通信制約49,000人。 - **傾向**: 生徒数は年々減少傾向にあり、2023年度の推定値も同程度(約2,400,000人前後)。詳細は文部科学省の公式サイト(mext.go.jp)で最新データを確認できます。 ### 世界全体の高校生総数(参考) - UNESCOの推定(2020年データ): 世界の高等教育段階(高校相当)の生徒総数は約1.5億人(約150,000,000人)。これは国によって定義が異なるため、概算です。';
SQL>
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
クエリ「高校の生徒の総数を教えて」は指定が曖昧なため、日本国内の高等学校を想定して回答する。2022年度の文部科学省データによると、日本の高校生総数は約249万9000人で、全日制約230万人、定時制約15万人、通信制約4万9000人。生徒数は減少傾向にあり、2023年度も同程度と推定される。世界全体ではUNESCOの2020年推定
で約1億5000万人だが、国による定義の違いから概算値である。詳細は文部科学省サイトで確認可能。
SQL>
- feedback の実行例
Select AI で得た回答について、それが適切だったのか、調整が必要だったのかを伝え、次回の プロンプトで改修するように促します.
feedback を使うためには、DBMS_CLOUD_AI.FEEDBACK プロシージャが実行できるように、特定の table にselect AI 実行ユーザの権限を付与します。
以下は、admin ユーザで実行します.
GRANT READ ON SYS.V_$MAPPED_SQL TO ai_user;
GRANT READ ON SYS.V_$SESSION TO ai_user;
feedback は、以下のような文法で行います
select ai feedback for query "Select AI showsql <feedbackしたい自然言語の問い合わせ>", <生成されたSQLクエリに対してのフィードバック>;
以下では、質問文の単語”スペイン語"と"バスケットボール" を LLM が英語に変換してしまい、対象の行が見つかりませんでした。
そこで、列の値は、日本語で検索するように feedback 設定したところ、正しい SQL が生成されました.
SQL> select ai スペイン語のクラスがあって、かつ、バスケットボールができる高校の一覧;
レコードが選択されませんでした。
SQL>
SQL> select ai showsql スペイン語のクラスがあって、かつ、バスケットボールができる高校の一覧;
RESPONSE
--------------------------------------------------------------------------------
SELECT h."SCHOOL_NAME" AS school_name
FROM "AI_USER"."HIGHSCHOOLS" h
WHERE UPPER(h."LANGUAGE_CLASSES") LIKE UPPER('%Spanish%')
AND UPPER(h."SCHOOL_SPORTS") LIKE UPPER('%basketball%')
SQL>
SQL> select ai feedback for query "select ai showsql スペイン語のクラスがあって、かつ、バスケットボールができる高校の一覧", 列の値は日本語表記 ;
RESPONSE
--------------------------------------------------------------------------------
Based on your feedback, the SQL query for prompt "スペイン語のクラスがあって、か
つ、バスケットボールができる高校の一覧" is successfully refined. The refined SQL
query as following:
SELECT h."SCHOOL_NAME" AS school_name
FROM "AI_USER"."HIGHSCHOOLS" h
WHERE UPPER(h."LANGUAGE_CLASSES") LIKE UPPER('%スペイン語%')
AND UPPER(h."SCHOOL_SPORTS") LIKE UPPER('%バスケットボール%')
SQL>
SQL> select ai showsql "スペイン語のクラスがあって、かつ、バスケットボールができる高校の一覧";
RESPONSE
--------------------------------------------------------------------------------
SELECT h."SCHOOL_NAME" AS school_name
FROM "AI_USER"."HIGHSCHOOLS" h
WHERE UPPER(h."LANGUAGE_CLASSES") LIKE UPPER('%スペイン語%')
AND UPPER(h."SCHOOL_SPORTS") LIKE UPPER('%バスケットボール%')
SQL> select ai "スペイン語のクラスがあって、かつ、バスケットボールができる高校の一覧";
SCHOOL_NAME
--------------------------------------------------------------------------------
金融技術研究所
ニューディレクションズ中等学校
アーバンアセンブリ刑事司法学校
...
...
高校における科学、技術、数学の新たな探究 (NEST+m)
116行が選択されました。
SQL>
feedback は、完全マッチする SQL に適用されるため、プロンプトの書き方が変われば、反映されないという問題があります。
少数の定型 SQL を投げるのであれば有効ですが、多様なプロンプト=SQL を投げるのであれば、feedback の設定は、冗長であまり効果的ではありません。
以上、Select AI の Action パラメータを試してみました.
余談
プロンプトの内容が正しく SQL に反映されるためには、プロンプトの内容をわかりやすく記述するだけでは不十分です. feedback を適宜設定してあげたり、対象テーブルにコメントやアノテーションなどをつけて列の意味などを補足説明してあげることが必要になります.
LLM も万能では無いので、人と同じで丁寧なアドバイスが必要ということですね。