For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション

サーバー側の制御

セッションの制御と非公開ツールの実行をサーバー側で行います。

アプリケーションで使用する API を選択します。認証、セッション作成、イベントの仕様は API ごとに異なります。

サーバーからの GPT-Live セッション制御

サーバーで会話イベントの受信、非公開ツールの実行、会話の更新が必要な場合は、アプリケーションサーバーを既存の GPT-Live の WebRTC または SIP セッションに接続します。この 2 つ目の接続を サイドバンド WebSocketと呼びます。両方の接続が 1 つのセッションを共有し、メインの音声は WebRTC または SIP が伝送します。

サイドバンドはイベントとコマンドを伝送します。ツールの実行、認可チェック、ビジネスルールはアプリケーション側で実装します。API キーとツールの認証情報はサーバー側で保持してください。

サイドバンドの必要性の判断

ブラウザアプリケーションでは、字幕とローカル UI の更新に WebRTC データチャネルを使用します。ガードレールのチェック、感情分析、先行的なツール呼び出しなど、文字起こしの処理をサーバーで実行する場合はサイドバンドを使用します。ブラウザの音声伝送には引き続き WebRTC を使いながら、サーバーでイベントを受信し、同じセッションを直接制御できます。例については、文字起こしの断片への対応を参照してください。

バックエンドがすでにメインの WebSocket 接続を管理している場合は、その接続でセッションのイベントを受信し、コマンドを送信できます。

Responses への委任はサイドバンドがなくても機能します。ブラウザはデータチャネルから関数呼び出しイベントを認証済みのバックエンドに転送し、実行を任せることができます。OpenAI がホストするツールは委任先のバックエンドで実行されるため、アプリケーション側にツールの実行機構は不要です。

既存セッションへの接続

  1. バックエンドで制御するセッションの ID を保存します。WebRTC の場合は、POST /v1/live/sessions に対する JSON レスポンスの session.id を使用します。SIP の場合は、まず着信を受け入れ、その Webhook の data.session_id を使用します。この ID は、アプリケーションのユーザーと会話の記録に紐づけて保持してください。

  2. 保存した ID を変更せずに次の URL に埋め込み、サーバーから WebSocket 接続を開きます。セッションを作成または受け入れたプロジェクトの認証情報を使い、Authorization: Bearer $OPENAI_API_KEY で認証します。セッション作成時に必要な接続ヘッダーも同じように含めてください。

    wss://api.openai.com/v1/live/sessions/{session_id}/attach
  3. 接続したソケットでイベントを受信し、コマンドを送信します。セッションはすでに実行中なので、session.start を再送信しないでください。

セッション ID は、内部構造を解釈せずに扱ってください。プレフィックスを保持し、アプリケーションにアクセスが許可されているセッションに対してのみ使用します。ID は Realtime の Location ヘッダーや call_id URL パラメーターではなく、Live の JSON レスポンスから読み取ってください。

イベントの監視とコマンドの送信

タスクイベントまたはコマンド
会話の追跡ユーザーとアシスタントの文字起こしの差分、委任イベント、ネストされた Responses イベントを受信します。
バックエンド構成の更新session.update を使用して、現在の委任モードで変更がサポートされている設定を更新します。フロントエンドのモデルや音声構成など、起動時の設定は固定されたままです。
コンテキストの提供指示には session.instructions.append、発話を伴わないコンテキストには session.thinking.append、発話可能な更新情報には session.commentary.append を使用します。
ツール結果の返却Responses への委任では、response.item.create を送信した後に response.create を送信して、バックエンドの処理を続行します。
マイク入力の制御session.input_audio.mutesession.input_audio.unmute を使用します。入力をミュートしても、アシスタントの出力は停止しません。
セッションの終了切断する前に、session.close を送信し、session.closed を受信します。

コマンドには、メインの接続と同じ検証ルールと委任ルールが適用されます。コンテキストを追加する際、セッション全般のコンテキストには delegation_id: null を使用します。null 以外の ID は、既存のクライアント委任を識別する必要があります。構成、関数の実行、コンテキスト追加の例については、委任とツールを参照してください。

ブラウザのセッションでは、マイク入力とスピーカー出力に、ネゴシエーション済みの WebRTC メディアトラックを引き続き使用します。サイドバンドは会話イベントと制御に使用します。文字起こしイベントやコマンドの確認応答があっても、音声が再生されたことや、ユーザーがその音声を聞いたことの証明にはなりません。

複製された音声の受信

メインの接続がライブメディアを伝送する一方、サイドバンドも接続後の入力音声と出力音声のコピーを受信します。

イベント音声フィールド時刻情報
session.input_audio.appendaudioタイムスタンプはありません。
session.output_audio.deltadeltastart_msend_ms は、セッションのタイムライン上での出力の範囲を示します。

どちらのペイロードも、メインのトランスポートの音声形式にかかわらず、base64 エンコードされた 24 kHz のモノラル生 PCM16LE データです。どちらのイベントにも event_id はありません。複製された入力には、入力ミュートが適用される前に受信した音声が含まれますが、モデルがそのサンプルを処理したことを示すものではありません。複製された出力の範囲には、フレームの欠落による空白が生じる場合があり、通話者が音声を聞いた時刻を示すものでもありません。

これらはサーバーイベントであり、サイドバンドで音声を送信できるという意味ではありません。マイク音声はメインのトランスポートで送信し、追加接続したソケットでは session.input_audio.append を送信しないでください。

アクションごとの担当の一本化

各アクションをブラウザとバックエンドのどちらが処理するかを決めます。両方の接続が関数呼び出しイベントを受信しても、関数は 1 回だけ実行します。コンテキストの更新とバックエンド処理の続行リクエストにも、同じ担当ルールを適用してください。

文字起こしとツールの状態はアプリケーションに保存します。バックエンドで会話を最初から監視する必要がある場合は早期に接続し、接続前に収集した履歴も保持してください。接続すれば過去の文字起こしやツール結果を復元できるとは考えないでください。

サイドバンドを使用するだけでは、セッションのイベントがブラウザから見えなくなるわけではありません。機密性の高いツールの認証情報と認可の判断はバックエンドに留め、会話に必要なコンテキストだけを返してください。

会話へのガードレールの適用

サーバーの接続を使用して会話を監視し、リクエストがアプリケーションのポリシーに沿っているかをチェックして、問題を検出したら介入します。サイドバンドを通じて、サーバーはセッションのイベントとコマンドにアクセスできます。チェックの実行と結果に基づく制御はアプリケーションが担います。サーバーがすでにメインの WebSocket 接続を管理している場合も、同じワークフローを適用できます。

会話と並行したチェックの実行

ガードレールは、文字起こしの断片を受信するたびに処理する仕組みの活用例の 1 つです。同じストリームを使い、チェックと並行して先行的な情報検索を開始したり、UI を更新したりすることもできます。

  1. 文字起こしを監視します。 session.input_transcript.delta の断片を蓄積し、ユーザーのリクエストにジェイルブレイクの試み、機密情報、ポリシー違反がないかをチェックします。session.output_transcript.delta を使用して、アシスタントの発話に根拠のない主張やアプリケーションの範囲外の応答がないかをチェックします。各チェックは、評価対象の文字起こしとアプリケーションのリクエストに紐づけて保持してください。
  2. チェックを並行して実行します。 高速で軽量なモデルを使えば、会話を続けながらリクエストを評価できます。{"triggered": true} など、アプリケーションが処理に利用できる小さな構造化された結果を返します。承認が必要なアクションは、チェックに合格するまでブロックしたままにしてください。タイムアウトやチェックの失敗を承認として扱ってはいけません。
  3. 該当するアクションをブロックします。 チェックで問題を検出したら、アプリケーションの状態にそのリクエストがブロックされたことを記録します。すでにキューに入っている処理も含め、ツールの実行や変更の確定の前に、その状態を確認してください。音声で拒否を伝えるだけでは、ツールの実行を防げません。
  4. 関連する処理を停止します。 バックエンドがキャンセルをサポートしている場合は、アプリケーションが管理するジョブをキャンセルし、ブロック済みのリクエストや新しいリクエストに置き換えられたリクエストから遅れて届いた結果を破棄します。Responses への委任では、該当するカスタム関数の実行を停止し、ブロックした処理を続行するための response.create を送信しないでください。これによって、ホスト側ですでに実行中のレスポンスがキャンセルされたり、フロントエンドの発話が停止したりするわけではありません。
  5. 判断を記録し、会話を軌道修正します。 該当するリクエストと委任の ID とともに判断をログに記録し、修正指示を送信します。guardrail.triggered のようなイベント名は、アプリケーションのテレメトリに属するものであり、GPT-Live API のイベントではありません。

断片の収集については文字起こしの差分を、バックエンドの結果を現在のタスクに沿ったものに保つ方法については委任とツールを参照してください。

会話の軌道修正

ガードレールに沿って会話を制御するには、session.instructions.append を使用します。進行中の発話を中断し、新しい指示を適用できます。たとえば、アプリケーションがリクエストをブロックした後に、次の内容を送信します。

export function sendUpdate(connection) {
  connection.send({
    type: "session.instructions.append",
    event_id: "guardrail_block_17",
    delegation_id: null,
    content:
      "Stop speaking immediately. Do not continue or act on the last request. Refuse briefly, then wait.",
  });
}

指示には、アプリケーション側で作成した内容を使用してください。信頼できないユーザーテキストを指示としてコピーしないでください。このセッション全体に対する修正には delegation_id: null を使用し、content は 500 トークン以内に収めてください。

client_event_id を使って、session.instructions.appended を送信したコマンドと対応付けます。確認応答は、コンテキストの挿入が完了したと推定される時点より後に届きますが、アシスタントの発話やキュー内の音声の再生が停止したことを保証するものではありません。修正指示を送っても、ユーザーがすでに聞いた音声を取り消すことはできません。

特定の文言を読み上げる開示にも、指示を使用します。例と再生時の考慮事項については、開示事項の読み上げを参照してください。

必要に応じた再生制御

まず、修正指示とアクションのブロックをテストします。アプリケーションでモデルの音声もブロックする必要がある場合は、クライアントまたはメディアリレーで出力を制御します。出力を一時的にミュートするか破棄し、ローカルのキュー内の音声を破棄してから修正指示を送信し、アプリケーションの復旧ポリシーに従って再生を再開します。再開する前に、古い音声を消去してください。サイドバンドだけではメディア経路を制御できません。また、指示の確認応答は、再生を再開してよいという合図ではありません。

session.input_audio.mute は、発信者のマイク入力を制御します。モデルの出力をミュートしたり、委任した処理をキャンセルしたりするものではありません。

GPT-Live は、発話しながら文字起こしの断片をストリーミングします。ユーザーが音声を聞く前にチェックを完了する必要がある場合、アプリケーション側で音声をバッファリングし、承認してから再生する必要があります。その分、遅延が増えます。また、音声の再生を抑止すると、モデルの会話コンテキストがユーザーの聞いた内容より先に進んでしまう場合があるため、会話がどのように再開されるかをテストしてください。

介入のテスト

許可されるリクエストとブロックされるリクエスト、誤検知、チェックの遅延や失敗、発話中の介入の発動、ツール実行中の介入の発動、キャンセルした処理から遅れて届く結果をテストします。アクションのブロック、アプリケーションの状態、修正指示に基づく発話、実際の再生をそれぞれ個別に検証してください。出力を制御する場合は、キュー内の音声と復旧もテストに含めます。タスクの成功と音声での応答時間を比較するには、音声エージェント評価の Cookbookを使用してください。

適切な終了処理

バックエンドがツールの実行や最終的な使用量の収集を担っている間は、イベントの受信を続けます。session.close を送信する前に session.closed のハンドラーを登録し、保留中の処理がすべて完了するまで WebRTC 接続、データチャネル、サイドバンドを開いたままにしてください。クリーンアップの前に、セッションの最終的な使用量と、Responses イベントで受信したバックエンドの使用量をすべて保存します。最後のイベントが届く前に接続が失敗した場合は、終了処理を未完了として記録してください。終了の手順については、セッションの管理を参照してください。