OpenAIのAssistants APIを呼び出してRetrievalを実行するAPEXアプリケーションを作成してみました。
GIF動画では、以下に列記した操作を行なっています。
Files のページを開き、Oracle APEX 23.2の新機能について記述されたWebページのテキストをOpenAIにアップロードします。こちらののページ がソースです。Assistants のページを開き、アシスタント を作成します。tools としてretrieval を指定し、アップロードしたファイルをAssistant Filesに含めています。Messages のページを開きます。新規にスレッド を作成します。 メッセージ を作成します。Contentには「Oracle APEX 23.2の新機能を、手短に一覧にしてください。」と記述しました。実行 します。Run オブジェクトが作成されます。リフレッシュ をクリックし、Status がcompleted になるまで待ちます。Status がcompleted になった後に、Role がassistant のメッセージ(OpenAI側で生成されたメッセージ)の内容を確認します。
今回の問い合わせでは、以下の回答が得られました。
Oracle APEX 23.2の新機能は以下のとおりです:
アプリケーションの作業用コピー : バグ修正や機能追加後、選択的に変更をメインアプリケーションにマージできます。複数の開発者が1つのアプリケーションへの変更をコントリビュートすることが可能です【9†source】。
無制限の属性 : 開発者はテンプレート・コンポーネント・プラグインを25属性という制約なしに作成でき、テンプレート・コンポーネントのレンダリングがより高速になりました【13†source】。
ユニバーサル・テーマのさらなる活用 : ユニバーサル・テーマに付属するいくつかのテンプレート・コンポーネントが更新され、開発者はアプリケーション全体でテンプレート・コンポーネントの使用方法の汎用性が向上しました【13†source】。
開発者エクスペリエンス向上 : 共有コンポーネントのサブスクリプションが改善され、サブスクライブされたコンポーネントが読取り専用となりました。自動依存性解決機能が加わり、サブスクリプションのステータスが共有コンポーネントレポートに表示されるようになりました。更に、一括リフレッシュと削除の機能が提供されます【13†source】。
クイックSQLの更新 : 生成されたSQLスクリプトとE-Rダイアグラムが即座にリフレッシュされ、データモデルの視覚化やユーザー・エクスペリエンスの簡素化が可能になりました【13†source】。
RESTデータ・ソースの機能強化 : 外部アプリケーションとのより深い統合が可能になり、APEXベースのソリューションが拡大しました。RESTソース・パラメータ及びRESTソース・プラグインが強化され、OpenAPIからのRESTソース・カタログを作成でき、ネイティブOData RESTソース・タイプが統合されました。さらに、Fusion Applications拡張機能のサポートが可能になり、Oracle Cloud ApplicationsのRESTデータ・ソースが完全で最適化され、Fusion Applicationsサンドボックスでの進行中のカスタマイズが簡単になりました【13†source】。
追加の新機能について情報を提供するには、さらにドキュメントをレビューする必要があります。もし必要であれば、その情報を提供できるよう検索を続けます。
上記のAPEXアプリケーションのエクスポートを以下に置いています。
https://github.com/ujnak/apexapps/blob/master/exports/openai-retrieval-assistant.zip
以下より、APEXアプリケーションの作成手順を紹介します。
以下の2つの記事で作成しているPL/SQLパッケージ とRESTデータ・ソース を流用します。
記事「
OpenAIのFiles APIを使ってファイルをアップロードする 」より、パッケージ
UTL_OPENAI_FILES_API と
RESTデータ・ソース の
List files を流用します。
パッケージUTL_OPENAI_FILES_API およびUTL_OPENAI_ASSISTANTS_API は、これらのコードをSQLワークショップ のSQLファイル として実行して作成します。
RESTソース・カタログ は以下の手順で作成します。
ワークスペース・ユーティリティ の、RESTソース・カタログ を開きます。
タスク よりカタログ・グループの管理 を開きます。RESTソース・カタログはカタログ・グループに所属する必要があります。カタログ・グループ としてOpenAI を作成し、作成するRESTデータ・ソースを所属させます。
グループの作成 をクリックします。
名前 はOpenAI とします。
作成 をクリックします。
RESTカタログ・グループ としてOpenAI が作成されました。
RESTソース・カタログ のページに戻ります。
タスク よりカタログのインポート をクリックします。
ダウンロードしたRESTソース・カタログのSQLファイルOpenAI Assistants API.sql をインポートするファイルとして選択します。ファイル・タイプ はRESTソース・カタログ です。
次 へ進みます。
すぐにインストールします。
次 へ進みます。
カタログ・グループ としてOpenAI を選択します。
RESTカタログのインポート をクリックします。
RESTソース・カタログ としてOpenAI Assistants API が作成されました。
同様の手順を繰り返し、
OpenAI Files API.sql もインポートします。
以上で、APEXアプリケーションでRESTデータ・ソース としてOpen AI Assistants APIのList assistants 、List messages 、List runs およびOpenAI Files APIのList files を作成する準備ができました。
新規にアプリケーションを作成します。名前 はOpenAI Retrieval Assistant とします。
アプリケーションの作成 をクリックします。
アプリケーションが作成されたら、共有コンポーネント のRESTデータ・ソース を開きます。
作成 をクリックします。
RESTデータ・ソースの作成 としてRESTソース・カタログから を選択します。
次 へ進みます。
RESTソース・カタログのOpenAI Assistants API の参照 をクリックします。
List assistants 、List messages 、List runs のプラスをクリックして、作成するRESTデータ・ソースとして選択します。なお、List threadsのAPIはAssistants APIより削除されたか、仕様が変わったため利用できなくなった模様です。
選択が完了したら、次 へ進みます。
OpenAIのAPIにアクセスするための
Web資格証明 を選択します。Web資格証明の作成方法については、記事「
OpenAIのChatGPTのAPIを呼び出すAPEXアプリを作る 」を参照してください。
RESTデータ・ソースの作成 をクリックします。
RESTデータ・ソースとしてList assistants 、List messages 、List runs が作成されます。
同様の手順でOpenAI Files APIより、RESTデータ・ソースList files を作成します。
以上でRESTデータ・ソースの作成は完了です。
アプリケーション定義 の置換 に、置換文字列 としてG_OPENAI_API_KEY を設定します。置換値はOpenAIのAPIキーが設定されているWeb資格証明の静的ID です。
ファイルのアップロードと削除を行うページを作成します。
ページの作成 をクリックします。
対話モード・レポート を選択します。
対話モード・レポートのページのページ番号 は2 、名前 はFiles 、ページ・モード は標準 です。フォーム・ページを含める をオン にし、フォーム・ページ番号 は3 、フォーム・ページ名 はFile Detail 、フォーム・ページ・モード はドロワー を指定します。
データ・ソース としてRESTデータ・ソース を選び、RESTデータ・ソース としてList files を選択します。
ナビゲーション はデフォルト のまま変更せず、次 へ進みます。
主キー列1 に
ID (Varchar2) を選択します。
ページの作成 をクリックします。
RESTデータ・ソースList files をデータ・ソースとした対話モード・レポートとフォームのページが作成されます。
データ・ソースのList files のデータベース操作 は行のフェッチ だけで、行の挿入、行の更新、行の削除は含まれていません。そのため、ページ作成ウィザード は作成 、変更の適用 、削除 を実行するボタンやプロセスを生成していません。
作成されたページを実行します。
すでにアップロードされているファイルが存在すれば、対話モード・レポートに表示されます。
編集アイコンをクリックすると、ドロワーにフォームが開きます。
このページにファイルの作成(OpenAIへのアップロード)と削除の操作を追加します。
ページ・デザイナ で対話モード・レポートのページを開きます。
対話モード・レポートのリージョンにボタンを作成します。このボタンはページ作成ウィザードによって作成されるものと同じ設定にします。
識別 のボタン名 はCREATE 、ラベル は作成 とします。レイアウト の位置 として対話モード・レポートの検索バーの右 を選択します。外観 のホット はオン にします。
動作 のアクション としてこのアプリケーションのページにリダイレクト を選択し、ターゲット としてページ3 を設定します。
変更を保存 します。
ページ・デザイナ でフォームのページを開きます。
ページ・アイテムP3_BYTES 、P3_OBJECT 、P3_STATUS 、P3_FILENAME 、P3_CREATED_AT 、P3_STATUS_DETAILS を選択します。これらは表示のみの値でユーザーから値を入力することはありません。サーバー側の条件 のタイプ としてアイテムはNULLではない 、アイテム としてP3_ID を選択することで、ファイルの作成(アップロード)では表示されないようにします。
ページ・アイテムP3_PURPOSE を選択します。
識別 のタイプ をテキスト・フィールド に変更します。デフォルト のタイプ を静的 、静的値 としてassistants を設定します。アップロードするファイルの用途は、意識して変更しない限りRetrievalを用途とするassistantsを設定します。
アップロードするファイルを選択するページ・アイテムを作成します。
識別 の名前 はP3_FILE 、タイプ はファイルのアップロード 、ラベル はFile とします。ストレージ のタイプ は表APEX_APPLICATION_TEMP_FILES 、ファイルをパージするタイミング はリクエストの終わり です。セッション・ステート のストレージ はリクエストごと(メモリー) とします。
このページにファイルの更新処理は実装しないため、ファイルを選択するのはファイルの作成時(アップロード時)に限られます。サーバー側の条件 のタイプ にアイテムはNULL 、アイテム としてP3_ID を指定することにより、アップロード処理以外ではページ・アイテムが表示されないようにします。
ファイルの作成と削除を実行するボタンを作成します。
ファイルの作成を行うボタンは、ボタン名 をCREATE とします。設定は、ページ作成ウィザードによって作成されるボタンCREATEと同じ設定にします。
識別 のラベル は作成 、レイアウト の位置 はCreate 、外観 のホット はオン にします。動作 のアクション はページの送信 、サーバー側の条件 のタイプ はアイテムはNULL 、アイテム としてP3_ID を選択します。
ファイルの削除を行うボタンは、ボタン名 をDELETE とします。設定は、ページ作成ウィザードによって作成されるボタンDELETEと同じ設定にします。
識別 のラベル は削除 、レイアウト の位置 はDelete 、動作 のアクション はページの送信、確認の要求 をオン にします。確認 のメッセージ に「本当に削除しますか? 」と記述します。サーバー側の条件 のタイプ はアイテムはNULLではない 、アイテム としてP3_ID を選択します。
プロセス・ビュー を開き、ファイルのアップロードと削除を行うプロセスを作成します。
ファイルのアップロードを行うプロセスは、識別 の名前 をUpload File 、タイプ としてコードの実行 を選択します。ソース のPL/SQLコード に以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare
l_file clob;
begin
for r in (
select * from apex_application_temp_files
where name = :P3_FILE
)
loop
:P3_ID := utl_openai_files_api.upload_file(
p_filename => r.filename
,p_content_type => r.mime_type
,p_file_content => r.blob_content
,p_purpose => :P3_PURPOSE
,p_credential_static_id => :G_OPENAI_API_KEY
,p_file => l_file
);
end loop;
end;
成功メッセージ は「
ファイルがアップロードされました。 」とします。
サーバ側の条件 の
ボタン押下時 に
CREATE を指定します。
ファイルの削除を行うプロセスは、識別 の名前 をDelete File 、タイプ としてAPIの呼出し を選択します。設定 のパッケージ にUTL_OPENAI_FILES_API を選びプロシージャまたはファンクション としてDELETE_FILE を選択します。
成功メッセージ は「ファイルが削除されました。 」とします。サーバ側の条件 のボタン押下時 にDELETE を指定します。
パラメータファンクションの結果 を選択し、パラメータ の出力を無視 をオン にします。
パラメータp_file_id を選択し、値 のタイプ はアイテム 、アイテム としてP3_ID を指定します。
パラメータp_credential_static_id を選択し、値 のタイプ はアイテム 、アイテム としてG_OPENAI_API_KEY を指定します。
パラメータp_file を選択し、パラメータ の出力を無視 をオン にします。
以上で、OpenAIへのファイルのアップロードと削除を行うページは完成です。
パラメータp_credential_static_id に置換文字列G_OPENAI_API_KEY を設定すると、page item not found というエラーが発生します。エラーは発生しますが、きちんと置換文字列はパラメータとして渡されます。Oracle APEX 23.2以前では発生していなかったと思うのですが、きちんと確認していません。
パラメータのタイプ に静的値 、静的値 として&G_OPENAI_API_KEY. を設定すると、エラーの発生を回避できます。
アシスタントの作成と削除を行うページを作成します。
ファイルのときと同様に、対話モード・レポート のページの作成 を始めます。
対話モード・レポートのページのページ番号 は4 、名前 はAssistants 、ページ・モード は標準 です。フォーム・ページを含める をオン にし、フォーム・ページ番号 は5 、フォーム・ページ名 はAssistant Detail 、フォーム・ページ・モード はドロワー を指定します。
データ・ソース としてRESTデータ・ソース を選び、RESTデータ・ソース としてList assistants を選択します。
ナビゲーション はデフォルト のまま変更せず、次 へ進みます。
主キー列1 に
ID (Varchar2) を選択します。
ページの作成 をクリックします。
ファイルのときと同様に、対話モード・レポートのリージョンに作成 ボタンを作ります。
識別 のボタン名 はCREATE 、ラベル は作成 とします。レイアウト の位置 として対話モード・レポートの検索バーの右 を選択します。外観 のホット はオン にします。
動作 のアクション としてこのアプリケーションのページにリダイレクト を選択し、ターゲット としてページ5 を設定します。
変更を保存 します。
Assistant Fileとして使用するファイルの選択に使用するLOVを作成します。また、この後に使用するアシスタントを選択するLOVも作成します。
共有コンポーネント のLOV を開きます。
作成 をクリックします。
LOVの作成 として最初から を選択します。
次 へ進みます。
名前 は
LOV_FILES 、
タイプ は
Dynamic です。
次 へ進みます。
データ・ソース にRESTデータ・ソース を選び、RESTデータ・ソース としてList files を選択します。
次 へ進みます。
戻り列 としてID 、表示列 としてFILENAME を選択します。
作成 をクリックします。
同様の手順で、アシスタントのLOV、LOV_ASSISTANTSを作成します。
LOVの名前 はLOV_ASSISTANTS とします。
RESTデータ・ソース としてList assistants を選択します。
戻り列 としてID 、表示列 としてNAME を選択します。
作成 をクリックします。
共有コンポーネント の
LOV として、
LOV_FILES と
LOV_ASSISTANTS が作成されました。
ページ・デザイナ でページ番号5 のAssistant Detail のページを開きます。
ページ・アイテムP5_NAME 、P5_MODEL 、P5_OBJECT を選択し、識別 のタイプ をテキスト・フィールド に変更します。
ページ・アイテムP5_OBJECT とP5_CREATED_AT を選択し、サーバー側の条件 のタイプ にアイテムはNULLではない 、アイテム としてP5_ID を設定します。これらの値はユーザーが入力することはないためP5_IDがNULL、つまりアシスタントの作成時には表示しません。
アシスタントが使用するツールを設定するページ・アイテムを作成します。
識別 の名前 はP5_TOOLS 、タイプ はテキスト領域 、ラベル はTools とします。デフォルト のタイプ に静的 を選択し、静的値 として以下を記述します。今回のアプリケーションはretrieval のみの使用を想定していますが、記述を変えることによりCode InterpreterやFunction Callingも呼び出せるようにしておきます。
[{"type":"retrieval"}]
セッション・ステート のストレージ はリクエストごと(メモリーのみ) 、アシスタントの作成時のみページ・アイテムが表示されるように、サーバー側の条件 のタイプ はアイテムはNULL 、アイテム にP5_ID を指定します。
Retrievalが参照するファイル(Assistant Files)を選択するページ・アイテムを作成します。
識別 の名前 はP5_FILE_IDS 、タイプ はチェック・ボックス・グループ 、ラベル はFile Ids とします。LOV のタイプ として共有コンポーネント を選択し、LOV に先ほど作成したLOV_FILES を選択します。追加値の表示 はオフ です。
セッション・ステート のストレージ はリクエストごと(メモリーのみ) 、アシスタントの作成時のみページ・アイテムが表示されるように、サーバー側の条件 のタイプ はアイテムはNULL 、アイテム にP5_ID を指定します。
ページ・アイテムP5_MODEL のデフォルト として、タイプ が静的 、静的値 としてgpt-4-1106-preview を設定します。ツールとしてRetrievalを使うための設定です。
ボタンCREATE とDELETE を作成します。これはファイルを操作するフォームでの手順と同じです。サーバー側の条件 のアイテム としてP3_IDの代わりにP5_ID を指定します。
アシスタントを作成するプロセスを作ります。
識別 の名前 はCreate Assistant 、タイプ としてAPIの呼出し を選択します。設定 のパッケージ はUTL_OPENAI_ASSISTANTS_API 、プロシージャまたはファンクション としてCREATE_ASSISTANT を選択します。
成功メッセージ は「アシスタントが作成されました 。」とします。サーバー側の条件 のボタン押下時 にCREATE を指定します。
パラメータ
ファンクションの結果 の
値 の
アイテム は
P5_ID とします。
パラメータp_file_ids を選択します。ページ・アイテムP5_FILE_IDS はチェック・ボックス・グループ であるため、選択したファイルのIDがコロンを挟んで連結された文字列になります。これをJSON配列に変換します。
値 のタイプ としてファンクション本体 を選択し、PL/SQLファンクション本体 として以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare
l_array json_array_t;
begin
l_array := json_array_t();
for c in (
select column_value from apex_string.split(:P5_FILE_IDS,':')
)
loop
l_array.append(c.column_value);
end loop;
return l_array.to_clob();
end;
パラメータp_credential_static_id の値 のタイプ は静的値 、静的値 は&G_OPENAI_API_KEY. とします。
パラメータp_response はデバッグ用途なので、出力を無視 をオン にします。
アシスタントを削除するプロセスを作成します。
識別 の名前 はDelete Assistant 、タイプ としてAPIの呼出し を選択します。設定 のパッケージ はUTL_OPENAI_ASSISTANTS_API 、プロシージャまたはファンクション としてDELETE_ASSISTANT を選択します。
成功メッセージ は「アシスタントが削除されました 。」とします。サーバー側の条件 のボタン押下時 にDELETE を指定します。
パラメータp_assistant_id の値 のアイテム としてP5_ID を指定します。
パラメータp_credential_static_id の値 のタイプ は静的値 、静的値 は&G_OPENAI_API_KEY. とします。
パラメータp_credential_static_id にはすべて同じ設定を行うため、今後の説明は簡単にします。
パラメータファンクションの結果 、p_response 、p_object 、p_deleted は、パラメータ の出力を無視 をオン にします。
以上で、OpenAIのアシスタントの作成と削除を行うページは完成です。
もっとも主要なページである、スレッドの作成とメッセージの作成および問合せの実行を行うページを作成します。
ファイルやアシスタントのときと同様に、対話モード・レポート のページの作成 を始めます。
対話モード・レポートのページのページ番号 は6 、名前 はMessages 、ページ・モード は標準 です。フォーム・ページを含める をオン にし、フォーム・ページ番号 は7 、フォーム・ページ名 はMessage Detail 、フォーム・ページ・モード はドロワー を指定します。
データ・ソース としてRESTデータ・ソース を選び、RESTデータ・ソース としてList messages を選択します。
ナビゲーション はデフォルト のまま変更せず、次 へ進みます。
進んだ先で主キー列1 のID (Varchar2) を選択し、ページの作成 をクリックします。
メッセージ を扱う対話モード・レポートとフォームのページが作成されます。
スレッド の作成および削除、メッセージ の作成、スレッド の実行、実行 の確認、アシスタント が生成したメッセージの表示といった、今回作成するアプリケーションの主要な処理を、これらのページに実装します。
ページ・デザイナ でページ番号6 の対話モード・レポートのページを開きます。
スレッド を実行する
アシスタント を選択するページ・アイテムを作成します。
識別 の名前 はP6_ASSISTANT_ID 、タイプ は選択リスト 、ラベル はAssistant とします。検証 の必須の値 はオン です。
LOV のタイプ として共有コンポーネント を選択し、LOV として先ほど作成したLOV_ASSISTANTS を選びます。追加値の表示 はオフ 、NULL値の表示 をオン として、NULL表示値 に- アシスタントを選択 - と記述します。
セッション・ステート のストレージ はページを遷移した後でも値が維持されるように、セッションごと(永続) を選択します。
スレッドの作成と削除を行うボタンとスレッドIDを保持するページ・アイテムを載せるリージョンを作成します。以前はOpenAIのAssistants APIにList threadsがあり、作成済みのスレッドIDをAPIを呼び出して取り出せたのですが、そのAPIが無くなったため、代わりにスレッドIDをページ・アイテムに保持します。
リージョンを作成し、ページ・アイテムP6_ASSISTANT_ID の下に配置します。
識別 のタイトル をThread 、タイプ は静的コンテンツ とします。外観 のテンプレート としてItem Container を選択します。設定しなくても良いですが、ボタンとページ・アイテムの見栄えを良くするために、テンプレート・オプション を開きAlignment にCenter を選択します。
スレッドを作成するボタンを作ります。
識別 のボタン名 はCREATE_THREAD 、ラベル はスレッド作成 とします。レイアウト のリージョン にThread を選択し、位置 はButton Start とします。動作 のアクション はデフォルトのページの送信 です。
タイプが静的コンテンツのリージョンでテンプレートにItem Containerを選択すると、直接リージョンにボタンやページ・アイテムを作成することができません。一旦、Body直下にボタンやページ・アイテムを作成した後、レイアウトのリージョンとしてItem Containerのリージョンを設定する必要があります。
作成したスレッドIDを保持するページ・アイテムを作成します。
識別 の名前 はP6_THREAD_ID 、タイプ はテキスト・フィールド 、ラベル はThread ID とします。レイアウト のリージョン にThread を選択し、位置 はItem とします。
セッション・ステート のストレージ はページを遷移した後でも値が維持されるように、セッションごと(永続) を選択します。
スレッドを削除するボタンを作ります。
作成したスレッドはアプリケーション側で管理し、使わなくなったら削除する必要があります。今回のアプリケーションでは、利用者がスレッドの削除を実行します。使われなくなったスレッドの自動削除といった、ハウスキーピングの機能は実装していません。
識別 のボタン名 はDELETE_THREAD 、ラベル はスレッド削除 とします。レイアウト のリージョン にThread を選択し、位置 はButton End とします。動作 のアクション はデフォルトのページの送信 です。
確認の要求 をオン にし、確認 のメッセージ として「本当に削除しますか? 」と記述します。
対話モード・ポートのリージョンMessages を選択します。メッセージ の一覧を取得するには、Thread IDの指定が必要です。
ソース の送信するページ・アイテム にP6_THREAD_ID を指定します。サーバー側の条件 のタイプ にアイテムはNULLではない を選択し、アイテム にP6_THREAD_ID を指定します。
対話モード・レポートのパラメータ のthread_id を選択し、値 のタイプ にアイテム 、アイテム にP6_THREAD_ID を指定します。
スレッド の実行 を一覧する対話モード・レポートを作成します。
リージョンMessages を重複させ、識別 のタイトル をRuns 、RESTソース をList runs に変更します。
スレッドを実行するボタンを作成します。作成したボタンはリージョンThread の下に配置します。
識別 のボタン名 はRUN 、ラベル は実行 とします。外観 のホット をオン にし、テンプレート・オプション のWidth はStretch とします。
スレッド に紐づいたメッセージ と実行 の一覧(対話モード・レポート)を更新するボタンを作成します。作成したボタンはボタンRUN の下に配置します。
識別 のボタン名 はREFRESH 、ラベル はリフレッシュ とします。テンプレート・オプション のWidth はStretch とします。
動作 のアクション として動的アクションで定義 を選択します。
ボタン
REFRESH で動的アクションを作成します。ボタンをクリックすることで、リージョン
Messages と
Runs をリフレッシュします。
動的アクションの識別 の名前 はRefresh Messages and Runs とします。タイミング はボタンのデフォルトで、イベント はクリック 、選択タイプ はボタン 、ボタン はREFRESH になります。
TRUEアクション としてリフレッシュ を選択し、影響を受ける要素 の選択タイプ にリージョン 、リージョン としてMessages を指定します。
同様にリージョンRuns をリフレッシュするTRUEアクションを作成します。作成済みのTRUEアクションを重複 させ、影響を受ける要素 のリージョン をRuns に変更するとよいでしょう。
メッセージを新規に作成するボタンを、リージョンMessages に作ります。
識別 の名前 はCREATE 、ラベル はメッセージ作成 とします。レイアウト の位置 として、対話モード・レポートの検索バーの右 を選択します。外観 のホット をオン にします。
動作 のアクション としてこのアプリケーションのページにリダイレクト を選択します。
ターゲット をリンク・ビルダー で開き、ページ として7 、アイテムの設定 の名前 にP7_THREAD_ID 、値 に&P6_THREAD_ID. を設定します。
OpenAIのAssistants APIでメッセージ を作成するには、スレッド が必要です。
リージョンMessages を選択し、プロパティ・エディタ の属性 を開きます。
リンク のターゲット をリンク・ビルダーで開きます。
アイテムの設定 に、名前 としてP7_THREAD_ID 、値 に\&P6_THREAD_ID.\ を追加します。
ページの表示上の設定は以上で完了です。これからプロセスの作成を行います。
左ペインでプロセス・ビュー を開きます。
スレッド を作成するプロセスを作成します。
識別 の名前 はCreate Thread 、タイプ はAPI呼出し です。設定 のパッケージ としてUTL_OPENAI_ASSISTANTS_API 、プロシージャまたはファンクション としてCREATE_THREAD を指定します。成功メッセージ として「スレッドが作成されました。 」を記述します。
サーバー側の条件 のボタン押下時 にCREATE_THREAD を指定します。
パラメータ
ファンクションの結果 の
値 の
アイテム として
P6_THREAD_ID を指定します。
パラメータ
p_messages 、
p_metadata はデフォルトのまま変更しません。
p_credential_static_id は静的値 の&G_OPENAI_API_KEY. とします。p_response の出力は無視 します。この設定はパッケージUTL_OPENAI_ASSISTANTS_APIのAPI呼出しで共通です。
スレッドを削除するプロセスを作成します。
識別 の名前 はDelete Thread 、タイプ はAPI呼出し です。設定 のパッケージ としてUTL_OPENAI_ASSISTANTS_API 、プロシージャまたはファンクション としてDELETE_THREAD を指定します。成功メッセージ として「スレッドが削除されました。 」を記述します。
サーバー側の条件 のボタン押下時 にDELETE_THREAD を指定します。
パラメータ
ファンクションの結果 、
p_response 、
p_object 、
p_deleted を選択し、
出力を無視 を
オン にします。
パラメータ
p_thread_id には、デフォルトでページ・アイテム
P6_THREAD_ID が割り当たります。パラメータ
p_credential_static_id には、これまでと同様に
静的値 として
&G_OPENAI_API_KEY. を設定します。
スレッドを実行するプロセスを作成します。
識別 の名前 はCreate Run 、タイプ はAPI呼出し です。設定 のパッケージ としてUTL_OPENAI_ASSISTANTS_API 、プロシージャまたはファンクション としてCREATE_RUN を指定します。成功メッセージ として「スレッドの実行を開始しました。 」を記述します。
サーバー側の条件 のボタン押下時 にRUN を指定します。
パラメータファンクションの結果 とp_response を選択し、出力を無視 をオン にします。
デフォルトで、パラメータ
p_thread_id には
P6_THREAD_ID 、
p_assistant_id には
P6_ASSISTANT_ID が割り当たります。そのため変更は不要です。
パラメータ
p_model 、
p_instructions 、
p_tools 、
p_metadata はAPIデフォルトのまま変更しません(結果としてP6_ASSISTANT_IDとして指定されたアシスタントの設定が使用されます)。これらのパラメータも変更は不要です。
パラメータp_credential_static_id の値 は、静的値 の&G_OPENAI_API_KEY. とします。
スレッドを削除した時にセッション・ステートをクリアするプロセスを作成します。
識別 の名前 をClear Session State after Delete とします。タイプ としてセッション・ステートのクリア を選択します。設定 のタイプ として現在のページのすべてのアイテムのクリア を選択します。ページ・アイテムP6_ASSISTANT_ID とP6_THREAD_ID が未設定の状態になります。
サーバー側の条件 のボタン押下時 にDELETE_THREAD を指定します。
以上で、スレッドの作成、削除および実行について実装ができました。
メッセージの作成と表示をページ番号7 のフォームのページに実装します。
ページ・デザイナ でページ番号7 のフォームのページを開きます。
RESTデータ・ソースのデータ・プロファイルの設定により、ページ・アイテムP7_ROLE 、P7_OBJECT 、P7_RUN_ID 、P7_THREAD_ID 、P7_ASSISTANT_ID のタイプがテキスト領域になっています。
これらのページ・アイテムをすべて選択し、タイプ をテキスト・フィールド に変更します。
ページ・アイテムP7_ROLE に計算 を作成し、デフォルトの値をuser にします。
ページ・アイテムP7_ROLE に作成した計算 の、計算 のタイプ に静的値 を選択し、静的値 としてuser を指定します。サーバー側の条件 のタイプ としてアイテムはNULL を選択し、アイテム にP7_ROLE を指定します。実行 のポイント がリージョンの前 であることを確認します。
これでページ・アイテムP7_ROLE に値が未設定の場合は、値がuser になります。
ページ・アイテムP7_OBJECT 、P7_RUN_ID 、P7_CREATED_AT 、P7_ASSISTANT_ID は、作成済みのメッセージに含まれる値であり、メッセージ作成時の引数にはなりません。
そのため、これらのページ・アイテムを選択し、サーバー側の条件 のタイプ としてアイテムはNULLではない を選択し、アイテム としてP7_ID を指定します。
メッセージ(Message オブジェクト)のcontent に含まれるtext 部分を表示するページ・アイテムを作成します。OpenAIのアシスタントが、Markdownのメッセージを返すことを想定しています。
識別 の名前 はP7_TEXT 、タイプ はMarkdownエディタ 、ラベル はText とします。用途は表示のみなので、設定 のツールバー はなし 、構文の強調表示 もなし とします。
セッション・ステート のデータ型 としてCLOB を選択し、ストレージ はリクエストごと(メモリーのみ) とします。
サーバー側の条件 のタイプ としてアイテムはNULLではない を選択し、アイテム としてP7_TEXT を指定します。表示すべきデータがあるときに限り、ページ・アイテムP7_TEXT を表示します。
メッセージのcontent を入力するページ・アイテムを作成します。メッセージを作成するときは、単純な文字列として扱います。メッセージを表示するときは、Messageオブジェクトのcontent はJSONドキュメントとして返されるため、JSONのまま表示します。
識別 の名前 はP7_CONTENT 、タイプ はテキスト領域 、ラベル はContent とします。
セッション・ステート のデータ型 としてCLOB を選択し、ストレージ はリクエストごと(メモリーのみ) とします。
レンダリング前 のヘッダー前 にあるプロセス初期化フォームMessage Detail を、OpenAI Assistants APIのRetrieve Messageを呼び出してメッセージの内容を取得するように変更します。
プロセス初期化フォームMessage Detail を選択します。
タイプ をAPIの呼出し に変更します。設定 のパッケージ としてUTL_OPENAI_ASSISTANTS_API を選択し、プロシージャまたはファンクション としてRETRIEVE_MESSAGE を指定します。
サーバー側の条件 のタイプ としてアイテムはNULLではない を選択し、アイテム としてP7_ID を指定します。
パラメータp_message_id の値 のタイプ をアイテム 、アイテム としてP7_ID を指定します。
パラメータ
ファンクションの結果 、
p_response 、
p_file_ids 、
p_metadata を選択し、
出力の無視 を
オン にします。
パラメータp_credential_static_id の値 は、静的値 の&G_OPENAI_API_KEY. とします。
content として返されるJSONドキュメントをプリティ・プリントするプロセスを作成します。プロセスを作成し、初期化フォームMessage Detail の下に配置します。
識別 の名前 はContent Pretty Print 、タイプ はコードを実行 とします。ソース のPL/SQLコード として以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare
l_raw_json clob;
l_pretty_output clob;
begin
l_raw_json := :P7_CONTENT;
select json_serialize(
l_raw_json returning clob pretty
) into l_pretty_output
from dual;
:P7_CONTENT := l_pretty_output;
end;
サーバー側の条件 のタイプ としてアイテムはNULLではない を選択し、アイテム としてP7_CONTENT を指定します。
メッセージのcontent の内容からtext を取り出すプロセスを作成します。作成したプロセスは、プロセスContent Pretty Print の下に配置します。
識別 の名前 はRetrieve Text From Content 、タイプ はコードを実行 とします。ソース のPL/SQLコード として以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare
l_contents json_array_t;
l_content json_object_t;
l_text_json json_object_t;
l_text clob;
begin
l_contents := json_array_t(:P7_CONTENT);
for i in 1..l_contents.get_size()
loop
l_content := treat(l_contents.get(i-1) as json_object_t);
if l_content.get_string('type') = 'text' then
l_text_json := l_content.get_object('text');
l_text := l_text || l_text_json.get_string('value');
end if;
end loop;
:P7_TEXT := l_text;
end;
サーバー側の条件 のタイプ としてアイテムはNULLではない を選択し、アイテム としてP7_CONTENT を指定します。
ページ作成ウィザードでソースとして指定したRESTデータ・ソースには、作成にあたるデータベース操作が実装されていないため、フォームに作成ボタンが作られていません。作成をボタンをフォームに作成します。
識別 のボタン名 はCREATE 、ラベル は作成 とします。レイアウト のリージョン はボタン 、位置 はCreate とします。外観 のホット をオン にします。
動作 のアクション はデフォルトのページの送信 です。
サーバー側の条件 のタイプ としてアイテムはNULL を選択し、アイテム としてP7_ID を指定します。
ボタンを押した時に実行される、メッセージを作成するプロセスを作成します。
プロセス・ビュー を開き、プロセスを作成します。作成したプロセスはダイアログを閉じる の上に配置します。
識別 の名前 はCreate Message 、タイプ はAPIの呼出し とします。設定 のパッケージ としてUTL_OPENAI_ASSISTANTS_API を選択し、パッケージまたはファンクション としてCREATE_MESSAGE を指定します。成功メッセージ として「メッセージが作成されたした。 」と記述します。
サーバー側の条件 のボタン押下時 にCREATE を指定します。
パラメータ
ファンクションの結果 を選択し、
値 の
アイテム として
P7_ID を指定します。
パラメータp_thread_id 、p_role 、p_content にはそれぞれデフォルトで、ページ・アイテムP7_THREAD_ID 、P7_ROLE 、P7_CONTENT が割り当たります。パラメータp_file_ids 、p_metadata はAPIデフォルト とする(つまり無指定)ため、変更は不要です。
パラメータp_credential_static_id の値 として、静的値 の&G_OPENAI_API_KEY. を設定し、パラメータp_response の出力は無視 します。
以上で、OpenAIのAssistants APIを呼び出しRetrievalを実行するAPEXアプリケーションは完成です。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完