GPT-Live が音声会話を担当し、バックエンドがタスクの推論とツールを担当します。アプリケーションのロジック、ツールの実装、権限、永続化する状態は維持します。移行では、これらの機能を新しい音声インターフェースに接続します。
このガイドでは、空き状況を調べ、ユーザーに予約枠の確認を求めてから予約するアシスタントを例に説明します。はじめにの手順で接続したセッションを用意し、比較用に既存のアプリケーションでの代表的な会話を保存しておきます。
移行前の準備
移行後もアプリケーションが満たすべき要件を記録します。
- ツールとビジネスルール:既存のプロンプト、ツール、ワークフローを、各アクションの実行条件とともに一覧にします。
- 入力の種類:音声、入力されたテキスト、画像がアプリケーションのどこから入り、どのバックエンドで必要になるかを特定します。画像と視覚的なコンテキストの追加を参照してください。
- 音声に依存する判断:文字起こしの内容だけでなく、元の音を必要とする判断を特定します。音声に依存する判断の維持を参照してください。
- 発話と再生:発話を開始してよいタイミング、停止しなければならないタイミング、音声の再生前に完了すべきチェックを明確にします。
- 権限とガードレール:認可、確認、入出力のチェックと、アプリケーション内でそれらを適用する箇所を一覧にします。ガードレールの調整を参照してください。
- 永続化する状態:切断や新しいセッションの開始をまたいでアプリケーションが保持すべき記録、タスクの進捗、保留中のアクションを特定します。
- 比較基準となる会話:現在のアプリケーションでの代表的な会話と、その開始時の状態、期待されるツールの動作、最終的なアプリケーションの状態、音声応答を保存します。
セッションのセットアップにははじめにを、比較計画の作成には音声エージェント評価の Cookbookを活用してください。
委任モードの選択
既存のアーキテクチャをもとに検討すると、選びやすくなります。
- Responses への委任は、モデルが関数を選び、アプリケーションが実行する Realtime アプリに適しています。ホスト型の Responses モデルがタスクの推論とツールの選択を引き継ぎます。
- クライアント委任は、既存のテキストエージェントやオーケストレーターに適しています。アプリケーションがコンテキストを提供し、そのバックエンドを呼び出して、結果を GPT-Live に返します。
どちらの移行方法でも、どちらのモードも使用できます。たとえば、すでに独立したバックエンドエージェントを持つ Realtime アプリでは、クライアント委任によってそのエージェントを引き続き使用できます。また、バックエンドのコンテキストや実行、結果が GPT-Live に届く前のレビューを、どこまで制御する必要があるかも検討してください。詳しい比較は委任モードの選択を参照してください。
移行方法の選択
現在のアプリケーションに合った移行方法を選択してください。
Realtime API からの移行
まずGPT-Live プロンプトガイドを参照してください。既存のプロンプトを丸ごと session.instructions にコピーするのではなく、音声モデル用とバックエンド用に分けます。会話のスタイルと委任に関する指針は音声用プロンプトに残し、詳細なワークフローとツールの使用手順はバックエンドに移します。
移行前: Realtime モデルが発話を担当し、check_availability や book_appointment などの関数を選択します。アプリケーションが関数を実行し、その結果を返します。
移行後: GPT-Live が発話を担当し、タスクの処理を委任します。バックエンドが同じ関数を選択し、アプリケーションが引き続き検証と実行を担当します。ここで説明する手順では Responses への委任を使用します。外部エージェントを引き続き使用する場合は、代わりにクライアントアダプターを使用してください。
Responses への委任の仕組み
delegation.responses でバックエンドのモデル、指示、ツールを構成します。GPT-Live がリクエストにバックエンドでの処理が必要だと判断すると、Live サービスがその Responses モデルを呼び出し、関連する会話のコンテキストを渡します。バックエンドはタスクについて推論し、ツールを選択します。カスタム関数の実行、権限の適用、結果の返却は、引き続きアプリケーションが担当します。
予約アシスタントでは、次のように進みます。
- ユーザーが金曜日に予約できる時間帯を尋ねると、GPT-Live がそのリクエストを委任します。
- Responses バックエンドが
check_availabilityをリクエストします。 - アプリケーションが関数を実行して結果を返し、バックエンドの応答を継続させます。
- GPT-Live はバックエンドの回答をもとに、空いている予約枠についてユーザーと会話します。
GPT-Live はバックエンドで処理が実行されている間も会話を続けられます。その処理が完了しても、アシスタントの発話が終わったとは限りません。構成とイベントフロー全体については、委任とツールを参照してください。
音声に依存する判断の維持
既存のツールに関する判断が、留守番電話のビープ音や録音された応答メッセージの抑揚など、音響的な手がかりに依存していないか確認します。GPT-Live は入力音声を聞き取りますが、その音声フロントエンドは通常の構造化された関数呼び出しを発行するのではなく、処理を委任します。クライアントモードでは、session.delegation.created に含まれるのはメタデータとタイミング情報であり、生の音声、タスクのテキスト、解析済みのツール引数は含まれません。委任先のバックエンドに波形が自動的に渡されることもありません。
留守番電話を検出する場合は、入力音声を音声対応の検出器に明示的に送ります。評価候補となるアプリケーション管理の構成の一つは、通話の一部で GPT-Live と並行して別の Realtime セッションを実行するものです。
- 通話の入力音声のコピーを両方のセッションに送信します。
- 検出器から、構造化された関数呼び出しで分類結果を報告させます。各結果をスキーマと照合し、古い結果は拒否し、根拠が不十分な場合は不明の状態を維持します。後から得られた根拠に応じて判断を修正できるようにします。
- 関連する信頼済みのコンテキストを GPT-Live に送り、出力音声の再生にアプリケーションのポリシーを適用します。
人か機械かの分類と、録音の準備ができているかどうかの判断は分けて扱います。留守番電話だと認識できても、応答メッセージとビープ音が終わったことや、録音を開始できることが確認できたわけではありません。分類器の結果やコンテキストの受領確認も、音声の再生許可を意味しません。ガードレールの調整と再生制御を活用し、アプリケーションが制御する音声経路でその判断を確実に適用してください。
短い「もしもし」に続いて留守番電話の応答メッセージが流れる場合、通話スクリーニングの案内が流れる場合、留守番電話の動作中に人が電話に出る場合をテストします。通話が終わる前に検出器を停止する場合は、停止後に人が電話に出るケースもテストしてください。これらのテスト結果と検出器による追加コストをもとに、停止するタイミングを決めます。最初に人と分類されたというだけでは、それ以降の検出が不要だとは判断できません。
接続と音声ライフサイクルの調整
Realtime のセッションセットアップをGPT-Live の接続手順に置き換えます。使用するトランスポートの起動手順と音声形式を再確認してください。WebRTC はメディアトラックで音声を、データチャネルで JSON イベントを伝送します。プライマリ WebSocket は JSON イベント内で音声を伝送します。
Realtime アプリケーションでサーバー接続を使って通話を監視したり、ガードレールを適用したりしている場合は、GPT-Live のサイドバンド接続に対応させます。会話のチェックと再生に関する変更については、ガードレールの調整に従ってください。
| 既存の Realtime の動作 | GPT-Live での対応 |
|---|---|
input_audio_buffer.append で WebSocket 音声を送信します。 | session.input_audio.append を送信します。その audio フィールドには、base64 でエンコードされた生の音声が含まれます。 |
response.output_audio.delta の delta フィールドに含まれる音声を再生します。 | session.output_audio.delta の delta フィールドに含まれる音声を順番に再生します。 |
| 手動でターンを制御する場合は、音声をコミットするか、応答を作成してターンを開始します。 | 音声を継続的にストリーミングします。発話のタイミングは GPT-Live が判断するため、手動の音声コミットと音声ターンのトリガーを削除します。 |
response.output_audio.done と response.done で音声生成と応答の完了を追跡します。 | GPT-Live には、各音声応答の終了を示す対応イベントはありません。クライアントで再生状態を追跡します。 |
| 入力の文字起こしイベントからユーザーの字幕を表示します。 | session.input_transcript.delta のテキストをユーザーの字幕に追記します。 |
response.output_audio_transcript.delta からアシスタントの字幕を表示します。 | session.output_transcript.delta のテキストをアシスタントの字幕に追記します。 |
生成と再生: Realtime では、response.output_audio.done が音声生成の終了を、response.done が応答ストリームの終了を示します。これらのイベントは応答が中断された場合や正常に完了しなかった場合にも発生するため、response.done の response.status を確認してください。どちらも、バッファ内の音声の再生が終わったことを示すものではありません。たとえば、サーバー側で生成が完了しても、クライアントには再生すべき音声がまだ 1 秒分残っていることがあります。「発話中」の表示は再生状態に基づいて制御してください。
字幕:入力の文字起こしはユーザーの発話を、出力の文字起こしはアシスタントが生成した発話を表します。入力の文字起こしが有効な場合、Realtime は conversation.item.input_audio_transcription.delta で更新を、conversation.item.input_audio_transcription.completed で最終的な文字起こしを送信します。delta は新しいテキスト断片です。GPT-Live では聞き取りと発話が同時に行われることがあるため、各断片を該当する話者の字幕にそれぞれ独立して追記します。断片はターン全体を表すものでも、再生を確認するものでもありません。表示の実装例については、字幕の表示を参照してください。
GPT-Live では、response.create は委譲された Responses の処理を開始または継続します。音声モデルに発話を許可するものではありません。起動、挨拶、割り込み、セッションの終了については、セッションの管理に従ってください。
会話とバックエンドの指示の分離
会話のスタイルと委譲に関するガイダンスを session.instructions に移します。ビジネスルールとツールの使用に関する指示は delegation.responses.instructions に移します。バックエンドを自分で運用している場合は、これらのルールを既存のプロンプトに残します。
移行前:単一の Realtime プロンプト
Help callers book appointments. Speak briefly. Check availability with the tool,
ask the caller to confirm a slot, then book it. Never claim an unverified booking.移行後:GPT-Live の会話用指示
Help callers book appointments. Keep spoken replies brief. Delegate availability
checks and booking requests. Ask the caller to confirm the proposed slot.
Only announce a booking when the backend reports that it succeeded.移行後:バックエンド用指示
Use the appointment tools to check current availability. Before booking, verify
that the caller confirmed the exact slot and still has permission to book it.
Apply the latest correction. Return verified availability, booking, or failure
status with the date, time, and time zone.ツールを実行する前に、アプリケーション側でユーザーの確認と権限のチェックを必ず実施してください。プロンプトの指示はモデルの動作を導きますが、これらのチェックを強制するものではありません。プロンプトの設計については、音声モデルのプロンプトを参照してください。
関数ハンドラーの調整
check_availability と book_appointment の実装はそのまま使用します。それぞれの定義を Realtime の session.tools または response.tools から delegation.responses.tools に移し、Responses の関数スキーマを使用します。ツール選択の設定は delegation.responses.tool_choice と delegation.responses.parallel_tool_calls に移します。Responses 委譲の設定を参照してください。
関数は引き続き、元の call_id に対応する結果を返します。変更されるのは、ハンドラーが呼び出しを受け取る場所と結果の送信先です。
| 手順 | Realtime API | Responses 委譲を使用する GPT-Live |
|---|---|---|
| 生成が完了した関数呼び出しを受け取ります。 | response.output_item.done を読み取ります。 | response.event のラップを解除し、内部の response.output_item.done を読み取ります。 |
| 操作を特定して実行します。 | アイテムの name、arguments、call_id を読み取り、実行が許可されたハンドラーを実行します。 | そのハンドラーとチェック処理はそのまま使用します。外側の delegation_id とバックエンドのレスポンス ID をアプリケーションに保持します。 |
| 各関数の結果を返します。 | conversation.item.create を送信します。 | response.item.create を送信します。 |
| 必要な結果がすべて揃ったら処理を継続します。 | response.create を送信します。 | response.create を送信してバックエンドの処理を継続します。 |
たとえば、check_availability が確認済みの空き枠を 1 つ返した場合、結果の形式は次のように変わります。これらは接続済みのセッションで送信するメッセージです。call_availability は、実際に受け取った呼び出し ID を表します。
移行前:Realtime の結果
{
"type": "conversation.item.create",
"item": {
"type": "function_call_output",
"call_id": "call_availability",
"output": "{\"available\":true,\"slot_id\":\"slot_friday_14\",\"booked\":false}"
}
}移行後:GPT-Live の結果
export function sendUpdate(connection) {
connection.send({
type: "response.item.create",
event_id: "availability_result_1",
item: {
type: "function_call_output",
call_id: "call_availability",
output: '{"available":true,"slot_id":"slot_friday_14","booked":false}',
},
});
}必要な関数の結果をすべて送信したら、バックエンドの処理を継続します。
export function sendUpdate(connection) {
connection.send({
type: "response.create",
event_id: "continue_availability_1",
});
}移行の初期段階では、parallel_tool_calls を false に設定すると、結果の処理が簡単になります。ライフサイクルの終了時点のスナップショットが output: [] であっても、出力アイテムの完了イベントから呼び出しを収集してください。引数の生成完了イベントだけでは、関数名と call_id は取得できません。収集、出力の送信、エラー処理については、関数の結果を返す手順をすべて実施してください。
コンテキストの保持と訂正の反映
Responses 委譲は、関連する音声会話のコンテキストをバックエンドに提供します。予約状態の正本はアプリケーションで管理してください。これには、選択された枠、ユーザーが確認した枠、権限、実行中の操作、その結果が含まれます。Live の会話履歴はコンパクションされることがあり、予約記録の代わりにはなりません。
木曜日の空き状況を検索している間にユーザーが「やっぱり金曜日にしてください」と言った場合は、タスクのリビジョンを更新し、それまでの予約枠に対するユーザーの確認を無効にします。予約を実行する前に、引数が現在のタスクとユーザーの確認内容に引き続き一致していることをチェックしてください。保留中の関数呼び出しをアプリケーションが拒否する場合は、置き換え済みまたはキャンセル済みという状態を正確に示す結果を返します。その後、必要な出力バッチを完了してから処理を継続してください。予約がすでに成功している場合は、次の操作を行う前に、その結果と変更リクエストを照合し、整合性を確保してください。
文字起こしの断片は、遅れて届いたり、アシスタントの発話と重なったりすることがあります。各 delta を受信したとおりに追加し、start_ms と end_ms を使って表示をまとめてください。これらのタイムスタンプは、確定したターンの境界や単語単位の再生タイムスタンプではありません。意図が不明確な場合は、重要な日付、名前、数値を確認してください。文字起こしとコンテキストの扱いについては、セッションの管理を参照してください。
画像と画面のコンテキスト: Realtime アプリケーションで画像を受け付ける場合は、画像を視覚情報に対応したバックエンドに渡し、関連するテキストを GPT-Live に返します。クライアント委譲と Responses 委譲は、どちらもこのパターンに対応しています。画像と視覚的コンテキストの追加を参照してください。
テキストエージェントまたはチェーン型パイプラインからの移行
移行前:テキストエージェントはテキストのリクエストを受け取り、ツールと保存済みの状態を使用します。チェーン型(カスケード型)の音声パイプラインでは、そのエージェントの前段に音声からテキストへの変換を、後段にテキストから音声への変換を追加します。
移行後: GPT-Live が音声インターフェースを提供し、タスクの処理を既存のエージェントに委譲します。チェーン型パイプラインでは、個別に設けられていた音声からテキストへの変換とテキストから音声への変換の段階を置き換えます。モデル、指示、ツール、ワークフロー、永続的な状態のうち、引き続きタスクに適しているものはバックエンドに残してください。
既存エージェントの接続
セッションのセットアップ時に、delegation を {"type":"client"} に設定します。アプリケーションは次のような通知を受け取ります。
{
"type": "session.delegation.created",
"offset_ms": 1000,
"delegation": {
"id": "item_appointment_1",
"type": "delegation",
"target": "client"
}
}通知に含まれるのはメタデータであり、リクエストのテキスト、ツールの引数、完全な文字起こしではありません。実際の delegation.id は変更せずに保持してください。ロールが付いた最近の文字起こしの断片と、アクティブなタスクや最新の訂正を含む検証済みのアプリケーション状態から、エージェントへの入力を組み立てます。文字起こしに完全な文が現れる前に、委譲の通知が届くこともあります。利用できるコンテキストだけではリクエストを特定できない場合は、追加のコンテキストを集めるか、ユーザーに確認してから操作してください。
テキストアプリケーションでは、ユーザーの最新のメッセージをエージェントに直接渡しているかもしれません。GPT-Live では、そのコンテキストを提供し、簡潔で検証済みの結果を返すアダプターを追加します。
async function handleDelegation(event, app) {
if (
event.type !== "session.delegation.created" ||
event.delegation?.target !== "client"
)
return;
const context = app.readContext();
if (!context) return; // Retain the notice; resolve the request before acting.
const summary = await app.runAgent({
revision: context.revision,
recentConversation: context.recentConversation,
task: context.task,
});
if (app.currentRevision() !== context.revision) return;
app.send({
type: "session.commentary.append",
event_id: crypto.randomUUID(),
delegation_id: event.delegation.id,
content: summary,
});
}このアダプターは、アプリケーションのコールバックを使ってコンテキストを読み取り、エージェントを実行し、現在のタスクのリビジョンを確認します。これらは SDK のメソッドではありません。コンテキスト用のコールバックは、最近の会話と現在のタスクを含む、利用可能なスナップショットを返します。リクエストがまだ不明確な場合は、スナップショットを返しません。エージェント用のコールバックは既存のエージェントを呼び出し、最大 500 トークンの検証済みの要約を返します。JavaScript では、アプリケーションが提供する send コールバックが Live 接続で JSON イベントを送信します。Python では、アダプターが SDK の connection を通じて更新を直接送信します。
コンテキストの準備ができていない場合は、通知を保持し、リクエストを明確にしてからアダプターを再度呼び出します。このアダプターを呼び出す前に、アプリケーションで委譲の処理権を確保し、通知が重複して届いても同じ操作が二重に開始されないようにしてください。認可、ユーザーの確認、操作 ID、再試行の判断はバックエンドで管理します。リビジョンのチェックにより、このアダプターが古い結果を伝えることを防ぎます。バックエンドでも、予約などの副作用を伴う処理の前に、現在のリビジョンをチェックする必要があります。
予約アシスタントでは、コンテキストから希望日、タイムゾーン、以前に提示した枠、ユーザーが確認した枠の有無、最新の訂正を明確に把握できるようにします。空き状況の結果では、枠が空いていることと、まだ予約は行われていないことを伝えてください。予約完了の通知は、予約が成功した後にのみ返します。セットアップと結果の処理の全体的な流れについては、クライアント委譲を参照してください。
更新と訂正の伝達
構造化されたツール出力とワークフローの詳細は、バックエンドに保持します。GPT-Live には、事実に基づく簡潔な更新を返します。
- まだ実行中の検索など、バックグラウンド処理の進捗には
session.thinking.appendを使用します。 - ユーザーに音声で伝えるべき検証済みの結果には、
session.commentary.appendを使用します。 - アプリケーション側で作成した動作に関するガイダンスには、
session.instructions.appendを使用します。
この 3 つはいずれも、最大 500 トークンの単純な文字列を content として受け取り、delegation_id を必須とします。関連する処理には元のクライアント委譲 ID を使用し、セッション全般のコンテキストには null を使用します。追加操作の確認応答は、client_event_id で対応付けてください。受理されたことは、発話や再生が行われたことを意味しません。適切な種類の更新の送信を参照してください。
ユーザーが「やっぱり金曜日にしてください」と言ったら、アクティブなタスクとそのリビジョンを更新し、木曜日に対するユーザーの確認をすべて無効にして、既存のエージェントに訂正後のリクエストを処理させます。保留中の検索をキャンセルするか、変更するか、そのまま完了させるかを判断してください。古い結果は GPT-Live に返す前に破棄します。発話への割り込みによってバックエンドの操作がキャンセルされることはなく、キャンセルをリクエストしただけでは、操作がキャンセルされたことの証明にはなりません。
音声セッションが終了した後も、バックエンドの処理が続くことがあります。その状態をアプリケーションに永続化してください。後で音声によるやり取りを再開する際は、保存済みの関連コンテキストを使って新しいセッションを開始します。セッションの管理を参照してください。
テキストと音声の安全対策の調整
テキストエージェントは、返信を表示する前に生成を完了し、検証できます。チェーン型パイプラインでは、返信全体を検証してからテキストから音声への変換に渡す場合があります。GPT-Live はバックエンドの処理中も発話できるため、ツールの結果やバックエンドの処理の継続を保留しても、すべての発話を止められるわけではありません。
ガードレールの調整に従い、既存のチェックを維持しながら、継続的な発話に対応してください。
テキスト入力は引き続き既存のバックエンドに接続します。テキストで入力された訂正は同じタスクへの更新として扱い、関連する検証済みのコンテキストを音声セッションに送信してください。テキスト入力の受け付けと正確で有用な更新の維持を参照してください。
ガードレールの調整
どちらのアーキテクチャから移行する場合も、既存のアプリケーションの入出力に対する安全対策を維持します。GPT-Live はバックエンドの処理やポリシーチェックの実行中も話し続けられるため、会話とバックエンドが実行するアクションの両方にチェックを適用します。
ブラウザが所有するセッションにサーバーから独立してアクセスする必要がある場合は、サイドバンド WebSocket を使用します。音声の送受信には引き続き WebRTC を使いながら、サーバーで文字起こしを受信し、修正指示を送信できます。サーバーがすでにメインの WebSocket を所有している場合は、そのイベントストリームを使用します。Responses 委譲では、追加のサイドバンドは必要ありません。
- ユーザーとアシスタントの文字起こしイベントを監視し、会話と並行してチェックを実行します。
- 対象のツールや外部アクションの実行をアプリケーションコードでブロックします。キャンセルがサポートされている場合は、アプリケーションが管理する関連処理をキャンセルし、遅れて届いた結果によってブロック済みのリクエストが続行されないようにします。
session.instructions.appendを送信してアシスタントの動作を修正し、その判断をアプリケーションに記録します。
たとえば、電話の相手が予約アシスタントに他人の予約を無断で変更するよう求めた場合は、予約操作が実行される前にブロックします。その後、変更できないことを説明するようアシスタントに指示します。予約記録が変更されていないことと、音声での応答の両方を確認します。口頭で拒否するだけでは、権限に基づく制御は実施できません。
修正指示を送っても、すでに相手が聞いた音声は取り消せません。再生前にチェックを完了する必要がある場合は、アプリケーションが制御する音声経路にバッファリングと承認の仕組みを追加し、それによる遅延の増加を考慮します。全体の流れ、修正指示の例、再生制御については、会話へのガードレールの適用に従ってください。冒頭で必ず伝える文言については、告知の実施を参照してください。
移行の検証
現在のアプリケーションでの代表的な会話を使って、移行後のアシスタントを比較します。シナリオ、バックエンドツール、成功基準を統一し、各シナリオを繰り返して、リグレッションと併せて意図した動作変更も記録します。
- アクションと音声での確認:空き状況を調べ、ユーザーに確認を求め、確認が取れた枠だけを予約します。バックエンドの処理結果、音声での回答、クライアントでの再生をそれぞれ個別に検証します。
- 修正と重複防止:リクエストの処理が完了する前に、木曜日から金曜日に変更します。古い結果を破棄し、再試行によって予約が重複して作成されないことを確認します。
- 権限:権限のないアクションと、確認を取らずに行う予約を試します。アプリケーションのポリシーによって実行がブロックされることを確認します。
- ガードレールによる介入:発話中とツール実行中にチェックを発動させます。修正後の発話、アクションのブロック、遅れて届いた結果の処理、再生の復旧を検証します。チェックに時間がかかる場合や誤検知も含めます。
- 割り込み:アシスタントの発話中や処理中に話しかけます。会話、音声再生、バックエンドのタスク状態をそれぞれ個別に検証します。
- 障害と再接続:ツールエラー、結果の消失、接続の切断をテストします。結果が不明な処理は、再試行する前に実際の状態と照合し、新しいセッションで関連する保存済みコンテキストを復元します。
バックエンドの遅延の削減を参考に、移行後のバックエンドを調整します。音声エージェント評価の Cookbook を使って、有用な音声応答が得られるまでの時間とタスクの成功状況を比較し、コストの最適化を使って使用量とコストを比較します。