2026年7月1日水曜日

APEX 26.1のAIエージェントでデータベースを操作する

先の記事「APEX 26.1のAIエージェントでHTMLキャンバスに描画した車を動かす」にて、APEX 26.1のAIエージェントを使ってブラウザを操作するサンプル・アプリを作ってみました。本記事では、AIエージェントを使ってデータベースを操作するエージェントを作ってみます。

以下、プロンプトで従業員の給与を更新します。データ・ソースとしてはサンプル・データセットのEMP/DEPTの含まれる表EMPを使用します。

作成するAPEXアプリケーションは以下のように動作します。LLMにmacOSのLM Studioで実行しているgoogle/gemma-4-31b-qatを使用しているため、処理に時間がかかっています(動作も若干安定しないです)。

ページ・アイテムP1_ENAMEKINGが選択されているときに限り、AIエージェントのツールにupdate_salaryが含まれるようにしています。KING以外のときは「更新できません。」と返されます。


作成したAPEXアプリケーションのAPEXlang形式のエクスポートを以下に置きました。

https://github.com/ujnak/APEXlang-exports/tree/main/salary-management-agent

以下より、作成したAPEXアプリケーションについて紹介します。主にAIエージェントの紹介になります。

ホーム・ページに、AIエージェントに含まれるツールupdate_salaryサーバー側の条件に使用されるページ・アイテムP1_ENAMEが作成されています。

選択リストソースとなるSQL問合せとして、以下を記述しています。

select ename d, ename r from emp order by 1

選択時のページ・アクションとして値のリダイレクトと設定を選び、セッション・ステートストレージセッションごと(永続)を選んでいます。そのため、ここで選択した値をAIエージェントのコード中で、バインド変数:P1_ENAMEから参照できます。


従業員一覧はクラシック・レポートで作成し、ソース表名EMPを設定しています。

給与の更新後にJavaScriptの実行によりレポートをリフレッシュするため、詳細HTML DOM IDEMPを設定しています。


AIエージェントへのプロンプトを入力するリージョンとして、静的コンテンツのリージョンを作成し、ソースHTMLコードに以下を記述しています。

<div id="chat"></div>

AIアシスタントは、ページのロード時に実行する動的アクションで初期化しています。


作成したAIエージェントについて説明します。

AIエージェントの名前Salary Management Agentとしています。生成AIサービスとしてLM Studio Gemma4を設定しています。これはワークスペースに生成AIサービスとして作成済みです。

システム・プロンプトとして以下を記述しています。

「従業員の給与を更新します。
利用できるツールにupdate_salaryが含まれていない場合は、給与の更新手段がありません。その場合は、更新できません、と返します。」


4つのツールを作成しています。


システム・プロンプト拡張としてinject_schema_informationを作成しています。

このツールによって、システム・プロンプトに表EMPとDEPTの定義情報を追記しています。

実行ポイントシステム・プロンプト拡張のツールをツールと呼ぶと、LLMのツール呼び出しに含まれるツール定義と混同しそうです。実行ポイントオンデマンドのツールのみが、いわゆるLLMが扱うツールになります。

タイプデータの取得を選んでいます。データの取得の処理は、データベース・サーバー側で実行されます。サーバー側の処理は、設定タイプにてSQL問合せファンクション本体静的値の3つから選べます。

識別タイプで、クライアント側のコードを実行サーバー側のコードを実行データの取得が選べるように見えますが、実行ポイントシステム・プロンプト拡張の場合、データの取得サーバー側のコードを実行を含んでいるため、タイプサーバー側のコードを実行は選べません。選ぶと実行ポイントオンデマンドに変わります。

設定説明に「従業員給与を保持するスキーマ情報。」と記述します。この文章もシステム・プロンプトに追記されます。タイプファンクション本体を選択します。

言語PL/SQLを選び、CLOBを返すファンクション本体として以下を記述します。
declare
    l_text clob; 
begin
    l_text := apex_db_dictionary.get_table_info( 
        p_table_names => 'EMP, DEPT' );
    return l_text;
end;
以上で、表EMP/DEPTのメタデータが、つねにシステム・プロンプトに追記されるようになりました。


従業員名から従業員番号を取り出すツールをget_empno_from_enameとして作成しています。タイプサーバー側のコードを実行です。

説明に「従業員名から従業員番号を取得します。」と記述しています。この説明を元に、LLMはツールを選択します。

パラメータとしてENAMEを追加しています。説明従業員名データ型VARCHAR2必須はいです。

設定言語PL/SQLを選択し、PL/SQLコードとして以下を記述します。
declare
    l_empno emp.empno%type;
    l_response clob;
begin
    select empno into l_empno from emp where ename = :ENAME;
    l_response := apex_string.format('empno %s found for ename %s', l_empno, :ENAME);
    apex_ai.set_tool_result( p_result => l_response );
exception
    when no_data_found then
        l_response := apex_string.format('No empno found for %s, perhapse the employee with the name does not exist.', :EMPNO);
        apex_ai.set_tool_result( p_result => l_response );
end;

ツールget_empno_from_enameはだれでも呼び出せるように、条件は設定していません。

従業員一覧のレポートをリフレッシュするツールをrefresh_reportとして作成しています。タイプクライアント側のコードを実行実行ポイントオンデマンドです。

ツールの説明として「従業員一覧のレポートをリフレッシュします。」を記述します。

設定コードに以下の1行を記述します。

apex.region("EMP").refresh();


本記事の主題である、従業員の給与を更新するツールをupdate_salaryとして作成しています。

タイプサーバー側のコードを実行です。実行ポイントは必ずオンデマンドになります。

ツールの説明として。以下を記述します。

「指定した従業員番号の従業員の給与を更新します。
更新後はツールrefresh_reportを呼び出して、レポートの表示を更新します。」

パラメータとしてEMPNOSALを追加します。

EMPNO説明従業員番号データ型NUMBER必須はいです。SAL説明給与データ型NUMBER必須はいです。

設定言語PL/SQLを選択し、PL/SQLコードとして以下を記述します。
declare
begin
    update emp set sal = :SAL where empno = :EMPNO;
end;

ツールupdate_salaryについては、以下の条件も設定します。

User ApprovalRequire Confirmationオンにします。Confirmation Title給与の更新とし、Confirmation Messageに以下を記述します。

「従業員&EMPNO.の給与を&SAL.に更新します。」

LLMがツールupdate_salaryを実行するようにレスポンスを返したときに、以下のようにユーザーに確認を求めるダイアログが開きます。

OKをクリックすると、ツールupdate_salaryが実行されます。OK取消といったラベルは、Approve LabelCancel Labelを設定して変更できます。


通知メッセージに「給与を更新しました。」と記述します。タイプ成功を選択します。

上記のように設定した通知は、以下のように表示されます。通知の設定の有無に関わらず、LLMからのレスポンスも表示されるようです。


サーバー側の条件として、タイプ言語PL/SQL式1に以下を記述しています。

:P1_ENAME = 'KING'

上記の条件により、ツールupdate_salaryはページ・アイテムP1_ENAMEKINGが設定されているときに限り、LLMに送信するツール定義に含まれます。それ以外の従業員はツールupdate_salaryがツールに含まれていないため、給与を更新するようにプロンプトを送信しても、システム・プロンプトに設定しているように「更新できません。」と返されます。


以下、設定画面のスクリーンショットです。


今回作成したAPEXアプリケーションの説明は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。