はじめに
本記事では、
Autonomous AI DatabaseからSidecar機能でSalesforceに自然言語で問い合わせを行う
こちらの記事のトレース・試行記事です
https://qiita.com/yohattor/items/8aa7151b37bf9dcf8fe2
Salesforce準備
SalesforceのDeveloper Edition環境取得
以下サイトからサインナップし、アカウント作成する
https://www.salesforce.com/products/free-trial/developer/
Salesforce 各情報確認
ユーザ名 取得方法
↓ 個人情報の中の、「ユーザー名」を確認する
ホスト名 取得方法
↓ 「私のドメイン」の中の、
「現在の[私のドメイン]のURL」を確認する
(xxx.my.salesforce.com)
セキュリティトークン 取得
↓ 「セキュリティトークンのリセット」を押下
SOAP API login()を有効化
↓ 「トランスレーションワークベンチ」>「ユーザーインターフェース」内の、
設定のカテゴリの中の、
「SOAP API login()を有効化」にチェック
Autonomous AI Database 設定
Autonomous AI Database 作成
参考
Autonomous AI Database ユーザ作成
参考
↓ Database Actions に Admin としてアクセス
以下実行
CREATE USER sample20260122 IDENTIFIED BY Welcome12345#;
権限付与
↓ 以下実行
GRANT DB_DEVELOPER_ROLE TO sample20260122;
GRANT EXECUTE ON DBMS_CLOUD TO sample20260122;
GRANT EXECUTE ON DBMS_CLOUD_AI TO sample20260122;
GRANT EXECUTE ON DBMS_CLOUD_ADMIN TO sample20260122;
GRANT CREATE DATABASE LINK TO sample20260122;
ALTER USER sample20260122 QUOTA UNLIMITED ON DATA;
GRANT READ, WRITE ON DIRECTORY data_pump_dir TO sample20260122;
クレデンシャル作成
Autonomous AI Database から Salesforce に接続するためのクレデンシャルを作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'SF_CRED', -- 作成するクレデンシャル名(任意)
username => 'XXXXXXXXXX@force.com', -- Salesforceのログインユーザ名
password => 'XXXXXXXXXX' --パスワード(任意)
);
END;
↓ 例
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'SF_CRED',
username => 'xxxx@agentforce.com',
password => 'xxxx'
);
END;
DB Link作成 / ADB<->Salesforce
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;
DB Link接続確認
↓ 以下実施。クエリ実行ができればok
元記事コマンドに脱字があったようです
SELECT id, name
FROM account@SALESFORCE_LINK
FETCH FIRST 10 ROWS ONLY;
OCI生成AIサービスのAPIキー取得
↓ 利用するリージョンに注意し、OCI生成サービスを利用する
右上のプロファイル > 「ユーザー設定」 > リソースの「APIキー」選択 > 「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 のアカウント情報と出荷情報を結合したビューを作成
元記事と少々異なり最初に、ビュー「sf_accounts_view」を作成しておく
CREATE OR REPLACE VIEW sf_accounts_view AS
SELECT id, name
FROM account@SALESFORCE_LINK;
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": "admin", "name": "v_sf_shipments"}
]
}'
);
END;
参考 : コメント確認用
SELECT
TABLE_NAME,
COLUMN_NAME,
COMMENTS
FROM user_col_comments
WHERE table_name='V_SF_SHIPMENTS';
SELECT
table_name,
comments
FROM user_tab_comments
WHERE table_name='V_SF_SHIPMENTS';
自然言語クエリ実行(ここからが本番)
自分がハマった事象
↓以下を実行
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて。',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
↓実行結果
あらぬビューを見にいっている.....
Sorry,
unfortunately a valid SELECT statement could not be generated for your natural language prompt.
Here is some more information to help you further:
SELECT COUNT(*) AS "Salesforce取引先の数"
FROM "Salesforce"."取引先"
Exception encountered: ORA-00942: 表またはビュー "Salesforce"."取引先"は存在しません
↓以下を実行
プロンプトで悪あがき
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforceの取引先の数を数えて。ビューはv_sf_shipmentsを参照するといいと思いますよ',
profile_name => 'GENAI_COHERE2',
action => 'runsql'
)
FROM dual;
↓実行結果
まさかの成功
[
{
"Salesforce取引先の数" : 10
}
]
↓showsqlを試してみる
SELECT DBMS_CLOUD_AI.GENERATE(
prompt => 'Salesforce取引先の数を数えて。ビューはv_sf_shipmentsを参照するといいと思いますよ',
profile_name => 'GENAI_COHERE2',
action => 'showsql'
)
FROM dual;
↓実行結果
SELECT COUNT(*) AS "Salesforce取引先の数"
FROM v_sf_shipments
状況備忘録
- 最初なぜかカラムのコメントが入っていなかった
- 改めてコメント作成し試行するも結果はかわらず...
- プロファイルが悪さをしている?のかと思い、ownerをsampleにしていたがadminに変更したところ、プロンプトにわざわざビューを指定せずとも回答が返ってきた




