2025年1月14日火曜日

OpenAIのRealtime APIをWebRTCで呼び出す

OpenAIのRealtime APIを、Oracle APEXのアプリケーションからWebRTCを使って呼び出してみます。参照するOpenAIのドキュメントは以下です。

Realtime API with WebRTC

WebRTCによるOpenAI Realtime APIの呼び出しは、すべてWebブラウザで動作するJavaScriptによって実装します。上記のOpenAIのドキュメントに記載されているコードを、ほぼそのまま流用します。WebRTCでRealtime APIを呼び出すには、OpenAIのサーバーよりephemeral token(一時トークン)を取得し、それをAPIキーとして使用します。この一時トークンの取得については、Oracle APEXが動作するデータベース・サーバーで実行します。

作成したAPEXアプリケーションは以下のように動作します。GIF動画なので音声が含まれていないため動作が分かりませんが、ボタンStartを押してConnection Stateopenになってから「OpenAIの創業者について教えてください。」と聞いています。Realtime APIのレスポンスに音声のトランスクリプトが含まれるため、それを取り出してページ・アイテムに設定しています。同時にWebブラウザでは、トランスクリプトの読み上げが行われています。Realtime APIから返された次の文章が読み上げられています。

OpenAIは、2015年に設立されました。創業者の一人には、イーロン・マスクやサム・アルトマンなどがいます。彼らは、人工知能の安全な発展と普及を目指して活動を始めました。設立当初は、営利目的ではなく、オープンソースでのAI研究を重視していました。


以下より実装について紹介します。

OpenAIのAPIサーバーより一時キーを取得するに当たって、OpenAIのAPIを呼び出します。このAPI呼び出しの認証には、OpenAIの(一時キーではない)APIキーを指定します。このAPIキーをOracle APEXのWeb資格証明として登録します。

Web資格証明静的IDOPENAI_API_KEYとしています。認証タイプHTTPヘッダー資格証明名はHTTPヘッダー名であるAuthenticationを設定します。資格証明シークレットBearerで始めて空白で区切り、skで始まるOpenAIのAPIキーを設定します。URLに対して有効については、https://api.openai.com/を設定します。


空のAPEXアプリケーションを作成し、デフォルトで作成されるホーム・ページにWebRTCによるOpenAI Realtime APIの呼び出しを実装します。

APEXアプリケーションの名前OpenAI WebRTCとします。

WebRTCの呼び出しを含んだJavaScriptのコードは、すべて静的アプリケーション・ファイルjs/app.jsに記述します。ページ・プロパティJavaScriptファイルURLとして、以下を設定します。

[module,defer]#APP_FILES#js/app#MIN#.js


一時キーの取得は、Ajaxコールバックとして実装します。プロセスの名前GET_EPHEMERAL_TOKENとして、ソースPL/SQLコードに以下を記述します。


一時キーはレスポンスであるJSONドキュメントのclient_secret.valueとして返されます。


ホーム・ページにはAjaxコールバックGET_EPHEMERAL_TOKENの呼び出しとレスポンスを確認するため、ボタンGET_EPHEMERAL_TOKENと、そのボタンをクリックしたときに実行される動的アクションを定義しています。このボタンはあくまでデバッグ用で、WebRTCでのRealtime API呼び出しには使用されません。


WebRTCによる会話を開始するボタンSTARTと、終了するボタンSTOPを作成します。最初に静的コンテンツのリージョンを作成し、静的IDとしてCONTROLSを割り当てます。外観テンプレートとして、Buttons Containerを選択します。


作成した静的コンテンツのリージョンにボタンSTARTを作成します。動作アクションとして動的アクションで定義を選択し、カスタム属性としてdata-action="START"を設定します。この設定により、ボタンをクリックするとAPEXアクションとして定義された"START"が呼び出されます。


同様にボタンSTOPを作成します。詳細カスタム属性としてdata-action="STOP"を設定します。ボタンSTARTの右隣に配置するため、レイアウト新規行の開始オフにします。


静的アプリケーション・ファイルjs/app.jsの内容は以下になります。ボタンSTARTをクリックするとファンクションinitが呼び出されます。

OpenAIのドキュメントにあるサンプルに対して、以下のコードを追加しています。
  • 一時キーを取得するために、apex.server.processを使ってAjaxコールバックGET_EPHEMERAL_TOKENを呼び出しています。
  • データ・チャネルの状態をページ・アイテムP1_CONNECTION_STATEに表示しています。
  • OpenAI Realtime APIの音声応答のトランスクリプトを取り出して、ページ・アイテムP1_RESPONSEに表示しています。
  • WebRTCによる会話の開始と終了を、APEXアクションのSTARTとSTOPとして定義しています。


以上でアプリケーションは完成です。

Realtime APIの呼び出しは、デバッグしているとクレジットがどんどん減るため、あまりデバッグできていません。

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

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