コンテンツにスキップ

Twilio 上の音声エージェント

Twilio は、通話の元の音声を WebSocket サーバーへ送信する Media Streams API を提供しています。この仕組みを使用して、音声エージェントの概要を Twilio に接続できます。websocket モードのデフォルトの Realtime Session トランスポートを使用して、Twilio からのイベントを Realtime Session に接続できます。ただし、通話では Web ベースの会話よりも遅延が自然に大きくなるため、適切な音声形式を設定し、独自の割り込みタイミングを調整する必要があります。

セットアップを容易にするため、割り込み処理や音声転送を含む Twilio への接続を処理する専用のトランスポートレイヤーを用意しました。

  1. Twilio アカウントと Twilio 電話番号を用意してください。

  2. Twilio からのリクエストを認証するサーバーをセットアップしてください。

    ローカルで開発している場合は、ローカルサーバーを Twilio からアクセス可能にするため、ngrok や Cloudflare Tunnel などのローカルトンネルを設定する必要があります。サーバーでは、トランスポートの作成または OpenAIへの接続の前に、着信 Webhook と WebSocket アップグレードの両方で X-Twilio-Signature を検証する必要があります。Twilio 公式のリクエストバリデーター、アカウントのプライマリ Auth Token、および設定済みの公開 URL を使用してください。その URL をリクエストの Host ヘッダーや転送ヘッダーから生成しないでください。TwilioRealtimeTransportLayer は、すでに認証済みの WebSocket を受け取ります。アダプターは HTTP リクエストを認証しません。

  3. 拡張機能パッケージをインストールして、Twilio アダプターをインストールします。

    ターミナルウィンドウ
    npm install @openai/agents-extensions
  4. アダプターとモデルをインポートして、RealtimeSession に接続します。

    import { TwilioRealtimeTransportLayer } from '@openai/agents-extensions';
    import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime';
    const agent = new RealtimeAgent({
    name: 'My Agent',
    });
    // Authenticate the HTTP webhook and WebSocket upgrade in your server first.
    // Create a new transport mechanism that will bridge the connection between Twilio and
    // the OpenAI Realtime API.
    const twilioTransport = new TwilioRealtimeTransportLayer({
    twilioWebSocket: websocketConnection,
    });
    const session = new RealtimeSession(agent, {
    // set your own transport
    transport: twilioTransport,
    });
  5. RealtimeSession を Twilio に接続します。

    import type { RealtimeSession } from '@openai/agents/realtime';
    // Connect only after the server has authenticated the Twilio WebSocket upgrade.
    async function connectAuthenticatedSession(
    session: RealtimeSession,
    apiKey: string,
    ) {
    await session.connect({ apiKey });
    }

ツール呼び出し、ガードレールなど、RealtimeSession に期待されるすべてのイベントと動作は、想定どおりに機能します。音声エージェントで RealtimeSession を使用する方法について詳しくは、音声エージェントの概要を参照してください。

  1. 重要なのは速度です。

    Twilio から必要なイベントと音声をすべて受信するために、認証済みの WebSocket 接続が利用可能になったら、すぐに TwilioRealtimeTransportLayer インスタンスを作成し、その直後に session.connect() を呼び出してください。

  2. 元の Twilio イベントにアクセスします。

    Twilio から送信される元のイベントにアクセスするには、RealtimeSession インスタンスで transport_event イベントをリッスンします。Twilio からのすべてのイベントは twilio_message 型となり、元のイベントデータを含む message プロパティを持ちます。

  3. デバッグログを確認します。

    問題が発生し、何が起きているのかについて詳細な情報が必要になることがあります。DEBUG=openai-agents* 環境変数を使用すると、Agents SDKのすべてのデバッグログが表示されます。または、DEBUG=openai-agents:extensions:twilio* を使用して、Twilio アダプターのデバッグログのみを有効にできます。

実行可能な Twilio コード例には、認証済みの Fastify ルートと Realtime Session のセットアップが含まれています。その README では、サーバー側で必要となる OPENAI_API_KEY、TWILIO_AUTH_TOKEN、TWILIO_PUBLIC_BASE_URL の設定について説明しています。公開ベース URL は、パスプレフィックス、クエリ文字列、フラグメントを含まない HTTPS オリジンです。トンネルの公開オリジンが変更された場合は、この設定を更新してください。

このサーバーは、Realtime 接続を開く前に、無効な通話署名とアップグレード署名を拒否します。Twilio Media Stream の URL では wss:// を使用し、クエリパラメーターはサポートされません。カスタムパラメーターについては、Twilio Stream のドキュメントを参照してください。