2025年3月25日火曜日

OpenAI Responses APIをOracle APEXのアプリケーションから呼び出す

新たにOpenAIから提供されたResponses APIを、Oracle APEXのアプリケーションから(正確にいうとOracle Databaseから)呼び出してみます。OpenAIからは2025年3月11日のニュース「エージェント開発のための新たなツール」にて、Responses APIについて紹介されています。

簡単なAPEXアプリケーションを作成し、Responses APIの組み込みツールのWeb検索previous_response_idを指定した会話の継続、およびReasoningモデルの呼び出しを確認してみます。

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


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

機能はすべてホーム・ページに実装しています。

モデルを選択するページ・アイテムとしてP1_MODELを作成しています。タイプ選択リストです。


選択リストの戻り値を、APIリクエストのパラメータmodelに与えています。


会話を継続するためのパラメータprevious_response_idとして与えるIDを保存するページ・アイテムとしてP1_RESPONSE_IDを作成しています。Responses APIを呼び出した後に、レスポンスに含まれるidを取り出しP1_RESPONSE_IDに設定します。

OpenAIのAPI Referenceによると、"Even when using previous_response_id, all previous input tokens for responses in the chain are billed as input tokens in the API.”とのことなので、input配列にメッセージ履歴を含めるのと、費用面では変わらないようです。


パラメータinstructionsとして指定する文字列をページ・アイテムP1_INSTRUCTIONSに指定します。実際にはinstructionsの代わりに、roledeveloperとしたcontentとしてinput配列に含めています。

指定がなければAPIリクエストには含めません。


ユーザーによるプロンプトをページ・アイテムP1_INPUTに入力します。タイプテキスト領域です。roleusercontentになります。


ボタンSUBMITをクリックすると、Responses APIを呼び出します。


ボタンSUBMITをクリックしたときに、以下のPL/SQLプロシージャOPENAI_RESPONSES_APIが実行されるようにします。


識別タイプとしてAPIの呼出しを選択し、設定タイプPL/SQLプロシージャまたはファンクションを選択し、プロシージャまたはファンクションOPENAI_RESPONSES_APIとします。


ボタンCLEARをクリックすると、タイプセッション・ステートのクリアであるプロセスを呼び出します。


APIレスポンスからはマークダウンが返されることを想定しています。レスポンスを表示するページ・アイテムP1_OUTPUT_TEXTタイプMarkdownエディタ読取り専用常時を設定します。


JSON配列として返されるannotationsクラシック・レポートに表示します。annotations自体は非表示のページ・アイテムP1_ANNOTATIONSに設定します。

ソースのSQL問合せに以下を記述します。
select j.type, j.title, j.url, j.start_index, j.end_index
from json_table(:P1_ANNOTATIONS, '$[*]'
    columns
    (
        type        varchar2(20)  path '$.type',
        title       varchar2(400) path '$.title',
        url         varchar2(200) path '$.url',
        start_index number        path '$.start_index',
        end_index   number        path '$.end_index'
    )
) j
サーバー側の条件を設定し、annotationsが返されているときだけクラシック・レポートを表示するようにします。
declare
    l_array json_array_t;
begin
    if :P1_ANNOTATIONS is not null then
        l_array := json_array_t(:P1_ANNOTATIONS);
        if l_array.get_size() > 0 then
            return true;
        end if;
    end if;
    return false;
end;

usageはJSONをそのままページ・アイテムP1_USAGEに表示します。


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

作成したAPEXアプリケーションを使って、OpenAIのResponses APIを呼び出してみます。

最初にモデルgpt-4o-miniを選択し、inputとして以下を入力します。

「これから開かれる大阪万博の期間を教えて。」

toolsとして組み込みのweb_search_previewを渡しているため、引用先も含めた回答が得られています。APIレスポンスに含まれるidがResponse Idに設定されます。


続けて以下を問合せます。Response Idが指定されているため、大阪万博に関する会話が継続します。

「日本からの展示にはどのようなものがありますか?」


会話を継続します。今度はinstructionsに「英語で答えてください。」を指定した上で、以下を問い合わせます。

「海外からのパビリオンではどのようなものがありますか?」

回答が日本語になったり、引用が無かったりしました。スイスとドイツは確認したところ、情報としては正しそうです。



モデルとしてo3-miniを選択し、以下を問い合わせました。

「万国博覧会の意義を教えて。」


Responses APIがChat Completions APIのように他の実装(vLLM、Ollamaやllama.cppといったところ)で採用されるかどうかは分かりませんが、Assistants APIよりは採用するハードルは低そうです。

とりあえず、previous_response_idの指定だけで会話を継続できるのは、大変便利です。

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

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