はじめに
Oracle Autonomous AI Database(ADB) には、データベースの内部でAI Agentを構築できる「Select AI Agent」という機能があります。
今回はこの機能を使って、DB上のデータを参照しながら処理を実行するAI Agentを作ってみます。
参照するデータはADBの AI Proxy Database を活用し、ADB上のデータだけでなくADB外のPostgreSQLのデータもADBからAgentが参照できるように構成します。
(AI Proxy Databaseの検証は別の記事で実施しているのでそちらもご参照ください。)
このようにデータソースをADBに集約し、データの近くでAI Agentを動かすことで、シンプルな構成でAI活用基盤が構成できます。
この記事でやること
この記事で実施することは以下の3つです。
- DBの情報を検索するAgentの構築
- メール送信を行うAgentの構築
- 2つのAgent同士を組み合わせたチームとして動作
単純に動かすだけでなく、簡単ですがうまくいかなかった点やチューニングのポイントも含めて整理しました。
環境構築
早速環境構築を進めていきましょう。
前提
環境はこちらの記事の検証で利用したものを流用しており、STEP2までの構築とStep3-3のADBへのデータ投入が完了した状態と同等です。
ですので、ADBおよびPostgreSQL環境の構築設定とベースとなるデータの投入は完了している状態です。
PostgreSQL上のデータ
| 項目 | 内容 |
|---|---|
| スキーマ名 | order_system |
| inventory |
100件(製品マスタ) 製品ID( MTR/SNS/CB)、在庫数(0〜500)、倉庫名(横浜/名古屋/福岡) |
| orders |
1,000件(受注履歴)。過去30日間の注文、ステータス(Shipped/Pending/Cancelled)、顧客ID |
ADB上のデータ
| 項目 | 内容 |
|---|---|
| スキーマ名 | AI_USER |
| CUSTOMERS |
物理テーブル(ADB上) 顧客マスタ。顧客名( CUST_NAME: ギガテンドー等)、ランク、連絡先(CONTACT_NAME)、メール(EMAIL) |
| INVENTORY |
View(DBLINKでPostgreSQL参照) 製品マスタ。製品ID( PROD_ID)、在庫数(STOCK_QTY: 0〜500)、倉庫名(WH_NAME: 横浜/名古屋/福岡) |
| ORDERS |
View(DBLINKでPostgreSQL参照) 受注履歴。注文ID( ORD_ID)、製品ID(PROD_ID)、数量(QTY)、ステータス(Shipped/Pending/Cancelled) |
Table/VIEWの情報
SQL> SELECT column_name, data_type, data_length
2 FROM user_tab_cols
3 WHERE table_name = 'ORDERS'
4* ORDER BY column_id;
COLUMN_NAME DATA_TYPE DATA_LENGTH
______________ ____________ ______________
ORD_ID NUMBER 22
PROD_ID VARCHAR2 20
QTY NUMBER 22
ORD_DATE DATE 7
STATUS VARCHAR2 20
CUST_ID VARCHAR2 20
6 rows selected.
SQL> SELECT column_name, data_type, data_length
2 FROM user_tab_cols
3 WHERE table_name = 'INVENTORY'
4* ORDER BY column_id;
COLUMN_NAME DATA_TYPE DATA_LENGTH
______________ ____________ ______________
PROD_ID VARCHAR2 20
STOCK_QTY NUMBER 22
WH_NAME VARCHAR2 50
UPDATE_AT DATE 7
SQL> SELECT column_name, data_type, data_length
2 FROM user_tab_cols
3 WHERE table_name = 'CUSTOMERS'
4* ORDER BY column_id;
COLUMN_NAME DATA_TYPE DATA_LENGTH
_______________ ____________ ______________
CUST_ID VARCHAR2 10
CUST_NAME VARCHAR2 100
REGION VARCHAR2 50
RANK VARCHAR2 20
CONTACT_NAME VARCHAR2 100
EMAIL VARCHAR2 255
6 rows selected.
構築作業
以下の流れで実施します。
- 下準備
- DB検索用Agentの作成
- メール送信用Agentの作成
- 上記2タイプのAgentを組み合わせたAgent Temaの作成
下準備
Agent作成の前にデータ投入や権限付与などの下準備をします。
データの投入
ADB上のCUSTOMERSテーブルに列を追加し、担当者とそのメールアドレスの情報を投入します。
担当者のメールアドレスとして私のメールアドレスを登録しています。
データがないときの動作用にデータの一つはNullを入れておきます。
SQL> UPDATE CUSTOMERS
2 SET CONTACT_NAME = '織田信長',
3 EMAIL = '*****@gmail.com'
4* WHERE CUST_NAME = 'ヨツビシ交易';
1 row updated.
SQL> UPDATE CUSTOMERS
2 SET CONTACT_NAME = '豊臣秀吉',
3 EMAIL = '*****@gmail.com'
4* WHERE CUST_NAME = 'ミツカド決済銀行';
1 row updated.
SQL> UPDATE CUSTOMERS
2 SET CONTACT_NAME = '徳川家康',
3 EMAIL = NULL
4* WHERE CUST_NAME = 'トヨノキ自走車';
1 row updated.
SQL> Commit;
Commit complete.
Agent作成権限の付与
Select AI Agentを作成するための権限を付与していきます。admin等の管理者権限を持つユーザーでログインし、作成済みのai_userに付与します。
GRANT EXECUTE on DBMS_CLOUD_AI_AGENT to ai_user;
Grant succeeded.
クレデンシャルの作成
LLMを利用する用のクレデンシャルを作成します。好きな名前をつけてください。私はOCI_CREDで作成しました。
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => '好きな名前',
user_ocid => 'ユーザーのOCID',
tenancy_ocid => 'テナンシのOCID',
private_key => 'APIの秘密鍵',
fingerprint => 'APIキーのフィンガープリント'
);
END;
/
プロファイルの作成
Select AI Agentの利用には、Agentがどのクレデンシャルを使ってどのLLMにアクセスし、どのオブジェクトを利用するかを指定するプロファイルの作成が必要です。
Agent用プロファイルの作成
AI Agent用のプロファイルも作成しておきます。
このプロファイルを後ほど作成するAgentにセットしてあげることで、AgentがLLMとオブジェクトへのアクセスが可能になります。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
profile_name =>'NL2SQL_PROFILE',
attributes =>'{"provider": "oci",
"credential_name": "OCI_CRED",
"region":"us-ashburn-1",
"model": "xai.grok-4",
"object_list": [
{"owner": "ai_user", "name": "ORDERS"},
{"owner": "ai_user", "name": "INVENTORY"},
{"owner": "ai_user", "name": "CUSTOMERS"}
]
}'
);
END;
/
DB検索Agentの作成
それではAgentを作成します。
ADBには組み込み済みのツールが存在しており、Agentはこれらのツールを使ってタスクを実行することができます。当然、自分でツールを作成することも可能ですが、今回は組み込み済みのツールを利用するAgentを作成します。
組み込み済みツールには以下があります。
組み込みツール
| 項目 | 内容 |
|---|---|
| SQL |
データベース・クエリ実行 自然言語をSQLに変換し、DB内のテーブルやビューからデータを取得・分析する。 |
| RAG |
ベクトル検索による回答生成 OCI OpenSearch等のベクトル・ストアと連携し、マニュアル等の非構造化データから回答を探す。 |
| WEBSEARCH |
外部検索エンジン連携 Google Search等を利用して、最新のニュースや市場価格などDB外の情報を取得する。 |
| NOTIFICATION |
外部通知(EMAIL / SLACK) 生成された回答や特定のデータを、メール送信(EMAIL)やSlack(SLACK)への投稿を通じて外部へ配信する。 |
NL2SQLを実行するAgentの構築
まずはNL2SQLの簡単なAgent構築から試しましょう。
NL2SQLのAgentは事前構成済みのため、簡単に設定が可能です。
必要な作業としては以下の流れです。
| Step | 内容 |
|---|---|
| 1. Agent Toolの作成 | Agentに使用させるツールを定義します。組み込み済みのSQLツールを使用します。 |
| 2. Taskの作成 | Agentが実行するタスクを定義します。何をどのツールで処理するのかを指定するイメージです。 |
| 3. Agentの作成 | AgentにAIプロファイルと役割を設定します。 |
| 4. Agent Teamの作成 | どのAgentがどのタスクをどういう順で実施するのかを定義します。 |
| 5. 有効化 | Agent Teamが動作するできるように有効化します。 |
1. NL2SQL Agent Toolの作成
Customersテーブルの顧客情報を参照するAgentのツールを作成します。NL2SQL_TOOLという名前にします。
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
tool_name => 'NL2SQL_TOOL',
attributes => '{
"instruction": "顧客の担当者情報を参照する際に利用",
"tool_type": "SQL",
"tool_params": {"profile_name": "NL2SQL_PROFILE"}}'
);
END;
/
2. タスクの作成
ユーザーの問い合わせに対してNL2SQLツールを使って回答をするというタスクを作成します。SQL_TASKというタスクにします
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TASK(
task_name => 'SQL_TASK',
attributes =>
'{
"instruction": "ユーザからの質問: {query}。",
"tools": ["NL2SQL_TOOL"],
"enable_human_tool": "False"
}'
);
END;
/
3. Agentの作成
AIプロファイルとロールを指定しAgentを作成します。CUST_SEARCH_AGENTという名前にしました。
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
agent_name => 'CUST_SEARCH_AGENT',
attributes => '{"profile_name": "NL2SQL_PROFILE",
"role": "データベース内のテーブルから顧客の名前や連絡先などの顧客情報を取得"
}'
);
END;
/
4. Agentチームの作成
作成したAgentにタスクを割り当てチーム化します。(今は1つのAgentですが。。)
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
team_name => 'CUSTOMER_SEARCH_AGENT_TEAMS',
attributes => '{"agents": [
{"name":"CUST_SEARCH_AGENT",
"task":"SQL_TASK"}],
"process": "sequential"
}');
END;
/
5. 有効化
忘れずに有効化しましょう。
EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('CUSTOMER_SEARCH_AGENT_TEAM');
Agentに仕事を頼んでみる
ひとまずNL2SQL_Agentの設定が完了しました。
動作確認をしてみましょう。
Agentを呼び出すには
select ai agent + プロンプト
と入力します。
まずはAgentの役割を確認します。
SQL> select ai agent あなたは誰ですか;
RESPONSE
________________________________________________________________
私はCUST_SEARCH_AGENTです。データベースから顧客の名前や連絡先などの情報を取得するためのエージェントです。
きちんと役割を果たすか確認してみましょう。
SQL> select ai agent ヨツビシ交易の担当者とメールアドレス教えて;
RESPONSE
_______________________________________________________
ヨツビシ交易の担当者は織田信長さんで、メールアドレスはxxxx@gmail.comです。
問題なさそうです。
Null値を入れたところはどうでしょうか。
SQL> select ai agent トヨノキ自走車の担当者とメールアドレス教えて;
RESPONSE
________________________________________________________________________
トヨノキ自走車の担当者は徳川家康さんですが、メールアドレスはデータベースに登録されていません。追加情報を必要とする場合はお知らせください。
きちんと動作していますね!
参考: Agentに関係のない仕事を頼むとどうなるか
現在作成したAgentはCUSTOMERSテーブルを参照する役割を与えています。しかし、クレデンシャルにはCUSTOMERSテーブル以外もオブジェクトとして指定しており、アクセスが可能な状態です。
全然関係のないテーブルにアクセスさせてみるとどうなるのか確認してみましょう。
PostgreSQL上のORDERSテーブルをAI Proxy Databaseで参照可能な状態になっていますので、このORDERSテーブルへのアクセスが必要な問い合わせをCUSTOMER_SEARCH_AGENT_TEAMに投げてみます。
SQL> select ai agent オーダーは何件ある?;
RESPONSE
____________________
オーダーの総件数は1000件です。
-- SQLで確認
SQL> SELECT COUNT(*) AS total_orders FROM ORDERS;
TOTAL_ORDERS
_______________
1000
きちんと正しい結果を返してくれています。
SQL検索ツールしか渡していないので検索という枠は出ませんが、Agentがリモート表に対するアクセスも可能であること、定義した仕事に関連しないテーブルでもある程度融通を利かせて対応してくれることがわかりました。
メールエージェントの作成
先ほどのNL2SQL AgentはDBから情報を参照するAgentでした。
次はNotificationツールのEMAILを利用するメール配信Agentを試してみたいと思います。
Agent作成の流れは先ほどと同様ですが、メールサーバーの設定を別途実施します。
こちらを参考に進めます。
ADBからのメール送信の設定
まずはADBから手動でメールを送れるように設定を進めます。
SMTPの構成
OCIコンソールのナビゲーションメニューを開き、「開発者サービス」を選択します。「アプリケーション統合」の下にある「メール配信」を選択します。

画面左のメニューから「構成」を選択すると各種送信情報が確認できます。

SMTP資格証明の作成
メールの送信時の認証のためのSMTP資格証明を生成します。
OCIコンソールにて画面右上の「プロファイル」から「アイデンティティドメイン」を選択します。

現在のドメインを選択し、自分のユーザー名を選択してください。


すると、SMTP資格証明というタブが出てくるので選択し、資格証明を生成します。説明は適当に入れてください。

生成されたユーザー名とパスワードを保管しておきます。

電子メール配信の承認済送信者を作成
送信元となるメールアドレスを登録し、承認済み送信者とします。
再び「開発者サービス」>「電子メール配信」を選択し、承認済み送信者を設定します。

Access Control Entry(アクセス制御エントリ)の作成
Access Control Entry(ACE)はデータベースから、「どのユーザーが」「どこの外部サイト(ホスト)の」「どのポート」に通信していいかを定義するものです。
プロシージャの実行権限付与
adminでログインしてai_userに権限を与えます。
SQL> GRANT EXECUTE ON DBMS_NETWORK_ACL_ADMIN TO AI_USER;
Grant succeeded.
プロシージャの実行
AI_USERにてACEの設定を実施しました。
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => 'smtp送信情報のエンドポイント',
lower_port => 587,
upper_port => 587,
ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
principal_name => 'AI_USER',
principal_type => xs_acl.ptype_db));
END;
/
メール送信用PL/SQLの作成
SEND_MAILというプロシージャーを作成しコンパイルします。
マニュアルのコードのままだと日本語で文字化けするため少し改良しています。
CREATE OR REPLACE PROCEDURE SEND_MAIL (
msg_to varchar2,
msg_subject varchar2,
msg_text varchar2 )
IS
mail_conn utl_smtp.connection;
-- 【ここを書き換え!】
username varchar2(1000):= '(OCIで発行したSMTPユーザー名)';
passwd varchar2(100) := '(OCIで発行したSMTPパスワード)';
msg_from varchar2(100) := '(承認済送信者のメールアドレス)';
mailhost VARCHAR2(100) := 'smtp.email.ap-tokyo-1.oci.oraclecloud.com'; -- 自分のリージョン
-- 【書き換えここまで】
BEGIN
mail_conn := UTL_smtp.open_connection(mailhost, 587);
utl_smtp.starttls(mail_conn);
UTL_SMTP.AUTH(mail_conn, username, passwd, schemes => 'PLAIN');
utl_smtp.mail(mail_conn, msg_from);
utl_smtp.rcpt(mail_conn, msg_to);
UTL_smtp.open_data(mail_conn);
-- ヘッダー部分:UTF-8であることを宣言
UTL_SMTP.write_data(mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || UTL_TCP.crlf);
UTL_SMTP.write_data(mail_conn, 'To: ' || msg_to || UTL_TCP.crlf);
UTL_SMTP.write_data(mail_conn, 'From: ' || msg_from || UTL_TCP.crlf);
-- 日本語の件名対応
UTL_SMTP.write_raw_data(mail_conn, utl_raw.cast_to_raw('Subject: ' || msg_subject || UTL_TCP.crlf));
UTL_SMTP.write_data(mail_conn, 'Content-Type: text/plain; charset=UTF-8' || UTL_TCP.crlf);
UTL_SMTP.write_data(mail_conn, 'Content-Transfer-Encoding: 8bit' || UTL_TCP.crlf || UTL_TCP.crlf);
-- 本文:RAWデータとして送信することで文字化けを防ぐ
UTL_SMTP.write_raw_data(mail_conn, utl_raw.cast_to_raw(msg_text || UTL_TCP.crlf));
UTL_smtp.close_data(mail_conn);
UTL_smtp.quit(mail_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_smtp.quit(mail_conn);
dbms_output.put_line('Error: ' || sqlerrm);
END;
/
メールを送ってみる
コンパイルしたPL/SQLを実行してメールを送ってみましょう。
今回は私のGmailアドレスに送ります。
BEGIN
SEND_MAIL(
msg_to => 'xxx@gmail.com', -- ★ここに自分の受信用アドレス
msg_subject => 'ADBからのデモメール成功',
msg_text => 'Cust_Searchエージェントの準備が整いました!'
);
END;
/
Gmailを確認してみましょう。

無事に届いていました。(迷惑メールフォルダに。。)
これにてADBからメールを送信する準備が整いました。
次はAgentからの送信です。
Agentからのメール送信
次にメール送信Agentからメールを送信するように構成します。作成のStepはSQL検索Agentと同様です。
Agentプロファイルの作成
先ほどのDB検索Agent同様にプロファイルの作成から実施します。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
profile_name =>'MAIL_AGENT_PROFILE',
attributes =>'{"provider": "oci",
"credential_name": "OCI_CRED",
"region":"us-ashburn-1",
"model": "xai.grok-4",
"object_list": [
{"owner": "ai_user", "name": "ORDERS"},
{"owner": "ai_user", "name": "INVENTORY"},
{"owner": "ai_user", "name": "CUSTOMERS"}
]
}'
);
END;
/
メール用のクレデンシャル作成
SMTPアクセス用のクレデンシャルを作成します。
ユーザー名とパスワードは先ほどのメール設定時に生成したSMTPの資格証明を入力します。
EMAIL_CREDという名前にしました。
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'EMAIL_CRED',
username => '<SMTP username>',
password => '<SMTP password>');
END;
/
SMTPアクセス用ACEの設定
AI_USERにてACEの設定を実施します。先ほど実施済みならSKIPして問題ないです。
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => 'smtp送信情報のエンドポイント',
lower_port => 587,
upper_port => 587,
ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
principal_name => 'AI_USER',
principal_type => xs_acl.ptype_db));
END;
/
Agent Toolの作成
メール送信を実施するツールを作成します。EMAILというツールを作成しました。
-- 既存のToolがある場合は削除
-- EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('EMAIL');
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
tool_name => 'EMAIL',
attributes => '{"tool_type": "NOTIFICATION",
"tool_params": {"notification_type" : "EMAIL",
"credential_name": "EMAIL_CRED",
"recipient": "宛先アドレス@gmail.com",
"smtp_host": "smtp.email.us-ashburn-1.oci.oraclecloud.com",
"sender": "送信元アドレス@gmail.com"}
}'
);
END;
/
Agent Taskの作成
Agentにやってもらうタスクを指定します。
Generata_Email_Taskというタスクを作成し、ツールにはEMAILツールを指定します。
-- 既存のTASKがある場合は削除
-- EXEC DBMS_CLOUD_AI_AGENT.DROP_TASK('Generate_Email_Task');
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TASK(
task_name => 'Generate_Email_Task',
attributes => '{"instruction": "指定されたアドレス宛に、日本語のメールを作成してください。",
"tools" : ["EMAIL"],
"enable_human_tool" : "false"
}'
);
END;
/
Agent作成
MAIL_AGENTというAgentを作成しました。ToolにはEMAIL、プロファイルにはMAIL_AGENT_PROFILEを指定します。
-- 既存のAGENTがある場合は削除
-- EXEC DBMS_CLOUD_AI_AGENT.DROP_AGENT('MAIL_AGENT');
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
agent_name => 'MAIL_AGENT',
attributes => '{
"profile_name": "MAIL_AGENT_PROFILE",
"role": "あなたはメール送信の実行責任者です。ユーザーがプロンプトで指定したメールアドレスへのメール送信を実行します。",
"tools": [
{
"tool_name": "EMAIL",
"description": "メール送信ツール。"
}
]
}'
);
END;
/
Agent Team作成
CUSTOMER_NOTIFICATION_TEAMというAgentチームを作成します。
-- 既存のTEAMがある場合は削除
--EXEC DBMS_CLOUD_AI_AGENT.DROP_TEAM('EMAIL_AGENT_TEAM');
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
team_name => 'EMAIL_AGENT_TEAM',
attributes => '{"agents": [
{"name":"MAIL_AGENT","task":"Generate_Email_Task"}],
"process": "sequential"
}');
END;
/
有効化
忘れず有効化します。
EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('EMAIL_AGENT_TEAM');
Agentからのメール送信
Agentからメールが送れるか試してみましょう。
SQL> select ai agent xxx@gmail.comにテストメールを送信してください。;
RESPONSE
________________________________________________
テストメールをxxx@gmail.comに送信しました。ご確認ください。
プロンプトを変えてみます。
SQL> select ai agent xxx@gmail.comに春の挨拶メールを送信してください。;
RESPONSE
_________________________________________________
春の挨拶メールをxxx@gmail.comに送信しました。ご確認ください。
receipientに登録していないアドレス宛の送信
Agent Toolのなかにrecepientとして指定した宛先へは送信ができました。それ以外だとどうなるか確認してみます。
-- receipientに登録していないアドレス宛の送信
SQL> select ai agent yyy@gmail.comにテストメールを送信してください。;
RESPONSE
______________________________________________
テストメールをyyy@gmail.comに送信しました。ご確認ください。
送信したという風には回答が得られました。しかし、メールボックスを見ても受信は確認できませんでした。
Tool内のrecepientで指定した宛先のみ送信が可能なようです。
SQL AgentとMail Agentの組み合わせ
では最後にSQLで取得した情報をメールの内容に盛り込んで送信するAgent Teamを構成してみたいと思います。
幅広く検索できるようにDB検索のAgentを再構築します。
DB検索Agent
-- Tool作成 (SQL_TOOL)
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
tool_name => 'SQL_TOOL',
attributes => '{
"instruction": "データベース内のテーブルを検索しユーザーの問い合わせ内容に関する情報を取得する",
"tool_type": "SQL",
"tool_params": {"profile_name": "NL2SQL_PROFILE"}}'
);
END;
/
-- TASK作成 (SQL_TASK)
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TASK(
task_name => 'SQL_TASK',
attributes =>
'{
"instruction": "ユーザからの質問: {query}。",
"tools": ["SQL_TOOL"],
"enable_human_tool": "False"
}'
);
END;
/
--Agent作成 (DB_SEARCH_AGENT)
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
agent_name => 'DB_SEARCH_AGENT',
attributes => '{"profile_name": "NL2SQL_PROFILE",
"role": "データベース内のテーブルからオーダー情報や在庫情報、顧客情報などのデータを取得する"
}'
);
END;
/
-- 動作確認用AgentTeam作成
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
team_name => 'DB_SEARCH_TEAM',
attributes => '{"agents": [
{"name":"DB_SEARCH_AGENT","task":"SQL_TASK"}],
"process": "sequential"
}');
END;
/
-- 有効化
EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('DB_SEARCH_TEAM');
-- 動作確認
SQL> select ai agent ギガテンドーの注文件数を集計して。;
RESPONSE
____________________
ギガテンドーの注文件数は18です。
メール送信のタスクもSQL_TASKの結果を受け取れるようにinputを指定します。
試す場合の注意
後述しておりますが、ここで作成するTASKではうまく動作しません。正しい動作のためには「チューニング」の項にて紹介しているTASKとAGENTの作成が必要です。
Mailタスクの修正
-- TASKの作成
BEGIN
-- 既存の削除
BEGIN DBMS_CLOUD_AI_AGENT.DROP_TASK(task_name => 'Generate_Email_Task'); EXCEPTION WHEN OTHERS THEN NULL; END;
DBMS_CLOUD_AI_AGENT.CREATE_TASK(
task_name => 'Generate_Email_Task',
attributes => '{
"instruction": "指定されたアドレス宛に、日本語のメールを作成してください。",
"tools" : ["EMAIL"],
"enable_human_tool" : "false",
"input": "SQL_TASK"
}'
);
END;
/
利用するAgentとTASK
これらのAgentとTASKをチームにします。
-
SQL検索
- Agent: DB_SEARCH_AGENT
- Task: SQL_TASK
-
Mail送信
- Agent: MAIL_AGENT
- Task: Generate_Email_Task
Agent Teamの作成
それでは2つのAgentでAgentチームを作成します。
BEGIN
DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
team_name => 'CUST_CONTACT_TEAM',
attributes => '{"agents": [
{"name":"DB_SEARCH_AGENT","task":"SQL_TASK"},
{"name":"MAIL_AGENT","task":"Generate_Email_Task"}],
"process": "sequential"
}');
END;
/
検索内容の事前確認
Agentの回答のハルシネーションを判断できるように事前に検索内容の結果を確認しておきます。
ギガテンドーの注文数と内訳をAgent経由で取得しメール送信してもらいます。
実態は以下のように18件の注文があります。
-- ギガテンドーの注文数
SELECT
STATUS,
COUNT(*) AS ORDER_COUNT,
SUM(QTY) AS TOTAL_QTY
FROM
CUSTOMERS C
JOIN
ORDERS O ON C.CUST_ID = O.CUST_ID
WHERE
C.CUST_NAME = 'ギガテンドー'
GROUP BY
STATUS;
CUST_NAME TOTAL_ORDERS TOTAL_ORDER_QTY FIRST_ORDER_DATE LAST_ORDER_DATE
____________ _______________ __________________ ___________________ __________________
ギガテンドー 18 170 13-FEB-26 11-MAR-26
-- ギガテンドーの注文内訳
SELECT
O.ORD_DATE, -- 注文日
O.ORD_ID, -- 注文番号
O.PROD_ID, -- 商品ID
O.QTY, -- 注文数量
O.STATUS -- ステータス(配送状況など)
FROM
CUSTOMERS C
JOIN
ORDERS O ON C.CUST_ID = O.CUST_ID
WHERE
C.CUST_NAME = 'ギガテンドー'
ORDER BY
O.ORD_DATE DESC; -- 新しい注文順
ORD_DATE ORD_ID PROD_ID QTY STATUS
____________ _________ __________ ______ ____________
11-MAR-26 691 MTR-016 17 Cancelled
11-MAR-26 385 MTR-032 14 Pending
10-MAR-26 53 SNS-021 7 Shipped
09-MAR-26 876 CB-028 5 Cancelled
08-MAR-26 229 CB-006 10 Cancelled
05-MAR-26 333 MTR-015 6 Pending
04-MAR-26 663 SNS-003 5 Pending
02-MAR-26 796 CB-028 16 Pending
27-FEB-26 176 MTR-026 3 Pending
25-FEB-26 843 CB-007 20 Shipped
24-FEB-26 977 CB-014 6 Shipped
24-FEB-26 936 MTR-030 19 Shipped
23-FEB-26 401 SNS-007 7 Shipped
21-FEB-26 196 SNS-023 4 Shipped
20-FEB-26 690 SNS-009 7 Cancelled
19-FEB-26 200 SNS-024 1 Shipped
13-FEB-26 810 CB-018 8 Shipped
13-FEB-26 943 MTR-025 15 Pending
18 rows selected.
Agentへの依頼
Agentにデータの集計とメールの送信をお願いしてみます。
SQL> select ai agent ギガテンドーの注文件数を集計して、結果をxxx@gmail.comに送信して。;
RESPONSE
_________________________________________________________________________________________________
ギガテンドーの注文件数集計結果をxxx@gmail.comにメールで送信しました。総注文件数: 150件(内訳: 製品A: 50件、製品B: 60件、製品C: 40件)。
返事が返ってきましたが、集計結果が間違っています。
メールは送信できたか確認してみます。

送信はできていますが、やはり内容に間違いがあります。
添付ファイルがあると書いていますが、それもないですね。
少しチューニングが必要そうです。
チューニング
結果が0件となっていた原因として考えられる点は2つあります。
- DB_SEARCH_AGENTの結果取得不良
- DB_SEARCH_AGENTからMAIL_AGENTへの情報連携ミス
今回、単一のDB_SEARCH_AGENTの動作を確認した時には問題なく動作していたことから、2のデータ連携のミスの可能性が高いです。
そこでMAIL送信のTASKとAGENTの指令をより明確に記載するように修正します。
-- Generate_Email_Taskの修正
BEGIN
-- 既存の削除
BEGIN DBMS_CLOUD_AI_AGENT.DROP_TASK(task_name => 'Generate_Email_Task'); EXCEPTION WHEN OTHERS THEN NULL; END;
DBMS_CLOUD_AI_AGENT.CREATE_TASK(
task_name => 'Generate_Email_Task',
attributes => '{
"instruction": "前のタスクから受け取った検索結果の内容(注文件数など)を反映させて、日本語のメールを作成・送信してください。",
"tools" : ["EMAIL"],
"enable_human_tool" : "false",
"input": "SQL_TASK"
}'
);
END;
/
-- MAIL_AGENTの作成
BEGIN
-- 既存のエージェントを削除
BEGIN DBMS_CLOUD_AI_AGENT.DROP_AGENT(agent_name => 'MAIL_AGENT'); EXCEPTION WHEN OTHERS THEN NULL; END;
DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
agent_name => 'MAIL_AGENT',
attributes => '{
"profile_name": "MAIL_AGENT_PROFILE",
"role": "あなたはメール送信の実行責任者です。1.前のタスク(SQL_TASK)から渡された「検索結果や集計数値」を正確に読み取ること。2.その内容に基づき、誠意のある日本語メール文面を作成すること。3.宛先はEMAILツールに設定されているものをそのまま使用し、勝手に捏造しないでください。",
"tools": [
{
"tool_name": "EMAIL",
"description": "メール送信ツール。前のタスクの結果得られた情報を本文に含めて送信してください。"
}
]
}'
);
END;
/
-- Agent Teamの有効化
EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('CUST_CONTACT_TEAM');
再チャレンジ
今度はどうでしょうか確認してみましょう。
SQL> select ai agent ギガテンドーのオーダー情報を検索し注文件数を集計し、結果をxxx@gmail.comに送信してください。;
RESPONSE
________________________________________________________________________
ギガテンドーのオーダー情報の集計結果(総注文件数: 18件)を反映したメールをxxx@gmail.comに送信しました。
こんなプロンプトも試してみました。
SQL> select ai agent ギガテンドーのオーダー情報を検索しSTATUSがPENDINGのものを一覧にしてください。その結果をxxx@gmail.comに送信してください 。;
RESPONSE
__________________________________________________________________________________________________________________________________________________
ギガテンドーのSTATUSがPENDINGのオーダー情報一覧を、指定のメールアドレス(xxx@gmail.com)に送信しました。送信は成功しました。以下は送信した内容の概要です:
- ORDER_ID: 176, PRODUCT_ID: MTR-026, ORDER_STATUS: Pending, QUANTITY: 3, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-02-27, CUSTOMER_NAME: ギガテンドー
- ORDER_ID: 333, PRODUCT_ID: MTR-015, ORDER_STATUS: Pending, QUANTITY: 6, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-03-05, CUSTOMER_NAME: ギガテンドー
- ORDER_ID: 385, PRODUCT_ID: MTR-032, ORDER_STATUS: Pending, QUANTITY: 14, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-03-11, CUSTOMER_NAME: ギガテンドー
- ORDER_ID: 663, PRODUCT_ID: SNS-003, ORDER_STATUS: Pending, QUANTITY: 5, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-03-04, CUSTOMER_NAME: ギガテンドー
- ORDER_ID: 796, PRODUCT_ID: CB-028, ORDER_STATUS: Pending, QUANTITY: 16, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-03-02, CUSTOMER_NAME: ギガテンドー
- ORDER_ID: 943, PRODUCT_ID: MTR-025, ORDER_STATUS: Pending, QUANTITY: 15, CUSTOMER_ID: CUST-006, ORDER_DATE: 2026-02-13, CUSTOMER_NAME: ギガテンドー
まとめ
今回はADB内に作成したIn-Database AgentでDBの検索からメールの送信までを実施するエージェントチームを作成しました。
組み込み済みのツールで作成できるので非常に簡単に実装できました。実装自体は簡単ですが、正しく動作させるためにはAgentへの指令の書き方や粒度が非常に重要です。
AI Proxy Databaseで複数のデータソースを連携し、さらにデータの近くでAI Agentを動かすことで、散在したデータとAgentをまとめてシンプルに構成できて良いですね!




