2023年12月4日月曜日

OpenAIのAssistants APIを呼び出しRetrievalを実行するAPEXアプリケーションを作成する

OpenAIのAssistants APIを呼び出してRetrievalを実行するAPEXアプリケーションを作成してみました。

GIF動画では、以下に列記した操作を行なっています。

  1. Filesのページを開き、Oracle APEX 23.2の新機能について記述されたWebページのテキストをOpenAIにアップロードします。こちらののページがソースです。
  2. Assistantsのページを開き、アシスタントを作成します。toolsとしてretrievalを指定し、アップロードしたファイルをAssistant Filesに含めています。
  3. Messagesのページを開きます。
  4. 新規にスレッドを作成します。
  5. メッセージを作成します。Contentには「Oracle APEX 23.2の新機能を、手短に一覧にしてください。」と記述しました。
  6. 実行します。
  7. Runオブジェクトが作成されます。リフレッシュをクリックし、Statuscompletedになるまで待ちます。
  8. Statuscompletedになった後に、Roleassistantのメッセージ(OpenAI側で生成されたメッセージ)の内容を確認します。


今回の問い合わせでは、以下の回答が得られました。

Oracle APEX 23.2の新機能は以下のとおりです:

  1. アプリケーションの作業用コピー: バグ修正や機能追加後、選択的に変更をメインアプリケーションにマージできます。複数の開発者が1つのアプリケーションへの変更をコントリビュートすることが可能です【9†source】。

  2. 無制限の属性: 開発者はテンプレート・コンポーネント・プラグインを25属性という制約なしに作成でき、テンプレート・コンポーネントのレンダリングがより高速になりました【13†source】。

  3. ユニバーサル・テーマのさらなる活用: ユニバーサル・テーマに付属するいくつかのテンプレート・コンポーネントが更新され、開発者はアプリケーション全体でテンプレート・コンポーネントの使用方法の汎用性が向上しました【13†source】。

  4. 開発者エクスペリエンス向上: 共有コンポーネントのサブスクリプションが改善され、サブスクライブされたコンポーネントが読取り専用となりました。自動依存性解決機能が加わり、サブスクリプションのステータスが共有コンポーネントレポートに表示されるようになりました。更に、一括リフレッシュと削除の機能が提供されます【13†source】。

  5. クイックSQLの更新: 生成されたSQLスクリプトとE-Rダイアグラムが即座にリフレッシュされ、データモデルの視覚化やユーザー・エクスペリエンスの簡素化が可能になりました【13†source】。

  6. 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_APIRESTデータ・ソースList filesを流用します。


記事「Oracle APEXのアプリケーションからOpenAIのAssistants APIを呼び出す」より、パッケージUTL_OPENAI_ASSISTANTS_APIRESTデータ・ソースList assistantsList messagesList runsを流用します。

パッケージUTL_OPENAI_ASSISTANTS_API: https://gist.github.com/ujnak/894aa93d7db34a6970345798ad7f86ac

パッケージ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 assistantsList messagesList runsおよびOpenAI Files APIのList filesを作成する準備ができました。

新規にアプリケーションを作成します。名前OpenAI Retrieval Assistantとします。

アプリケーションの作成をクリックします。


アプリケーションが作成されたら、共有コンポーネントRESTデータ・ソースを開きます。

作成をクリックします。


RESTデータ・ソースの作成としてRESTソース・カタログからを選択します。

へ進みます。


RESTソース・カタログのOpenAI Assistants API参照をクリックします。


List assistantsList messagesList runsのプラスをクリックして、作成するRESTデータ・ソースとして選択します。なお、List threadsのAPIはAssistants APIより削除されたか、仕様が変わったため利用できなくなった模様です。


選択が完了したら、へ進みます。


OpenAIのAPIにアクセスするためのWeb資格証明を選択します。Web資格証明の作成方法については、記事「OpenAIのChatGPTのAPIを呼び出すAPEXアプリを作る」を参照してください。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースとしてList assistantsList messagesList 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を選択します。

ナビゲーションデフォルトのまま変更せず、へ進みます。


主キー列1ID (Varchar2)を選択します。

ページの作成をクリックします。


RESTデータ・ソースList filesをデータ・ソースとした対話モード・レポートとフォームのページが作成されます。

データ・ソースのList filesデータベース操作行のフェッチだけで、行の挿入、行の更新、行の削除は含まれていません。そのため、ページ作成ウィザード作成変更の適用削除を実行するボタンやプロセスを生成していません。


作成されたページを実行します。

すでにアップロードされているファイルが存在すれば、対話モード・レポートに表示されます。


編集アイコンをクリックすると、ドロワーにフォームが開きます。


このページにファイルの作成(OpenAIへのアップロード)と削除の操作を追加します。

ページ・デザイナで対話モード・レポートのページを開きます。

対話モード・レポートのリージョンにボタンを作成します。このボタンはページ作成ウィザードによって作成されるものと同じ設定にします。

識別ボタン名CREATEラベル作成とします。レイアウト位置として対話モード・レポートの検索バーの右を選択します。外観ホットオンにします。

動作アクションとしてこのアプリケーションのページにリダイレクトを選択し、ターゲットとしてページ3を設定します。

変更を保存します。


ページ・デザイナでフォームのページを開きます。

ページ・アイテムP3_BYTESP3_OBJECTP3_STATUSP3_FILENAMEP3_CREATED_ATP3_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コードに以下を記述します。

成功メッセージは「ファイルがアップロードされました。」とします。サーバ側の条件ボタン押下時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を選択します。

ナビゲーションデフォルトのまま変更せず、へ進みます。


主キー列1ID (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_FILESLOV_ASSISTANTSが作成されました。


ページ・デザイナでページ番号Assistant Detailのページを開きます。

ページ・アイテムP5_NAMEP5_MODELP5_OBJECTを選択し、識別タイプテキスト・フィールドに変更します。


ページ・アイテムP5_OBJECTP5_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を使うための設定です。


ボタンCREATEDELETEを作成します。これはファイルを操作するフォームでの手順と同じです。サーバー側の条件アイテムとして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ファンクション本体として以下を記述します。



パラメータ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_responsep_objectp_deletedは、パラメータ出力を無視オンにします。


以上で、OpenAIのアシスタントの作成と削除を行うページは完成です。

もっとも主要なページである、スレッドの作成とメッセージの作成および問合せの実行を行うページを作成します。

ファイルやアシスタントのときと同様に、対話モード・レポートページの作成を始めます。

対話モード・レポートのページのページ番号6名前Messagesページ・モード標準です。フォーム・ページを含めるオンにし、フォーム・ページ番号7フォーム・ページ名Message Detailフォーム・ページ・モードドロワーを指定します。

データ・ソースとしてRESTデータ・ソースを選び、RESTデータ・ソースとしてList messagesを選択します。

ナビゲーションデフォルトのまま変更せず、へ進みます。

進んだ先で主キー列1ID (Varchar2)を選択し、ページの作成をクリックします。


メッセージを扱う対話モード・レポートとフォームのページが作成されます。

スレッドの作成および削除、メッセージの作成、スレッドの実行、実行の確認、アシスタントが生成したメッセージの表示といった、今回作成するアプリケーションの主要な処理を、これらのページに実装します。


ページ・デザイナでページ番号の対話モード・レポートのページを開きます。

スレッドを実行するアシスタントを選択するページ・アイテムを作成します。

識別名前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を選択します。設定しなくても良いですが、ボタンとページ・アイテムの見栄えを良くするために、テンプレート・オプションを開きAlignmentCenterを選択します。


スレッドを作成するボタンを作ります。

識別ボタン名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を重複させ、識別タイトルRunsRESTソースList runsに変更します。


スレッドを実行するボタンを作成します。作成したボタンはリージョンThreadの下に配置します。

識別ボタン名RUNラベル実行とします。外観ホットオンにし、テンプレート・オプションWidthStretchとします。


スレッドに紐づいたメッセージ実行の一覧(対話モード・レポート)を更新するボタンを作成します。作成したボタンはボタンRUNの下に配置します。

識別ボタン名REFRESHラベルリフレッシュとします。テンプレート・オプションWidthStretchとします。

動作アクションとして動的アクションで定義を選択します。


ボタンREFRESHで動的アクションを作成します。ボタンをクリックすることで、リージョンMessagesRunsをリフレッシュします。

動的アクションの識別名前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_messagesp_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_responsep_objectp_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_IDp_assistant_idにはP6_ASSISTANT_IDが割り当たります。そのため変更は不要です。

パラメータp_modelp_instructionsp_toolsp_metadataはAPIデフォルトのまま変更しません(結果としてP6_ASSISTANT_IDとして指定されたアシスタントの設定が使用されます)。これらのパラメータも変更は不要です。

パラメータp_credential_static_idは、静的値&G_OPENAI_API_KEY.とします。

スレッドを削除した時にセッション・ステートをクリアするプロセスを作成します。

識別名前Clear Session State after Deleteとします。タイプとしてセッション・ステートのクリアを選択します。設定タイプとして現在のページのすべてのアイテムのクリアを選択します。ページ・アイテムP6_ASSISTANT_IDP6_THREAD_IDが未設定の状態になります。

サーバー側の条件ボタン押下時DELETE_THREADを指定します。


以上で、スレッドの作成、削除および実行について実装ができました。

メッセージの作成と表示をページ番号のフォームのページに実装します。

ページ・デザイナでページ番号のフォームのページを開きます。

RESTデータ・ソースのデータ・プロファイルの設定により、ページ・アイテムP7_ROLEP7_OBJECTP7_RUN_IDP7_THREAD_IDP7_ASSISTANT_IDのタイプがテキスト領域になっています。

これらのページ・アイテムをすべて選択し、タイプテキスト・フィールドに変更します。


ページ・アイテムP7_ROLE計算を作成し、デフォルトの値をuserにします。

ページ・アイテムP7_ROLEに作成した計算の、計算タイプ静的値を選択し、静的値としてuserを指定します。サーバー側の条件タイプとしてアイテムはNULLを選択し、アイテムP7_ROLEを指定します。実行ポイントリージョンの前であることを確認します。

これでページ・アイテムP7_ROLEに値が未設定の場合は、値がuserになります。


ページ・アイテムP7_OBJECTP7_RUN_IDP7_CREATED_ATP7_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_responsep_file_idsp_metadataを選択し、出力の無視オンにします。


パラメータp_credential_static_idは、静的値&G_OPENAI_API_KEY.とします。

contentとして返されるJSONドキュメントをプリティ・プリントするプロセスを作成します。プロセスを作成し、初期化フォームMessage Detailの下に配置します。

識別名前Content Pretty Printタイプコードを実行とします。ソースPL/SQLコードとして以下を記述します。


サーバー側の条件タイプとしてアイテムはNULLではないを選択し、アイテムとしてP7_CONTENTを指定します。


メッセージのcontentの内容からtextを取り出すプロセスを作成します。作成したプロセスは、プロセスContent Pretty Printの下に配置します。

識別名前Retrieve Text From Contentタイプコードを実行とします。ソースPL/SQLコードとして以下を記述します。


サーバー側の条件タイプとしてアイテムはNULLではないを選択し、アイテムとしてP7_CONTENTを指定します。


ページ作成ウィザードでソースとして指定したRESTデータ・ソースには、作成にあたるデータベース操作が実装されていないため、フォームに作成ボタンが作られていません。作成をボタンをフォームに作成します。

識別ボタン名CREATEラベル作成とします。レイアウトリージョンボタン位置Createとします。外観ホットオンにします。

動作アクションはデフォルトのページの送信です。

サーバー側の条件タイプとしてアイテムはNULLを選択し、アイテムとしてP7_IDを指定します。


ボタンを押した時に実行される、メッセージを作成するプロセスを作成します。

プロセス・ビューを開き、プロセスを作成します。作成したプロセスはダイアログを閉じるの上に配置します。

識別名前Create MessageタイプAPIの呼出しとします。設定パッケージとしてUTL_OPENAI_ASSISTANTS_APIを選択し、パッケージまたはファンクションとしてCREATE_MESSAGEを指定します。成功メッセージとして「メッセージが作成されたした。」と記述します。

サーバー側の条件ボタン押下時CREATEを指定します。


パラメータファンクションの結果を選択し、アイテムとしてP7_IDを指定します。


パラメータp_thread_idp_rolep_contentにはそれぞれデフォルトで、ページ・アイテムP7_THREAD_IDP7_ROLEP7_CONTENTが割り当たります。パラメータp_file_idsp_metadataAPIデフォルトとする(つまり無指定)ため、変更は不要です。

パラメータp_credential_static_idとして、静的値&G_OPENAI_API_KEY.を設定し、パラメータp_response出力は無視します。

以上で、OpenAIのAssistants APIを呼び出しRetrievalを実行するAPEXアプリケーションは完成です。

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