コンテンツにスキップ

Realtime Agent を Twilio に接続

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

セットアップ体験を向上させるために、割り込み処理や音声転送を含め、Twilio との接続を代行する専用のトランスポートレイヤーを用意しました。

  1. Twilio アカウントと Twilio 電話番号を所有していることを確認します。

  2. Twilio からのイベントを受信できる WebSocket サーバーをセットアップします。

    ローカルで開発している場合は、ngrokCloudflare Tunnel などのローカルトンネルを設定し、ローカルサーバーを Twilio からアクセス可能にする必要があります。TwilioRealtimeTransportLayer を使用して Twilio に接続できます。

  3. 拡張パッケージをインストールして Twilio アダプターを導入します:

    Terminal window
    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',
    });
    // 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 に接続します:

    session.connect({ apiKey: 'your-openai-api-key' });

RealtimeSession から期待されるすべてのイベントや動作(ツール呼び出し、ガードレールなど)がそのまま利用できます。RealtimeSession を音声エージェントで使う方法については 音声エージェントの概要 を参照してください。

  1. スピードが鍵です。

    Twilio から必要なすべてのイベントと音声を受け取るには、WebSocket 接続への参照を取得したらすぐに TwilioRealtimeTransportLayer インスタンスを作成し、直ちに session.connect() を呼び出してください。

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

    Twilio から送信される元イベントにアクセスしたい場合は、RealtimeSession インスタンスの transport_event をリッスンできます。Twilio からの各イベントは twilio_message という type と、生のイベントデータが入った message プロパティを持ちます。

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

    詳細を確認したい場合は、DEBUG=openai-agents* 環境変数を使用すると Agents SDK のすべてのデバッグログを表示できます。あるいは DEBUG=openai-agents:extensions:twilio* を使って Twilio アダプターのログのみに絞ることも可能です。

以下は、Twilio からのリクエストを受け取り RealtimeSession に転送する WebSocket サーバーのエンドツーエンド例です。

Example server using Fastify
import Fastify from 'fastify';
import dotenv from 'dotenv';
import fastifyFormBody from '@fastify/formbody';
import fastifyWs from '@fastify/websocket';
import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime';
import { TwilioRealtimeTransportLayer } from '@openai/agents-extensions';
// Load environment variables from .env file
dotenv.config();
// Retrieve the OpenAI API key from environment variables. You must have OpenAI Realtime API access.
const { OPENAI_API_KEY } = process.env;
if (!OPENAI_API_KEY) {
console.error('Missing OpenAI API key. Please set it in the .env file.');
process.exit(1);
}
const PORT = +(process.env.PORT || 5050);
// Initialize Fastify
const fastify = Fastify();
fastify.register(fastifyFormBody);
fastify.register(fastifyWs);
const agent = new RealtimeAgent({
name: 'Triage Agent',
instructions:
'You are a helpful assistant that starts every conversation with a creative greeting.',
});
// Root Route
fastify.get('/', async (request, reply) => {
reply.send({ message: 'Twilio Media Stream Server is running!' });
});
// Route for Twilio to handle incoming and outgoing calls
// <Say> punctuation to improve text-to-speech translation
fastify.all('/incoming-call', async (request, reply) => {
const twimlResponse = `
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>O.K. you can start talking!</Say>
<Connect>
<Stream url="wss://${request.headers.host}/media-stream" />
</Connect>
</Response>`.trim();
reply.type('text/xml').send(twimlResponse);
});
// WebSocket route for media-stream
fastify.register(async (fastify) => {
fastify.get('/media-stream', { websocket: true }, async (connection) => {
const twilioTransportLayer = new TwilioRealtimeTransportLayer({
twilioWebSocket: connection,
});
const session = new RealtimeSession(agent, {
transport: twilioTransportLayer,
});
await session.connect({
apiKey: OPENAI_API_KEY,
});
console.log('Connected to the OpenAI Realtime API');
});
});
fastify.listen({ port: PORT }, (err) => {
if (err) {
console.error(err);
process.exit(1);
}
console.log(`Server is listening on port ${PORT}`);
});
process.on('SIGINT', () => {
fastify.close();
process.exit(0);
});