OpenAIよりAssistants APIのベータ版がリリースされました。Oracle APEXよりAssistants APIを呼び出すアプリケーションを作成してみました。
2023年12月1日追記
OpenAIのAssistants APIよりList threadsが削除されたようです。そのためThreadsの扱いは変更する必要があります。
以下の動画は、Assistants APIのOverviewで紹介されている手順を実行しています。
Assistants APIでは、オブジェクトのタイプとしてassistant、assistant.file、thread、message、message.file、run、run.stepを定義し、それぞれのオブジェクトにCreate、Modify、Retrieve、Delete、List(厳密にいうとListはオブジェクトへの操作ではありません)の操作を実装しています。オブジェクトのタイプによっては、一部の操作は実装されていません。例えば、messageオブジェクトにDelete操作はありません。これ以外の特別なAPIとしては、Submit tool outputs to run、Create thread and run、Cancel a runがあります。パッケージUTL_OPENAI_ASSISTANTS_APIにはCreate thread and runの呼び出しは含まれていません。また、List操作はRESTデータ・ソースとして作成したので、パッケージにList操作を呼び出すファンクションは含まれていません。
オブジェクト・タイプが定義されていて、それぞれのオブジェクトにいわゆるCRUD操作(Create、Read、Update、Delete)があるので、Oracle APEXとしては扱いやすい形式です。ただし、RESTサービスからはAPEXアプリケーションを自動生成することはできません。OpenAIのAssistants APIのリファレンスには、ぞれぞれのオブジェクト・タイプの定義が記載されています。その情報を元に、仮のスキーマを生成します。クイックSQLの以下のモデルからスキーマを生成します。
SQLの生成、SQLスクリプトの保存、レビューおよび実行を行います。SQLの実行を確認する画面では、即時実行をクリックします。
SQLスクリプトが実行され、表や索引がすべて生成された時点で、アプリケーションの作成を実行します。
アプリケーション作成ウィザードが起動します。Assistants、Threads、Messagesといったすべてのオブジェクト・タイプに対応したフォーム付き対話モード・レポートのページが追加されています。
アプリケーションの作成を実行します。
アプリケーションが作成されます。このアプリケーションを元に、データ・ソースやプロセスをAssistants APIを呼び出すように、置き換えていきます。
アプリケーション作成直後の状態です。
Assistantsを開くと、Assistantsを一覧する対話モード・レポートのページが表示されます。
作成をクリックします。
オブジェクトAssistantsが持つ属性の入力画面が、画面右よりドロワーとして開きます。
ページ・デザイナを開きます。
フォームが開く時に、データ・ソースより値を取り出しページ・アイテムに設定するプロセス初期化フォームAssistantが作成されています。
このプロセスをAssistants APIのRetrieve assistant APIの呼び出しに置き換えます。
識別の名前はRetrieve assistant、タイプとしてAPIの呼び出しを選択します。設定のタイプにPL/SQL Packageを選択し、パッケージとしてUTL_OPENAI_ASSISTANTS_APIを設定します。プロシージャまたはファンクション名はRETRIEVE_ASSISTANTです。
サーバー側の条件のタイプにアイテムはNULLではないを選択し、アイテムとしてP3_IDを選択します。
パッケージUTL_OPENAI_ASSISTANTS_APIに実装したファンクションは、ファンクションの結果としてID値を返すようにしています。この値は、パラメータにP3_ASSISTANT_IDとして含まれています。そのため、出力を無視します。
オブジェクトAssistantの主キーとなる属性はassistant_idですが、仮に作成した表では主キーとなる列はすべてIDになっています。そのため、主キーに対応するパラメータ(Assistantではp_assistant_id)に、手動で主キーとなるページ・アイテム(今回の例ではP3_ID)を割り当てます。
また、デバッグ用に出力パラメータとしてp_responseを定義しています。APEXのプロセスから呼び出す際は、出力を無視します。
以上でフォームにデータを読み込むプロセスの置き換えができました。
左ペインでプロセス・ビューを開き、データの挿入、更新、削除を行なうプロセスを置き換えます。
最初にプロセスを削除します。
ボタンCREATEをクリックしたときに実行するプロセスを作成します。呼び出されるファンクションはCREATE_ASSISTANTです。
CREATEの場合は、ファンクションの結果が主キーの値なので、値のアイテムにP3_IDを割り当てます。
同様の手順で、プロセスModify assistantおよびDelete assistantを作成すると、オブジェクトAssistantの操作の実装は完了です。
Assistantの一覧を取得するRESTデータ・ソースを作成します。1つ以上のAssistantを作成した後に作業を行います。データがないとデータ・プロファイルは自動的に生成されません。
共有コンポーネントのRESTデータ・ソースを開きます。
RESTデータ・ソースの作成は最初からを選びます。
次に進みます。
RESTデータ・ソース・タイプとして簡易HTTPを選択します。名前はList assistantsとします。
URLエンドポイントはOpenAIのAPI Referenceより、以下を指定します。
https://api.openai.com/v1/assistants
List messagesのようにパスに変数が含まれる場合は、以下のように{thread_id}といった記述を:thread_idに置き換えます。
https://api.openai.com/v1/threads/{thread_id}/messages
以下に置き換えて設定します。
https://api.openai.com/v1/threads/:thread_id/messages
このようにURLに含まれるコロンで始まる名前は、URLパラメータとして認識されます。データ・プロファイルを自動生成するために、1行はデータが返される値を設定します。
リモート・サーバーやサービスURLパスの設定を確認し、次へ進みます。
Assistants APIのページングの仕様が不明だったため、ページ区切りタイプとしてページ区切りなしを選択しています。
次へ進みます。
認証が必要ですをオンにして、OpenAIのAPIを呼び出すために使用するWeb資格証明を設定します。
Assistants APIを呼び出すためには、特別なHTTPヘッダーを設定する必要があります。そのため、ここでは検出を実行できません。RESTソースの手動作成をクリックします。
RESTデータ・ソースが作成されます。編集画面を開きます。
パラメータのセクションより、パラメータの作成をクリックします。
パラメータのタイプとしてHTTPヘッダーを選択し、名前にOpenAI-Betaを指定します。デフォルト値はassistants=v1です。静的はオンにします。これでREST API呼び出し時にHTTPヘッダーとして以下が追加されます。
OpenAI-Beta: assistants=v1
同様にHTTPヘッダーとしてContent-Type: application/jsonも追加します。
Assistants APIのList操作の行セレクタはdataになります。行セレクタにdataを指定し、データ・プロファイルの再検出をクリックします。
List操作で返されるレスポンスにデータが含まれていれば、データ・プロファイルとして含まれる属性(列)が自動的に生成されます。
データ・プロファイルの置換をクリックします。
以上でRESTデータ・ソースの作成は完了です。変更の適用をクリックし、RESTデータ・ソースの編集画面を閉じます。
RESTデータ・ソースが作成されたら、対応する対話モード・レポートのソースの位置をRESTソースに変更し、RESTソースを作成したRESTデータ・ソースに変更します。
データ・ソースの設定を変更すると、対話モード・レポートにOpenAI側に作成されているオブジェクトが一覧されます。
以上が基本的な実装手順です。
オブジェクトMessageの場合のように、List messages APIで一覧を取得する際にthread_idが必要な場合は、レポートのページにページ・アイテム(この例ではP8_THREAD_ID)を作成し、それをパラメータに割り当てます。
Threadを一覧するページから、Threadを選択してMessagesのページを開くように、対話モード・レポートの列にリンクを設定します。
オブジェクトrunのように、レポートから詳細画面を開く際に主キーの値(runの場合はrun_id)だけでなく、別のIDが必要な場合があります(runの場合はthread_id)。
デフォルトでは主キーの列だけが設定されているため、アイテムの設定にページ・アイテムと値のペアを追加する必要があります。
オブジェクトのRetrieve呼び出しで取り出せる属性の数は、ほとんどの場合、CreateやModifyで設定できる属性の数より多くなっています。Retrieveで取り出せるがCreateやModifyには含まれていない属性は、読み出しのみの属性です。そのため、フォームのページ・アイテムのタイプも表示のみに変更します。
タイプを表示のみにし、設定のページの送信時に送信はオフにします。
このような作業を行なって作成したAPEXアプリケーションのエクスポートを、以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/openai-assistants-sample.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完