2023年12月5日火曜日

OpenAIのAssistants APIを呼び出すアプリのツールにCode InterpreterとFunction Callingを追加する

先日作成したOpenAI Assistants APIを呼び出してRetrievalを実行するAPEXアプリケーションに、ツールとしてCode InterpreterとFunction Callingを追加してみました。Function Callingを呼び出すアプリケーションは以前に「OpenAI ChatGPTのFunction Callingを使ってPL/SQLプロシージャを呼び出す」として記事にしています。Function Callingに関しては、この記事の実装を流用します。

Function Callingを使って東京の天気を問い合わせています。


今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-openai-assistant.zip

以下よりアプリケーションの作成手順を紹介します。

クイックSQLの以下のモデルから、表OPENAI_FUNCTIONSOPENAI_FUNCTION_SETを作成します。


ページ作成ウィザードを起動し、対話モード・レポートを選択します。表OPENAI_FUNCTIONSフォーム付き対話モード・レポートのページを作成します。

対話モード・レポートページ番号98は別のページで使うので空けておきます)、名前Functionsフォームフォーム・ページ番号10フォーム・ページ名Function Detailとします。データ・ソース表/ビューの名前OPENAI_FUNCTIONSを指定します。

それ以外はデフォルトでに進み、主キー列1ID (Number)を指定してページの作成を実行します。


同様に表OPENAI_FUNCTION_SETフォーム付き対話モード・レポートのページを作成します。

対話モード・レポートページ番号11名前Function Setフォームフォーム・ページ番号12フォーム・ページ名Function Set Detailとします。データ・ソース表/ビューの名前OPENAI_FUNCTION_SETを指定します。

それ以外はデフォルトでに進み、主キー列1ID (Number)を指定してページの作成を実行します。


OPENAI_FUNCTIONSOPENAI_FUNCTION_SETを編集するページができたので、記事「OpenAI ChatGPTのFunction Callingを使ってPL/SQLプロシージャを呼び出す」を参照して、PL/SQLファンクションGET_CURRENT_WEATERを作成します。表OPENAI_FUNCTIONSにファンクションとしてget_current_weatherを登録し、表OPENAI_FUNCTION_SETにファンクションget_current_weaterを含んだFunction SetとしてWeatherを作成します。

アシスタントを作成する際に上記のファンクションセットを選択できるように、共有コンポーネントLOVを作成します。

作成するLOVの名前LOV_FUNCTION_SETとします。タイプDynamicです。

へ進みます。


表ビューの名前としてOPENAI_FUNCTION_SET (表)を選択します。

へ進みます。


戻り列ID表示列FUNCTION_SET_NAMEです。

作成をクリックすると、LOV_FUNCTION_SETが作成されます。


Function Callingを呼び出す際に使用するパッケージUTL_OPENAI_TOOLS_APIを作成します。以下のパッケージのコードを実行します。


アシスタントの作成時にツールとしてCode InterpreterFunction Callingを設定できるようにします。

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

ページ・アイテムP5_TOOLSを選択します。現在はデフォルトの値を[{ "type": "retrieval" }]として、ツールとしてRetrievalを使用する設定になっています。

識別タイプチェック・ボックス・グループに変更します。設定列の数にします。LOVタイプ静的値を選択し、静的値として以下を設定します。戻り値CODE_INTERPRETERRETRIEVALFUNCTION_CALLINGのどれか、または全てを含みます。


追加値の表示オフです。

デフォルトタイプ- 選択 -に戻し、無指定にします。


ツールに含めるfunctionを決めるfunction setを選択するページ・アイテムを作成します。作成したページ・アイテムはページ・アイテムP5_FILE_IDSの下に配置します。

識別名前P5_FUNCTION_SET_IDタイプラジオ・グループです。レイアウト新規行の開始オフにし、ページ・アイテムP5_FILE_IDSの右隣に配置します。

LOVタイプ共有コンポーネントを選択し、LOVとしてLOV_FUNCTION_SETを選びます。追加値の表示オフNULL値の表示オフです。

セッション・ステートストレージリクエストごと(メモリーのみ)とし、サーバー側の条件タイプアイテムはNULLアイテムP5_IDを指定し、アシスタントの作成時のみ設定できるようにします。


プロセス・ビューを開き、プロセスCreate Assisantのパラメータp_toolsを選択します。

タイプファンクション本体に変更し、PL/SQLファンクション本体として以下を記述します。



以上で作成するアシスタントのツールにCode Interpreter、RetrievalおよびFunction Callingを含めることができるようになりました。

現在の天気を確認するアシスタントを作成します。NameMy Weather Forecast AssistantInstructionsは「あなたは日本の天気を教えてくれるアシスタントです。」とします。ToolsFunction Callingにチェックを入れ、Function SetとしてWeatherを選択します。

作成をクリックします。


APIを呼び出して作成したアシスタントも、OpenAIのAssistantsのPlaygroundで扱うことができます。


アシスタントを作成したので、Messagesのページよりスレッドの作成を行います。メッセージとして「現在の東京の天気を教えてください。」を作成し、スレッド実行します。

実行したスレッドはStatusrequires_actionで停止します。

アシスタントがファンクションの呼び出しを要求していて、その結果を待っている状態です。Oracle APEX側で要求されているストアド・プロシージャを実行し、その実行結果をOpenAI Assistants APIのSubmit Tool Outputsを呼び出してアップロードする必要があります。


Runオブジェクトの内容を表示するページを作成し、そのページにSubmit Tool Outputsを呼び出すボタンを作成します。

ページの作成をクリックし、ページ作成ウィザードを開始します。

フォームを選択します。


ページ番号8名前Run Detailとします。ページ・モードドロワーを選択します。データ・ソースとしてRESTデータ・ソースを選択し、RESTデータ・ソースとしてList runsを選びます。

ドロワーなので、ナビゲーションは双方ともオフです。

へ進み、主キー列1ID (Varchar2)を選択し、ページを作成します。


作成されたページを編集します。

ページ・アイテムP8_IDの除くすべてのページ・アイテムを選択し、識別タイプ表示のみに変更します。


デバッグ用にページ・アイテムP8_RESPONSEを作成します。タイプテキスト領域ラベルResponseとします。

セッション・ステートデータ型CLOBストレージリクエストごと(メモリのみ)を指定します。


レンダリング前ヘッダーの前にあるプロセス初期化フォームRun Detailを選択します。

識別タイプAPIの呼出しに変更し、設定パッケージとしてUTL_OPENAI_ASSISTANTS_APIプロシージャまたはファンクションとしてRETRIEVE_RUNを指定します。

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


パラメータp_run_idを選択し、アイテムとしてP8_IDを指定します。


パラメータファンクションの結果p_toolsp_file_idsp_metadataを選択し、パラメータ出力を無視オンにします。


Assistants APIのSubmit Tool Outputsを発行するボタンを作成します。

識別ボタン名SUBMIT_TOOL_OUTPUTSラベルSubmit Tool Outputsとします。外観ホットオンテンプレート・オプションWidthStretchにします。

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

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


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

識別名前Submit Tool OutputsタイプとしてAPIの呼出しを選択します。設定パッケージUTL_OPENAI_TOOLS_APIプロシージャまたはファンクションとしてSUBMIT_TOOL_OUTPUTSを指定します。

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


パラメータp_run_idの値のアイテムはP8_IDとします。


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

パラメータp_required_actionp_tool_outputは、パラメータ出力を無視オンにします。


プロセスダイアログを閉じるを選択し、サーバー側の条件SUBMIT_TOOL_OUTPUTSを追記します。ボタンSUBMIT_TOOL_OUTPUTSを押した後にドロワーが閉じられます。


フォームのページについては、以上で完成です。

ページ番号List runsをソースとした対話モード・レポートから、ドロワーを開く設定を追加します。

リージョンRunsを選択し、プロパティ・エディタ属性タブを開きます。リンクターゲットをクリックし、リンク・ビルダーを開きます。


ターゲットタイプとしてこのアプリケーションのページページとして先ほど作成したドロワーのページである8を指定します。

アイテムの設定名前P8_ID(P7_IDから変更します)に\#ID#\、その次に名前P8_THREAD_ID\&P6_THREAD_ID.\を設定します。


リージョンRunsから開かれたドロワーが閉じた時に、対話モード・レポートがリフレッシュされるように、動的アクションをリージョンRunsに作成します。

作成した動的アクションの識別名前ダイアログのクローズとします。タイミングイベントとしてダイアログのクローズを選択し、選択タイプリージョンリージョンとしてRunsを指定します。


TRUEアクションとしてリフレッシュを選択します。影響を受ける要素選択タイプリージョンリージョンとしてRunsを選択します。


以上で、OpenAIのAssistants APIからCode InterpreterとFunction Callingを呼び出す機能を追加できました。

Code Interpreterの処理の過程を確認するためには、Run Stepsを見る必要があります。

Run Stepsを参照するページを追加します。

RESTソース・カタログのOpenAI Assistants APIよりList run stepsを選択し、RESTデータ・ソースList run stepsを作成します。


RESTデータ・ソースList run stepsをソースとしたフォーム付き対話モード・レポートのページを作成します。主キー列1ID (Varchar2)を選択します。


対話モード・レポートのページに、RESTソースList run stepsの必須パラメータであるRun IDを保持するページ・アイテムP13_RUN_IDを作成します。

タイプテキスト・フィールドラベルRun IDセッション・ステートストレージセッションごと(永続)とします。


同様に必須パラメータであるThread IDを保持するページ・アイテムP13_THREAD_IDを作成します。ラベルThread IDになります。


リージョンRun Stepsのパラメータを設定します。

パラメータrun_idタイプアイテムアイテムとしてP13_RUN_IDを指定します。


パラメータthread_idタイプアイテムアイテムとしてP13_THREAD_IDを指定します。


リージョンRun Stepsを選択し、ソース送信するページ・アイテムとしてP13_RUN_IDP13_THREAD_IDを指定します。


プロパティ・エディタ属性タブを開き、リンクターゲットをクリックしてリンク・ビルダーを開きます。


アイテムの設定に、名前P14_RUN_ID\#RUN_ID#\名前P14_THREAD_ID\#THREAD_ID#\の組み合わせを追加します。


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

Run Stepの詳細を確認するためにページ・アイテムを4つ作成します。タイプはすべて表示のみです。

作成するページ・アイテムはP14_RESPONSEP14_STEP_DETAILSP14_EXPIRE_ATP14_METADATAです。セッション・ステートデータ型P14_EXPIRED_ATを除いてCLOBP14_EXPIRED_ATVARCHAR2)、ストレージリクエストごと(メモリーのみ)とします。


ページ・アイテムP14_IDを除いた既存のページ・アイテムをすべて選択し、タイプ表示のみに変更します。


レンダリング前ヘッダーの前にあるプロセス初期化フォームRun Stepsを選択します。

識別タイプAPIの呼出しに変更し、設定パッケージとしてUTL_OPENAI_ASSISTANTS_APIプロシージャまたはファンクションとしてRETRIEVE_RUN_STEPを指定します。

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


パラメータp_step_idタイプアイテムアイテムP14_IDとします。


パラメータファンクションの結果パラメータ出力を無視オンにします。


ページ番号6のMessagesの対話モード・レポートからRun Stepsのページに遷移できるように、リンクを設定します。

リージョンMessagesの列RUN_IDを選択し、タイプリンクに変更します。リンクターゲットクリックし、リンク・ビルダーを開きます。


ターゲットタイプこのアプリケーションのページページ13を指定します。

アイテム設定に、名前P13_RUN_ID#RUN_ID#名前P13_THREAD_ID#THREAD_ID#の組み合わせを追加します。


以上でRun Stepsを表示するページも完成です。

以下はCode Interpreterを呼び出したGIF動画になります。


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

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