[Oracle Cloud] Autonomous Database ) SELECT AI（自然言語によるクエリ実行）を活用するコツ 2025年5月分 (2025/05/12)

# はじめに
Oracle CloudのAutonomous Databaseで提供される自然言語によるクエリ実行（SELECT AI）を活用するには、AIプロファイルを作成する必要があります。
AIプロファイルを作成する際のオプションが追加されたので、試してみました。
- 特定スキーマの表全体を対象にする
- 関連する表を自動的に検出
- 列に大/小文字の区別を設定
- 表アクセスを制限

# 事前準備
[Autonomous Database：SELECT AI（自然言語によるクエリ実行）がOCI生成AIサービスに対応したので試してみた](https://qiita.com/500InternalServerError/items/17255806823161a2b6bb)などを参考にSELECT AIを使うことができる準備をします。

# 特定スキーマの表全体を対象にするプロファイル

SHスキーマの表全体を対象にするプロファイルの作成

```sql
BEGIN
 DBMS_CLOUD_AI.create_profile( 
	profile_name=>'OCI_SHALL', 
	attributes=>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"object_list": [{"owner": "SH"}], 
		"oci_compartment_id": "ocid1.compartment.oc1..aaaaaaaan...", 
		"model" : "meta.llama-3.3-70b-instruct" 
	}'
  ); 
END; 
/ 
```

SELECT AIでの確認

```sql
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_SHALL');

PL/SQLプロシージャが正常に完了しました。

SQL> select ai please list the user tables;

TABLE_NAME
--------------------------------------------------------------------------------
TIMES
PRODUCTS
COUNTRIES
COSTS
PROMOTIONS
SALES
CHANNELS
CUSTOMERS
SUPPLEMENTARY_DEMOGRAPHICS

9行が選択されました。
```

# 関連する表を自動的に検出

object_list_modeを"auto"に設定することでSelect AIが関連する表を自動的に検出し、Oracle Database 23aiの問合せに関連する特定の表に対してのみメタデータを送信します。
これにより、<profile_name>_OBJECT_LIST_VECINDEXという名前のベクトル索引が自動的に作成されます。
ベクトル索引は、デフォルトの属性および値(refresh_rate、similarity_threshold、match_limitなど)で初期化されます。
このベクトル索引の一部の属性は、DBMS_CLOUD_AI.UPDATE_VECTOR_INDEXを使用して変更できます。

自スキーマに関連する表を自動的に検出するプロファイルの作成

```sql
BEGIN
 DBMS_CLOUD_AI.create_profile( 
	profile_name=>'OCI_AUTO', 
	attributes=>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"oci_compartment_id": "ocid1.compartment...aaaaaaaan...",
		"object_list_mode": "automated", 
		"model" : "meta.llama-3.3-70b-instruct" 
	}'
  ); 
END; 
/ 
```

ベクトル索引の確認

```sql
SQL> SELECT INDEX_NAME, TABLE_NAME, INDEX_TYPE FROM USER_INDEXES WHERE INDEX_TYPE = 'VECTOR';

INDEX_NAME
--------------------------------------------------------------------------------
TABLE_NAME
--------------------------------------------------------------------------------
INDEX_TYPE
---------------------------
OCI_AUTO_FEEDBACK_VECINDEX
OCI_AUTO_FEEDBACK_VECINDEX$VECTAB
VECTOR

OCI_AUTO_OBJECT_LIST_VECINDEX
OCI_AUTO_OBJECT_LIST_VECINDEX$VECTAB
VECTOR

SQL> SELECT content from OCI_AUTO_OBJECT_LIST_VECINDEX$VECTAB;

CONTENT
--------------------------------------------------------------------------------
"SELECTAIS"."VECTOR$OCI_AUTO_FEEDBACK_VECINDEX$113171_113178_0$IVF_FLAT_CENTROID

"SELECTAIS"."TIMES" ("TIME_ID" , "DAY_NAME" , "DAY_NUMBER_IN_WEEK" , "DAY_NUMBER

"SELECTAIS"."TIMES" ("FISCAL_QUARTER_DESC" , "FISCAL_QUARTER_ID" , "DAYS_IN_CAL_

"SELECTAIS"."PRODUCTS" ("PROD_ID" , "PROD_NAME" , "PROD_DESC" , "PROD_SUBCATEGOR

"SELECTAIS"."CHANNELS" ("CHANNEL_ID" , "CHANNEL_DESC" , "CHANNEL_CLASS" , "CHANN

"SELECTAIS"."COUNTRIES" ("COUNTRY_ID" , "COUNTRY_ISO_CODE" , "COUNTRY_NAME" , "C

"SELECTAIS"."PROMOTIONS" ("PROMO_ID" , "PROMO_NAME" , "PROMO_SUBCATEGORY" , "PRO

"SELECTAIS"."CUSTOMERS" ("CUST_ID" , "CUST_FIRST_NAME" , "CUST_LAST_NAME" , "CUS

"SELECTAIS"."COSTS" ("PROD_ID" , "TIME_ID" , "PROMO_ID" , "CHANNEL_ID" , "UNIT_C

"SELECTAIS"."SALES" ("PROD_ID" , "CUST_ID" , "TIME_ID" , "CHANNEL_ID" , "PROMO_I

"SELECTAIS"."VECTOR$OCI_AUTO_OBJECT_LIST_VECINDEX$113151_113158_0$IVF_FLAT_CENTR

"SELECTAIS"."VECTOR$OCI_AUTO_OBJECT_LIST_VECINDEX$113151_113158_0$IVF_FLAT_CENTR

"SELECTAIS"."OCI_AUTO_FEEDBACK_VECINDEX$VECTAB" ("CONTENT" , "ATTRIBUTES" , "EMB

"SELECTAIS"."VECTOR$OCI_AUTO_FEEDBACK_VECINDEX$113171_113178_0$IVF_FLAT_CENTROID
```

SELECT AIでの確認

```sql
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_AUTO');

PL/SQLプロシージャが正常に完了しました。

SQL> SELECT AI how many customers;

customer_count
--------------
         55500

SQL> select ai please list the user tables;

RESPONSE
--------------------------------------------------------------------------------
Sorry, unfortunately a valid SELECT statement could not be generated for your na
tural language prompt. Here is some more information to help you further:
<以下 略?
```


# 列に大/小文字の区別を設定

Select AIを使用すると、LLMがデータベースおよびLLMから大/小文字を区別しないレスポンスを生成するように指定できます。
大文字と小文字が区別されない問合せを取得するには、case_sensitive_valuesをfalseに設定します。

プロファイルの作成

```sql
BEGIN
 DBMS_CLOUD_AI.CREATE_PROFILE( 
	profile_name =>'OCI_CASE_SENSITIVE_FALSE', 
	attributes =>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"object_list": [{"owner": "SH"}], 
		"oci_compartment_id": "ocid1.compartment.oc1..aaaaaaaa...", 
		"case_sensitive_values" : "false" }
	'); 
END; 
/ 
```

SELECT AIでの確認

```sql
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_CASE_SENSITIVE_FALSE');

PL/SQLプロシージャが正常に完了しました。

SQL> select ai showsql how many customers in San Francisco are married;

RESPONSE
--------------------------------------------------------------------------------
SELECT COUNT(cu."CUST_ID") AS "NUMBER_OF_CUSTOMERS" FROM "SH"."CUSTOMERS" cu WHE
RE UPPER(cu."CUST_CITY") = UPPER('San Francisco') AND cu."CUST_MARITAL_STATUS" =
 'married'
```

WHERE句に「UPPER」関数が含まれています。

参考：case_sensitive_valuesを true に設定した例

```sql
BEGIN
 DBMS_CLOUD_AI.CREATE_PROFILE( 
	profile_name =>'OCI_CASE_SENSITIVE_AUTO', 
	attributes =>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"object_list": [{"owner": "SH"}], 
		"oci_compartment_id": "ocid1.compartment.oc1..aaaaaaaa...", 
		"case_sensitive_values" : "ture" }
	'); 
END; 
/ 

SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_CASE_SENSITIVE_TURE');

PL/SQLプロシージャが正常に完了しました。

SQL> select ai showsql how many customers in San Francisco are married;

RESPONSE
--------------------------------------------------------------------------------
SELECT COUNT(DISTINCT c."CUST_ID") AS "NUMBER_OF_MARRIED_CUSTOMERS"
FROM "SH"."CUSTOMERS" c
WHERE c."CUST_CITY" = 'San Francisco' AND c."CUST_MARITAL_STATUS" = 'Married'
```

# 表アクセスを制限

enforece_object_listをtrueに設定するとAIプロファイルのobject_listで指定された表のみを使用するようにLLMに指示します。

```sql
BEGIN
 DBMS_CLOUD_AI.CREATE_PROFILE( 
	profile_name =>'OCI_ENFORCED_TRUE', 
	attributes =>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"object_list": [
			{"owner": "SELECTAIS", "name": "TIMES"}, 
			{"owner": "SELECTAIS", "name": "CUSTOMERS"}, 
			{"owner": "SELECTAIS", "name": "PRODUCTS"}, 
			{"owner": "SELECTAIS", "name": "SALES"}
		], 
		"enforce_object_list" : "true" }
	'); 
END; 
/ 
```

SELECT AIでの確認

```sql
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_ENFORCED_TRUE');

PL/SQLプロシージャが正常に完了しました。

SQL>  select ai showsql how many customers in San Francisco are married;

RESPONSE
--------------------------------------------------------------------------------
SELECT COUNT(c."CUST_ID") AS "NUMBER_OF_CUSTOMERS" FROM "SELECTAIS"."CUSTOMERS"
c WHERE UPPER(c."CUST_CITY") = UPPER('San Francisco') AND c."CUST_MARITAL_STATUS
" = 'married'


SQL> select ai please list the user tables;
select ai please list the user tables
*
行1でエラーが発生しました。:
ORA-00900: SQL文が無効です。 ヘルプ:
https://docs.oracle.com/error-help/db/ora-00900/
```

参考：enforce_object_listを false に設定した例

```sql
BEGIN
 DBMS_CLOUD_AI.CREATE_PROFILE( 
	profile_name =>'OCI_ENFORCED_FALSE', 
	attributes =>'{
		"provider": "oci", 
		"credential_name": "OCI_GENAI_CRED", 
		"object_list": [
			{"owner": "SELECTAIS", "name": "TIMES"}, 
			{"owner": "SELECTAIS", "name": "CUSTOMERS"}, 
			{"owner": "SELECTAIS", "name": "PRODUCTS"}, 
			{"owner": "SELECTAIS", "name": "SALES"}
		], 
		"enforce_object_list" : "false" }
	'); 
END; 
/ 

PL/SQLプロシージャが正常に完了しました。

SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('OCI_ENFORCED_FALSE');

PL/SQLプロシージャが正常に完了しました。

SQL> select ai showsql how many customers in San Francisco are married;

RESPONSE
--------------------------------------------------------------------------------
SELECT COUNT(DISTINCT c."CUST_ID") AS "NUMBER_OF_CUSTOMERS" FROM "SELECTAIS"."CU
STOMERS" c WHERE UPPER(c."CUST_CITY") = UPPER('San Francisco') AND c."CUST_MARIT
AL_STATUS" = 'married'


SQL> select ai please list the user tables;

TABLE_NAME
--------------------------------------------------------------------------------
CUSTOMERS
PRODUCTS
SALES
TIMES
```

# さいごに

DBMS_CLOUD_AI.CREATE_PROFILEプロシージャのオプションを活用することで、AIプロファイルの制御を細かくできるようになりました。

### 参考情報

- [Examples of Using Select AI](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/select-ai-examples.html#GUID-8BEF8CA8-D98D-41FB-A819-6C2F862099DC)
- [How to help AI models generate better natural language queries](https://blogs.oracle.com/datawarehousing/post/how-to-help-ai-models-generate-better-natural-language-queries-in-autonomous-database)
- [Use natural language to query data in Autonomous Database](https://www.youtube.com/watch?v=2C-wirdC0aw)