Autonomous Database：Azure OpenAI Serviceを利用した自然言語によるクエリ実行（SELECT AI）を試してみた（日本語でも実行できた）

# はじめに

先日のAutonomous Databaseの機能強化で、自然言語からSQLを生成するSELECT AI機能でAzure OpenAI Serviceが利用可能になったので、早速試してみました。

なお、こちらの検証内容は、あくまで2023年11月時点の内容です。
また、実行される環境での動作が必ずしもこの記事の内容と同一であるかは保証致しません。

AIプロバイダとしてOpenAIを使用する場合の記事はこちら。

https://qiita.com/500InternalServerError/items/10d1af43a381514a51dd

AIプロバイダとしてCohereを使用する場合の記事はこちら。

https://qiita.com/500InternalServerError/items/7ba0bd00439075ed15d0

# 1. ユーザの作成とロール/権限の付与
SQLclからadminユーザとしてAutonomous Databaseに接続します。
なお、こちらの環境では環境変数NLS_LANGをJapanese_Japan.AL32UTF8に設定しています。

```
[opc@tools ~]$ sql admin/Demo#1Demo#1@adb


SQLcl: Release 23.2 Production on Fri Nov 10 10:25:59 2023

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Last Successful login time: Fri Nov 10 2023 10:26:01 +09:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.21.0.1.0


SQL> 
```
検証に使用するユーザselect_aiを作成し、必要なロールを付与します。
```
SQL> GRANT DWROLE, UNLIMITED TABLESPACE TO select_ai IDENTIFIED BY Demo#1Demo#1;

権限付与が成功しました。

SQL> 
```
ユーザselect_aiに対して、SELECT AI機能の利用に必要なDBMS_CLOUD_AIパッケージの実行権限を付与します。
```
SQL> GRANT EXECUTE ON DBMS_CLOUD_AI TO select_ai;

権限付与が成功しました。

SQL> 
```

select_ai_userに対して、Azure OpenAIのエンドポイントに対するHTTPアクセスを許可します。

エンドポイントのホスト名はAzureポータルから確認できます。
![スクリーンショット 2023-11-10 10.50.38のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/f55485c8-85f3-88c4-0342-2ac97698357e.png)

DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACEプロシージャを使用して、ネットワークACLを設定します、
```
SQL> BEGIN  
  2      DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
  3*          host => 'myazureopenai777.openai.azure.com',  -- Azureポータルの「キーとエンドポインント」にあるエンドポイントのホスト名
  4           ace  => xs$ace_type(privilege_list => xs$name_list('http'),
  5                               principal_name => 'SELECT_AI',  -- SELECT AIを使用するADBのユーザ名
  6                               principal_type => xs_acl.ptype_db)
  7      );
  8  END;
  9* /

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

SQL> 
```
SQLclを終了します。
```
SQL> exit
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.21.0.1.0から切断されました
[opc@tools ~]$ 
```

# 2. クレデンシャルの作成

SQLclからSELECT_UIユーザとしてAutonomous Databaseに接続します。
```
[opc@tools ~]$ sql select_ai/Demo#1Demo#1@adb


SQLcl: Release 23.2 Production on Fri Nov 10 10:28:59 2023

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Last Successful login time: Fri Nov 10 2023 10:29:01 +09:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.21.0.1.0

SQL> 
```
DBMS_CLOUD.CREATE_CREDENTIALプロシージャで、Azure Opne AIにアクセスするためのクレデンシャルAZURE_OPENAI_CREDを作成します。

パラメータpasswordには、Azureポータルで取得したキー1またはキー2の値を設定します。
![スクリーンショット 2023-11-10 10.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/81e98edf-bf9d-ba5b-2ca6-e41f29d3355a.png)


```
SQL> BEGIN
  2      DBMS_CLOUD.CREATE_CREDENTIAL(
  3          credential_name => 'AZURE_OPENAI_CRED',  -- 作成するクレデンシャルの名前
  4          username        => 'AZUREAI',
  5          password        => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -- Azureポータルからコピーしたキー1またはキー2の値
  6      );
  7  END;
  8* /

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

SQL> 
```
クレデンシャルAZURE_OPENAI_CREDが作成できました。

# 3. AIプロファイルの作成

DBMS_CLOUD_AI.CREATE_PROFILEプロシージャで、SELECT AIで使用するAIプロファイルAZURE_OPENAI_PROFILEを作成します。
・profile_nameには作成するプロファイル名を指定します。
・credential_nameには、先ほど作成したAzure OpenAIにアクセスするためのクレデンシャルを指定します。
・attributesのproviderには、"azure"を指定します。（Azure OpenAI Serviceを使用する場合）
・attributesのazure_deployment_nameには、Azure OpenAIのデプロイ名を指定します。
・attributesのazure_resource_nameには、Azure OpenAIのリソース名を指定します。
・attributesのobject_listには、このプロファイルで使用するスキーマ・オブジェクトの所有者とオブジェクト名を指定します。
この例では、Autonomous Databaseにデフォルトで用意されているスキーマSH内にあるcustomers、sales、produces、countriesの4つの表をこのプロファイルで使用するオブジェクトとして登録しています。
```
SQL> BEGIN
  2     DBMS_CLOUD_AI.CREATE_PROFILE(
  3         profile_name => 'AZURE_OPENAI_PROFILE',
  4         attributes   =>
  5             '{"provider": "azure",
  6               "azure_deployment_name": "MyAzureOpenAIDeployment",
  7               "azure_resource_name": "MyAzureOpenAI777",
  8               "credential_name": "AZURE_OPENAI_CRED",
  9               "object_list": [{"owner": "SH", "name": "customers"},
 10                               {"owner": "SH", "name": "sales"},
 11                               {"owner": "SH", "name": "products"},
 12                               {"owner": "SH", "name": "countries"}]
 13              }'
 14      );
 15  END;
 16* /

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

SQL>
```
AIプロファイルAZURE_OPENAI_PROFILEが作成できました。

# 4. セッションで使用するAIプロファイルの設定
DBMS_CLOUD_AI.SET_PROFILEプロシージャで、現在のセッションで使用するAIプロファイルに先ほど作成したAZURE_OPENAI_PROFILEを設定します。
```
SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('AZURE_OPENAI_PROFILE');

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

SQL> 
```
現在のセッションで使用するAIプロファイルにAZURE_OPENAI_PROFILEが設定されました。

# 5. 自然言語によるクエリ（SELECT AI）の実行
SELECT AIを使用して、自然言語によるクエリを実行してみます。
```
SQL> SELECT AI 顧客は全部で何人いますか;

   TOTAL_CUSTOMERS 
__________________ 
             55500 

SQL> 
```
日本語での自然言語によるクエリが実行できることが確認できました。

SELECT AI SHOWSQLで生成されたSQLを確認します。
```
SQL> SELECT AI SHOWSQL 顧客は全部で何人いますか;

RESPONSE                                                       
______________________________________________________________ 
SELECT COUNT(*) AS total_customers
FROM SELECT_AI.CUSTOMERS    

SQL> 
```
SELECT AI SHOWSQLで生成されたSQLが確認できました。

# まとめ
SELECT AI機能のAIプロバイダーとしてAzure OpenAI Serviceを使用して、自然言語によるクエリの実行ができることが確認できました。

# 参考情報
・[Use Select AI to Generate SQL from Natural Language Prompts](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/sql-generation-ai-autonomous.html)
・[DBMS_CLOUD_AI Package](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-ai-package.html#GUID-000CBBD4-202B-4E9B-9FC2-B9F2FF20F246)
・[DBMS_CLOUD.CREATE_CREDENTIALプロシージャ](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-742FC365-AA09-48A8-922C-1987795CF36A)