目的
本記事の目的は、Salesforce に存在するデータに対して Autonomous AI Database の Select AI Sidecar 機能を活用し、自然言語クエリを実行することです。
具体的には、Salesforce に登録されている顧客データのうち、出荷遅延が発生している顧客を一覧で取得するというシナリオを、自然言語クエリで実行することを試しました。
実行手順概要
- Salesforce 準備
- Salesforce 情報を確認
- Autonomous AI Database 準備
- Autonomous AI Database を作成
- ユーザー作成・権限付与
- Autonomous AI Database から Salesforce への接続
- クレデンシャル作成
- DBLINK 作成
- API 接続を有効化
- DBLINK 接続確認
- OCI 生成 AI サービスの準備
- OCI 生成 AI サービスの API キー取得
- OCI 生成 AI サービス接続用クレデンシャル作成
- Select AI(自然言語クエリ)の実行
- ビュー作成
- プロファイル作成
- 自然言語クエリ実行
具体的実行手順
Saleforce情報を確認する
以下の情報を Salesforce 上で確認し、メモしておきます。
Salesforce 側の情報
- ログインユーザー名
- パスワード
- Security Token
- My Domain のホスト名(
xxx.my.salesforce.com)
Autonomous AI Database を立ち上げる
以下の公式ドキュメントを参考に Autonomous Database を作成します。
ユーザー作成
以下を参考に、Database Actions に Admin としてアクセスし、新規ユーザーを作成します。
今回は sample というユーザーを作成しました。
権限付与
GRANT DB_DEVELOPER_ROLE TO sample;
GRANT EXECUTE ON DBMS_CLOUD TO sample;
GRANT EXECUTE ON DBMS_CLOUD_AI TO sample;
GRANT EXECUTE ON DBMS_CLOUD_ADMIN TO sample;
GRANT CREATE DATABASE LINK TO sample;
ALTER USER sample QUOTA UNLIMITED ON DATA;
GRANT READ, WRITE ON DIRECTORY data_pump_dir TO sample;
クレデンシャル作成
Autonomous AI Database から Salesforce に接続するためのクレデンシャルを作成します。BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'SF_CRED', -- 作成するクレデンシャル名(任意)
username => 'XXXXXXXXXX@force.com', -- Salesforceのログインユーザ名
password => 'XXXXXXXXXX' --パスワード(任意)
);
END;
DB Link作成
BEGIN
DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK(
db_link_name => 'SALESFORCE_LINK', -- 作成するデータベース・リンク名(任意)
hostname => 'XXXXXXXX.my.salesforce.com', --Salesforceのホスト名
port => '19937',
service_name => 'salesforce',
ssl_server_cert_dn => null,
credential_name => 'SF_CRED', -- 使用するクレデンシャル名(②で指定した名前)
gateway_params => JSON_OBJECT(
'db_type' value 'salesforce',
'security_token' value 'XXXXXXXXX' -- セキュリティトークン
)
);
END;
API接続を有効化
Salesforceの設定画面で「SOAP API Loginを有効化」にチェックを入れます。
DB Link接続確認
以下のクエリが実行できれば、Salesforce との接続は成功です。SELECT id, name
FROM account@SALESFORCELINK
FETCH FIRST 10 ROWS ONLY;
OCI生成AIサービスのAPIキー取得
今回は 大阪リージョン(ap-osaka-1) の OCI 生成 AI サービスを利用します。
OCI コンソールから API キーを作成し、以下の情報を控えておきます。
- user_ocid
- tenancy_ocid
- fingerprint
- private_key
OCI 生成 AI サービス接続用クレデンシャル作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OCI_GENAI_CRED',
user_ocid => 'ocid1.user.XXXXXXXX',
tenancy_ocid => 'ocid1.tenancy.XXXXXXXXXX',
private_key => '-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2+8WCKbAOR/0m
<中略>
HoqpMa3S46c+kaDK15rZc08=
-----END PRIVATE KEY-----',
fingerprint => 'dd:9e:b8:bd:73:1d:e4:0a:f2:aa:ac:00:be:a6:a8:dd'
);
END;
デモデータ準備&ビューを作成
Salesforce のアカウント情報と出荷情報を結合したビューを作成します。
CREATE TABLE shipment (
shipment_id NUMBER GENERATED BY DEFAULT AS IDENTITY
CONSTRAINT shipment_pk PRIMARY KEY,
account_sf_id VARCHAR2(18) NOT NULL,
-- Salesforce Account ID(sf_account_view.account_id と結合)
status VARCHAR2(30) NOT NULL,
-- SHIPPED / DELAYED などの出荷ステータス
delay_reason VARCHAR2(400),
-- 遅延理由(DELAYED のときのみ使用)
shipped_date DATE
-- 出荷日
);
INSERT INTO shipment (
account_sf_id,
status,
delay_reason,
shipped_date
)
SELECT
a.id,
/* 出荷ステータス */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN 'DELAYED'
ELSE 'SHIPPED'
END AS status,
/* 遅延理由(DELAYED のときのみ) */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN
CASE
WHEN MOD(ROWNUM, 3) = 0 THEN '部品供給の遅延'
WHEN MOD(ROWNUM, 3) = 1 THEN '輸送トラブル'
ELSE '倉庫内作業の遅れ'
END
ELSE NULL
END AS delay_reason,
/* 出荷日 */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN SYSDATE - MOD(ROWNUM, 7)
ELSE SYSDATE - 1
END AS shipped_date
FROM sf_accounts_view a
FETCH FIRST 10 ROWS ONLY;
CREATE OR REPLACE VIEW v_sf_shipments AS
SELECT
a.id,
a.name,
s.shipment_id,
s.status,
s.delay_reason,
s.shipped_date
FROM
sf_accounts_view a
JOIN shipment s
ON s.account_sf_id = a.id;
コメント記入(任意)
テーブルやカラムにコメントを追加することで、AI がより正確に自然言語クエリを解釈できるようになります。
COMMENT ON TABLE v_sf_shipments IS
'Salesforceの取引先(Account)と出荷情報を結合したビュー。
1行が1件の出荷を表す。
出荷が遅延している取引先を確認する用途でよく使用され、
出荷遅延とは status が DELAYED のレコードを意味する。';
COMMENT ON COLUMN v_sf_shipments.id IS
'Salesforce Account ID。取引先(Salesforceアカウント)を一意に識別するID';
COMMENT ON COLUMN v_sf_shipments.name IS
'Salesforceの取引先名(アカウント名、会社名)。
自然言語で「取引先」「アカウント」と指定された場合はこの列を指す。';
COMMENT ON COLUMN v_sf_shipments.shipment_id IS
'出荷を一意に識別するID';
COMMENT ON COLUMN v_sf_shipments.status IS
'出荷ステータス。
値は SHIPPED または DELAYED。
DELAYED は出荷遅延を表す。
自然言語で「出荷が遅延している」「出荷遅延」「遅れている出荷」
と指定された場合は、status = ''DELAYED'' の条件を意味する。';
COMMENT ON COLUMN v_sf_shipments.delay_reason IS
'出荷が遅延している理由。
出荷ステータスが ''DELAYED'' の場合に設定される。
自然言語で「遅延理由」と指定された場合はこの列を指す。';
COMMENT ON COLUMN v_sf_shipments.shipped_date IS
'出荷日';
Select AI(自然言語クエリ)に向けてプロファイルを作成
作成したプロファイルを使用して、自然言語クエリを実行します。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE2',
'{
"provider": "oci",
"credential_name": "OCI_GENAI_CRED",
"model":"cohere.command-r-08-2024",
"oci_apiformat":"COHERE",
"region": "ap-osaka-1",
"object_list": [
{"owner": "sample", "name": "v_sf_shipments"}
]
}'
);
END;
自然言語クエリ実行
作成したプロファイルを使用して、自然言語クエリを実行します。
パターン①「Salesforce取引先の数を数えて。」
RUNSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて。',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OCI_GENAI_CRED',
user_ocid => 'ocid1.user.XXXXXXXX',
tenancy_ocid => 'ocid1.tenancy.XXXXXXXXXX',
private_key => '-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2+8WCKbAOR/0m
<中略>
HoqpMa3S46c+kaDK15rZc08=
-----END PRIVATE KEY-----',
fingerprint => 'dd:9e:b8:bd:73:1d:e4:0a:f2:aa:ac:00:be:a6:a8:dd'
);
END;
デモデータ準備&ビューを作成
Salesforce のアカウント情報と出荷情報を結合したビューを作成します。CREATE TABLE shipment (
shipment_id NUMBER GENERATED BY DEFAULT AS IDENTITY
CONSTRAINT shipment_pk PRIMARY KEY,
account_sf_id VARCHAR2(18) NOT NULL,
-- Salesforce Account ID(sf_account_view.account_id と結合)
status VARCHAR2(30) NOT NULL,
-- SHIPPED / DELAYED などの出荷ステータス
delay_reason VARCHAR2(400),
-- 遅延理由(DELAYED のときのみ使用)
shipped_date DATE
-- 出荷日
);
INSERT INTO shipment (
account_sf_id,
status,
delay_reason,
shipped_date
)
SELECT
a.id,
/* 出荷ステータス */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN 'DELAYED'
ELSE 'SHIPPED'
END AS status,
/* 遅延理由(DELAYED のときのみ) */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN
CASE
WHEN MOD(ROWNUM, 3) = 0 THEN '部品供給の遅延'
WHEN MOD(ROWNUM, 3) = 1 THEN '輸送トラブル'
ELSE '倉庫内作業の遅れ'
END
ELSE NULL
END AS delay_reason,
/* 出荷日 */
CASE
WHEN MOD(ROWNUM, 2) = 0 THEN SYSDATE - MOD(ROWNUM, 7)
ELSE SYSDATE - 1
END AS shipped_date
FROM sf_accounts_view a
FETCH FIRST 10 ROWS ONLY;
CREATE OR REPLACE VIEW v_sf_shipments AS
SELECT
a.id,
a.name,
s.shipment_id,
s.status,
s.delay_reason,
s.shipped_date
FROM
sf_accounts_view a
JOIN shipment s
ON s.account_sf_id = a.id;
コメント記入(任意)
テーブルやカラムにコメントを追加することで、AI がより正確に自然言語クエリを解釈できるようになります。COMMENT ON TABLE v_sf_shipments IS
'Salesforceの取引先(Account)と出荷情報を結合したビュー。
1行が1件の出荷を表す。
出荷が遅延している取引先を確認する用途でよく使用され、
出荷遅延とは status が DELAYED のレコードを意味する。';
COMMENT ON COLUMN v_sf_shipments.id IS
'Salesforce Account ID。取引先(Salesforceアカウント)を一意に識別するID';
COMMENT ON COLUMN v_sf_shipments.name IS
'Salesforceの取引先名(アカウント名、会社名)。
自然言語で「取引先」「アカウント」と指定された場合はこの列を指す。';
COMMENT ON COLUMN v_sf_shipments.shipment_id IS
'出荷を一意に識別するID';
COMMENT ON COLUMN v_sf_shipments.status IS
'出荷ステータス。
値は SHIPPED または DELAYED。
DELAYED は出荷遅延を表す。
自然言語で「出荷が遅延している」「出荷遅延」「遅れている出荷」
と指定された場合は、status = ''DELAYED'' の条件を意味する。';
COMMENT ON COLUMN v_sf_shipments.delay_reason IS
'出荷が遅延している理由。
出荷ステータスが ''DELAYED'' の場合に設定される。
自然言語で「遅延理由」と指定された場合はこの列を指す。';
COMMENT ON COLUMN v_sf_shipments.shipped_date IS
'出荷日';
Select AI(自然言語クエリ)に向けてプロファイルを作成
作成したプロファイルを使用して、自然言語クエリを実行します。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE2',
'{
"provider": "oci",
"credential_name": "OCI_GENAI_CRED",
"model":"cohere.command-r-08-2024",
"oci_apiformat":"COHERE",
"region": "ap-osaka-1",
"object_list": [
{"owner": "sample", "name": "v_sf_shipments"}
]
}'
);
END;
自然言語クエリ実行
作成したプロファイルを使用して、自然言語クエリを実行します。パターン①「Salesforce取引先の数を数えて。」
RUNSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて。',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
SHOWSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて',
profile_name => 'GENAI_COHERE2',
action => 'showsql'
)
FROM dual;
NARRATEを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて。',
profile_name => 'GENAI_COHERE2',
action => 'narrate'
)
FROM dual;
パターン②「出荷が遅延している取引先(Salesforceアカウント)を一覧で出して」
RUNSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している取引先(Salesforceアカウント)を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
SHOWSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している取引先(Salesforceアカウント)を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'showsql'
)
FROM dual;
NARRATEを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している取引先(Salesforceアカウント)を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'narrate'
)
FROM dual;
パターン③「出荷が遅延している理由を一覧で出して」
RUNSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している理由を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
SHOWSQLを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している理由を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'showsql'
)
FROM dual;
NARRATEを実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => '出荷が遅延している理由を一覧で出して。',
profile_name => 'GENAI_COHERE2',
action => 'narrate'
)
FROM dual;
まとめ
本記事では、Oracle Autonomous AI Database の SELECT AI - Sidecar 機能を使って、Salesforceデータと組み合わせて自然言語検索することを検証しました。検証の結果、以下のことが確認出来ました。
- ユーザーは SQL を直接書かずに自然言語で質問できる
- runsql、showsql、narrateなどのアクションを通じて、外部DB上のデータを柔軟に扱える
- SQLに詳しくないユーザーでも、マルチクラウド環境のデータにアクセスしやすくなる
既存のSalesforceを活かしつつ、Autonomous AI Databaseをハブとした統合的なNL2SQLシステムを構築できることが分かりました。
参考資料











