ラベル AI の投稿を表示しています。 すべての投稿を表示
ラベル AI の投稿を表示しています。 すべての投稿を表示

2026年9月11日金曜日

OpenAI CodexとLive音声モードのチャットで駅別乗降客数マップを表示するアプリを作成する

先日、OpenAI CodexとモデルにGPT-6 Astraで簡単なAPEXアプリケーションを作成しました。その際に「これなら音声チャットでアプリを作れそう。」と思ったので、実際にChatGPTのLive音声モードでアプリケーションを作成してみました。

Live音声モードからの指示とCodexで、以下のようなAPEXアプリケーションが作成できました。
https://github.com/ujnak/APEXlang-exports/tree/main/station-passengers-native


最初は、Oracle APEXのアプリケーションを作成する、と指示するのを忘れたため、バックエンドがPython、フロントエンドがJavaScriptでアプリケーションが作成されました。パッケージとして地図を表示するためにLeafletを使用していますが、それ以外は特にパッケージのようなものは使用せず(Oracle Databaseに接続するドライバやFast APIも使っていない)、とにかく最短で動くアプリケーションを作成したといった感じです。


このアプリケーションをAPEXアプリにしてと依頼したら、Python製のサーバー呼び出しをAPEXのAjaxコールバックに置き換えましたが、フロントエンドのJavaScriptアプリについてはAPEXに静的アプリケーション・ファイルとして保存し、まったく同じ外観のAPEXアプリが出来上がりました。
https://github.com/ujnak/APEXlang-exports/tree/main/station-passengers

そのアプリをAPEXの機能を使うように書き換えています。最初のGIF動画のAPEXアプリケーションは、第3版ということになります。

以下より作業内容を紹介します。

駅別乗降客数のデータは国土交通省の国土数値情報ダウンロードサイトから、最新の2024年度(令和6年度)版をダウンロードしています。


作業フォルダとしてNumberOfPassengersを作成し、そこにダウンロードしたファイルS12-26_GML.zipを配置し解凍しました。その後、Oracle DatabaseとAPEXのスキルをインストールしています。

作業フォルダにアプリケーションの元になるデータが配置されたので、OpenAI Codexのプロジェクトを作成しました。プロジェクト名は駅別乗降客数データとしています。


この後は、ChatGPTのデスクトップ・アプリからLive音声モードですべての作業を行いました。Live音声モードでCodexのプロジェクトで作業してと依頼すると、Codexのタスクを開始するか、または既存のタスクを見つけて、そのタスクにLive音声モードのセッションから作業依頼を出すようです。

参考までに、以下が会話履歴です。一番最初は「日本語で話して。」と指示しています。
Live音声モードのモデルGPT-Live-1のバックエンドと、CodexにAstra(軽)を使っています。ちょっとしたアプリケーションであれば表の作成からデータのロード、アプリケーションの作成まで、AIとの会話だけで出来そうです。

今回の記事は以上になります。

2026年9月10日木曜日

国土地理院が公開している自然災害伝承碑データより伝承碑の位置を表示するAPEXアプリをCodexで作成する

国土交通省の機関である国土地理院よりオープン・データとして、自然災害伝承碑データが公開されています。過去に発生した災害を後世に伝えるために全国各地に建立されている伝承碑の、位置情報および災害名、災害種別、伝承内容などがオープン・データに含まれています。

国土地理院 - 自然災害伝承碑データの提供について
https://www.gsi.go.jp/bousaichiri/denshouhi_datainfo.html

このオープン・データのGeoJSONファイルより、OpenAI Codexを使って伝承碑が存在する場所や伝承碑の説明を表示するAPEXアプリケーションを作成します。一覧する伝承碑を絞り込むために、ファセット検索も組み込みます。

Codexが作成したAPEXアプリケーションは以下のように動作します。


OpenAI CodexとモデルにGPT-6 Astra(軽)を使用しました。

Oracle APEXのアプリケーションを作成するため、Oracle Corporationから配布されているOracle DatabaseとAPEXlangのスキルを使用しています。

APEXlangのスキルはOracle APEXのリリース・サイクルとは独立してアップデートされています。APEXlangスキルのリリース・ノートは以下のリンクで公開されています。本記事の公開時点での最新リリースは2026.8.26です。


以前は指示通りに生成できなかったアプリケーションも、更新されたAPEXlangスキルでは生成できる可能性があります。

OpenAI CodexやClaude CodeといったAIコーディング・エージェントとAPEXlangを使ったアプリケーション作成については、Oracle APEX 26.1がリリースされたときにOracle CorporationのScott SpendoliniさんがAPEX Office Hoursで紹介されています。


このセッションの中で、SQLcl MCPサーバーの構成が推奨されています。


少なくてもCodexはSQLclをCLIで扱えるので、SQLclの構成は必要なさそうです。本記事ではSQLcl MCPサーバーは構成せず、SQLclのみでデータベースを操作しています。

また、あらかじめスターター・アプリケーションを作成することが推奨されていますが、最新のAPEXlangスキルでは、これも不要に見えます。本記事ではスターター・アプリケーションは作成していません。


GitHubにあるAPEXlangのREADME.mdにPrompt Examples by Taskとして、いくつかのプロンプトが紹介されています。


その中にWhole app from beginning to endとして、以下のプロンプトが紹介されています。
Create a dashboard page for order operations with KPI cards, a monthly revenue chart, and an interactive report. Use existing schema evidence and ask before guessing missing columns.
一般的なスターター・アプリケーションは不要と思われますが、APEX 26.1で導入されたボイラープレートのように、会社固有のテーマ、あらかじめ作成済みの認証スキーム、LOV、プラグインを含んでいるアプリケーションであれば、作成してプロジェクト・フォルダにエクスポートしておくと、アプリケーションの作成に必要な要件や指示が減り、時間とコストの節約になるでしょう。

以下よりCodexで行なった作業を紹介します。

最初にローカルのPCに作業フォルダを作成します。今回はndmm_monumentsとしてフォルダを作成しました。

国土地理院 - 自然災害伝承碑データの提供についてのページにアクセスし、ページの一番下にある免責事項同意するをクリックすると、データのダウンロード・ページに移ります。

GeoJSON形式のデータをダウンロードします。


ファイルは000250767.zipとしてダウンロードされます。このファイルを作業フォルダに配置し解凍します。解凍するとフォルダ20260827_GeoJSONが作成され、その下に20260827.geojsonとして、GeoJSON形式のデータファイルが作成されます。

ndmm_monuments % ls -l 20260827_GeoJSON

total 4760

-rw-rw-rw-@ 1 ********  staff     6729 12月 23  2021 0_はじめにお読みください(国土地理院コンテンツ利用規約).txt

-rw-rw-rw-@ 1 ********  staff     1229  1月 15  2024 1_データについて_geojson.txt

-rw-rw-rw-@ 1 ********  staff  2422479  8月 31 07:35 20260827.geojson

ndmm_monuments % 


作業フォルダにOracle DatabaseとAPEXlangのスキルをインストールします。スキルのインストール方法には色々ありますが、本記事ではMicrosoft APMを使用します。APMはあらかじめインストールしておきます。

作業ディレクトリに移動し、Oracle APEXとOracle DBのスキルをインストールします。

apm install oracle/skills/apex --target codex
apm install oracle/skills/db --target codex
apm deps list

APEXlangのスキルはoracle/skills/apexに含まれています。

ndmm_monuments % apm install oracle/skills/apex --target codex

[*] Validating 1 package...

[+] oracle/skills/apex

[*] Updated apm.yml with 1 new package(s)

[>] Installing 1 new package...

[>] Resolving skills-apex...

[i] Targets: codex  (source: --target flag)

  [+] github.com/oracle/skills/apex #default @fcbc9430

  |-- Skill integrated -> .agents/skills/

  [!] 1 dependency unpinned: oracle/skills -- add #tag or #sha to prevent drift

[*] Installed 1 APM dependency in 6.4s.

ndmm_monuments % apm install oracle/skills/db --target codex

[*] Validating 1 package...

[+] oracle/skills/db

[*] Updated apm.yml with 1 new package(s)

[>] Installing 1 new package...

[>] Resolving skills-db...

[i] Targets: codex  (source: --target flag)

  [+] github.com/oracle/skills/db #default @fcbc9430

  |-- Skill integrated -> .agents/skills/

  [!] 1 dependency unpinned: oracle/skills -- add #tag or #sha to prevent drift

[*] Installed 1 APM dependency in 6.7s.

ndmm_monuments % apm deps list                              

                                       APM Dependencies (Project)                                      

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━┓

Package                     Version Source   Prompts Instructions Agents Skills Hooks

┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━┩

oracle/skills/apex          unknown github       -          -         -      1      -  

oracle/skills/db            unknown github       -          -         -      1      -  

oracle/skills/apex/apexlang unknown orphaned     -          -         -      1      -  

└─────────────────────────────┴─────────┴──────────┴─────────┴──────────────┴────────┴────────┴───────┘

[!] 1 orphaned package(s) found (not in resolved dependency graph):

[!]   - oracle/skills/apex/apexlang

[i] Run 'apm prune' to remove orphaned packages

ndmm_monuments % 


OpenAI ChatGPTのデスクトップ・アプリよりCodexを選択し、プロジェクトを作成します。

プロジェクトタイプローカルを選択します。次へ進みます。


プロジェクト名自然災害伝承碑マップとします。ソースフォルダに作成済みの作業フォルダーを割り当てます。

以上でプロジェクトを作成します。


プロジェクトを作成したのち、最初の指示として以下を与えました。概ね口頭での話し言葉で実施してほしい作業を伝えています。

SQLclの実行ファイルの位置、SQLclの保存済みの接続名、接続先となるスキーマ名やAPEXワークスペース名は作業を行う環境に合わせて変更します。
国土地理院からダウンロードした日本の自然災害伝承碑のGeoJSONのデータを、Oracle DatabaseにロードしてOracle APEXのマップ上に表示するアプリケーションを作成します。

データベースに接続するために使用するSQLclの実行ファイルは/opt/homebrew/bin/sqlclです。

接続先となるデータベースは、SQLclの保存済みの接続local-26ai-apexdevを使って接続します。

APEXアプリケーションを作成するワークスペースはAPEXDEVです。

保存済みの接続local-26ai-apexdevでは、スキーマAPEXDEVに接続されます。これはAPEXのワークスペースAPEXDEVのデフォルト・パーシング・スキーマです。

表などのデータベース・オブジェクトはスキーマAPEXDEV以下に作成します。

データを保存する表は、これから伝える条件で作成してください。

自然災害伝承碑のデータを利用するにあたって、公開されている以下のファイルの内容に配慮してください。
20260827_GeoJSON/0_はじめにお読みください(国土地理院コンテンツ利用規約).txt
20260827_GeoJSON/1_データについて_geojson.txt

ソースとなる自然災害伝承データは、 ファイル20260827_GeoJSON/20260827.geojsonに保存されています。

このGeoJSONファイルをデータベースの表にロードしてください。

作成する表はNDMM_MONUMENTSとします。

GeoJSONの1つのFeatureを1行として保存し、proppertiesはそれぞれ列として定義します。

Featureには、"ID", 碑名",  "建立年","所在地", "災害名", "災害種別", "伝承内容", "公開日", "修正等公開日", "制限事項" があります。

これらのFeatureを表の列として定義します。この他に自然災害伝承碑の座標を列として定義します。

表の列として定義するにあたり、列名は英語にしてください。データ型はファイルから実際のデータ型を参照して適切なデータ型を選んでください。

geometryについては、SDO_GEOMETRY型の列として保存してください。

データベースに表を作成したら、ファイル20260827_GeoJSON/20260827.geojsonの内容を作成した表NDMM_MONUMENTSにロードしてください。

データをすべて表NDMM_MONUMENTSにロードした後、geometryを保存した列にOracle Spatialの空間索引を作成してください。

これから、新規に作成するAPEXアプリケーションの要件を説明します。

新規に作成するAPEXアプリケーションの名前は「自然災害伝承碑マップ」とします。

アプリケーション別名はndmm_monumentsとします。

上記の表NDMM_MONUMENTSをデータ・ソースとしたファセット検索付きのマップ・リージョンを持つページを作成してください。

作成したページには、国土地理院コンテンツ利用規約に沿って、出典と行なった加工と編集について表示してください。

マップ・リージョンの他に、マップ上に表示されている自然災害伝承碑の行を一覧するクラシック・レポートのリージョンを作成してください。

災害種別と災害名をファセットとしてください。

マップ上にそれぞれの自然災害伝承碑を配置してください。

マップ上のポイントをクリックして開く情報ボックスに、表NDMM_MOMENTSのgeometryを除く列を表示するようにしてください。
APEXlangのスキルには、与えられた指示から作業プランをMarkdownファイルに生成してから作業を始めるようなワークフローが定義されている模様です。作業フォルダ以下には、そういった作業途中で生成されたファイルが残されています。


APEXlang形式のアプリケーションの保存先を聞かれたり、Chromeが起動して作成されたAPEXアプリケーションへのサインインを求められました。Chromeの操作のために、コンピュータの制御をCodex Computer Useが行えるように許可しておく必要があります。

22分で表の作成とデータロードを含めて、指示したAPEXアプリケーションが作成されました。


最初に作成されたアプリケーションです。修正したい部分がいくつか見つかりました。


災害種別のファセットが"洪水・土砂災害"のように、複数の種別がファセットの選択肢として1つになっていました。これはもともとGeoJSONの"災害種別"のプロパティの値が"洪水・土砂災害"であったためです。これをで分割して、それぞれを災害種別として選択できるように変更を依頼しました。

「災害種別のファセットは複数の値を「はい」にして、区切り文字を・、そして選択した値はANDで表示する伝承碑を選択するように、ファセットの設定を変更してください。」


3分40秒で修正が完了しました。

表示中の自然災害伝承碑を一覧するクラシック・レポートとリージョンの間にパディングが含まれていていたため、削除するよう依頼しました。

「表示中の自然災害伝承碑のクラシック・レポートのパディングを削除して、リージョンの外枠との隙間を無くしてください。」


約7分で修正が完了しました。

クラシック・レポートのページ送りのコントロールがクラシック・レポートの右下のみに配置されていました。これを右上にも配置するよう依頼しました。

「ページ送りのコントールをリージョンの右下だけでなく、右上にも追加してください。」


13分半で修正が完了しました。人の感覚ではちょっとした作業なのですが、AIの作業としては時間がかかっていて不思議な感じがします。

地図をズーム・イン/アウトしたり移動したときに、地図の表示範囲に含まれる伝承碑がクラシック・レポートに一覧されています。この処理がファセットに適用されていませんでした。

同様の処理をファセットに実装するよう依頼しました。

「地図上に表示されている伝承碑はクラシック・レポートに反映されていますが、検索条件を表示するファセットには反映されていません。クラシック・レポートと同様にファセットにも反映するようにしてください。」

2回アプリケーションへのログインを要求されていますが、これは1回目は修正に失敗していてエラーが発生していました。そのエラーを修正した後に2回目のログインを要求されています。


約11分で修正が完了しました。

地図上のポイントをクリックしたときに表示される情報ボックスの大きさが縦に長く、地図上に全体が表示されずに溢れていたため、情報ボックスが横長になるように修正を依頼しました。

「地図上の伝承碑のポイントをクリックしたときに表示される情報ボックスですが、地図の領域からはみ出てすべての情報が表示されません。横幅を2倍に広げて、縦方向の長さは半分にしてください。」


約5分で修正が完了しました。

以上で、記事の先頭のGIF動画のアプリケーションが作成されました。

修正点のまとめです。


実は先日までCodexとGPT-5.6 Sol(中)で、同じ仕様のAPEXアプリケーションを作成していました。初回はコマンドラインのCodexで作成し、Codexだけで作成できることを確認するのにだいたい1日かかりました。次に作業環境をデスクトップ・アプリのCodexに移し、GPT-5.6 Sol(中)で同じ指示でアプリケーションを作成しました。これは半日程度かかりました。なかなか動くコードが生成されず、プロンプトの与え方を色々と変えたり追加のプロンプトが必要だったことと、Computer Useが今ひとつでCodexによるデバッグに制限があったためだと考えています。

GPT-5.6 Solで作業をしていたプロジェクトは削除し、新しくプロジェクトを作成した上でGPT-6 Astraで作業しているのですが、昨日までの作業の成功例が反映された結果、GPT-6 Astraの作業がスムーズに進んだ可能性はあります。

そのような可能性はありますが、それでもGPT-6 AstraによるAPEXアプリケーションの生成は印象的でした。

全ての指示を文字で与えていますが、与えた指示自体は話ことばにしています。おそらくAPEXアプリケーションは、AIコーディング・エージェントと会話をしながらでも作成できるでしょう。

今回、Codexが作成したAPEXアプリケーションのエクスポートを以下に置いています。
https://github.com/ujnak/APEXlang-exports/tree/main/ndmm_monuments

GPT-6 Astraが生成したコードも印象的です。

今回の記事は以上になります。

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

2026年7月3日金曜日

APEX 26.1のAIエージェントのレスポンス形式にJSONオブジェクトを指定する

Oracle APEX 26.1のAIエージェントは、レスポンス形式JSONオブジェクトを指定できます。JSONスキーマを定義することにより、PL/SQL APIのAPEX_AI.GENERATEを呼び出したときに、レスポンスとして得られるJSONオブジェクトの形式を決めることができます。

実装サンプルとして、以下のAPEXアプリケーションを作成してみました。

AIエージェントにメッセージを送信し、レスポンスとして得られたGeoJSONのポリゴンをAPEXのマップ・リージョンに表示しています。LLMにOpenAI GPT-5.5を使用しています。


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


以下より、作成したAPEXアプリケーションについて紹介します。

共有コンポーネントAIエージェントとして、Get Polygon from a promptを作成しています。

生成AIサービスGPT-5.5を選択しています。このサービスは、あらかじめAPEXワークスペースに、生成AIとして作成しておきます。システム・プロンプトとして以下を記述します。

「プロンプトに関連する地域を推測し、その地域を囲むポリゴンをGeoJSONのPolygonとして生成してください。」


レスポンス形式タイプJSONオブジェクトを選択し、JSONスキーマとして以下を記述します。OpenAI GPT-5.5に出力させました。Claude Sonnet 5でレビューしています。


オンライン・ヘルプに記載されていますが、タイプJSONオブジェクトを指定した場合、このAIエージェントを呼び出せるのは、PL/SQL APIのAPEX_AI.GENERATEに限られます。詳細静的IDはAPI呼び出しの際に使用されます。
Select the type of response that should be generated by the AI provider.
  • Text: Plain text
  • JSON Object: A JSON object that will adhere to a specific JSON schema. Note that AI Agents which return a JSON object can currently only be referenced by the apex_ai.generate PL/SQL API.

このスキーマ定義はChat Completions APIであれば、response_formatのjson_schemaとして送信されます。このAIエージェントはツールを含みませんが、ツールを含むこともできるはずです(まだ動作確認ができていません)。ユーザー向けの最初のレスポンスが、設定したJSONスキーマに従ったJSONオブジェクトになります。

また、JSONスキーマのオンライン・ヘルプに記載されていますが、生成AIが返すレスポンスについて、データベースが26aiであればJSONオブジェクトの検証を行いますが、それ以前のバージョン(つまり19c)は検証しないようです。性能の低いLLMを使用する場合、レスポンスが指定したJSONスキーマに従わないことがあるので注意が必要です。
The JSON Schema based on which the JSON object is generated.

Note that the referenced AI provider might not support the full scope of the JSON Schema specification. Consult the documentation of the individual AI providers for more information.

Starting with database 26ai, the incoming JSON object is automatically validated against the JSON Schema. For earlier database versions, Oracle recommends validating the JSON object programatically before further processing.
プロンプトからGeoJSONのポリゴンを返すAIエージェントの説明は以上です。

ホーム・ページに、生成されたポリゴンをマップに表示する機能を実装しています。

ホーム・ページにマップ・リージョンとレイヤーを作成します。とりあえずポリゴンが表示できればよいので、最低限の実装にしています。

マップ・リージョンはJavaScriptから扱えるように、HTML DOM IDとしてMAPを設定しています。


レイヤーは、GeoJSONのポリゴンを表示するように構成します。ただし、AIエージェントを呼び出して得られるポリゴンだけを表示するため、データ・ソースは空にします。

属性名前Polygonとし、タイプとしてポリゴンを選択します。

ソース位置データ・ベースを選択し、タイプSQL問合せSQL問合せとして以下を記述します。必ずfalseとなる条件を設定しているため、1行も選択されません。

select 'label' as label, null as polygon from dual where 1<>1

列のマッピングジオメトリ列のデータ型としてGeoJSONを選び、GeoJSON列POLYGON(SELECT文に含まれる列POLYGON)を選択します。


描画されるポリゴンの外観を設定します。

塗りつぶしの色塗りつぶしの不透明度0.5ストロークの色にしています。

レイヤーを取り出すファンクションgetLayerIdByNameの引数は、レイヤーの名前です。詳細静的IDではありません。


プロンプトはページ・アイテムP1_PROMPTに入力します。タイプテキスト・フィールドにしています。


AIエージェントが返すポリゴンは、ページ・リージョンP1_POLYGONに保持します。タイプは非表示で良いのですが、データを確認するためテキスト領域としています。


ボタンDRAWを作成します。動作アクションとして、APEX 26.1の新機能であるトリガー・アクションを設定します。


ボタンDRAWをクリックしたときに最初に実行されるトリガー・アクションとして、Get a polygon from a promptを作成します。

PL/SQLで以下を記述します。先ほど作成したAIエージェントをAPEX_AI.GENERATEから呼び出しています。
begin
    :P1_POLYGON := apex_ai.generate(
        p_agent_static_id => 'get-polygon-from-a-prompt'
       ,p_prompt => :P1_PROMPT
    );
end;
送信するアイテムP1_PROMPT戻すアイテムP1_POLYGONを設定します。

サーバー側で処理している間にスピナーを表示するように、処理中の表示オンにします。この設定はAPEX 26.1の新機能です。

実行結果を待機オンにし、ポリゴンをP1_POLYGONに設定した後に、後続のトリガー・アクションが動作するようにします。


後続のトリガー・アクションとして以下のJavaScriptのコードを実行します。初版はOpenAI GPT-5.5に書いてもらって、一部Claude Sonnet 5に書き直してもらいました。コメントはブログの著者が書いています。


ページ・アイテムP1_POLYGONに保持されているGeoJSONのポリゴンを、マップに描画しています。


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

生成AIの出力フォーマットを規定することにより、後続の処理の実装(今回の例ではマップへの描画)が容易になります。

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

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のアプリケーション作成の参考になれば幸いです。