コンテンツにスキップ

リアルタイムトランスポート

既定のトランスポートレイヤー

Section titled “既定のトランスポートレイヤー”

既定のトランスポートレイヤーは WebRTC を使用します。音声はマイクから録音され、自動で再生されます。

独自のメディアストリームやオーディオ要素を使用するには、セッション作成時に OpenAIRealtimeWebRTC インスタンスを指定します。

import { RealtimeAgent, RealtimeSession, OpenAIRealtimeWebRTC } from '@openai/agents/realtime';
const agent = new RealtimeAgent({
name: 'Greeter',
instructions: 'Greet the user with cheer and answer questions.',
});
async function main() {
const transport = new OpenAIRealtimeWebRTC({
mediaStream: await navigator.mediaDevices.getUserMedia({ audio: true }),
audioElement: document.createElement('audio'),
});
const customSession = new RealtimeSession(agent, { transport });
}

WebRTC の代わりに WebSocket 接続を使用するには、セッション作成時に transport: 'websocket' または OpenAIRealtimeWebSocket のインスタンスを渡します。これは サーバー 側ユースケース、例えば Twilio で電話エージェントを構築する場合に適しています。

import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime';
const agent = new RealtimeAgent({
name: 'Greeter',
instructions: 'Greet the user with cheer and answer questions.',
});
const myRecordedArrayBuffer = new ArrayBuffer(0);
const wsSession = new RealtimeSession(agent, {
transport: 'websocket',
model: 'gpt-realtime',
});
await wsSession.connect({ apiKey: process.env.OPENAI_API_KEY! });
wsSession.on('audio', (event) => {
// event.data is a chunk of PCM16 audio
});
wsSession.sendAudio(myRecordedArrayBuffer);

任意の録音/再生ライブラリを使用して、元の PCM16 オーディオバイトを処理してください。

OpenAIRealtimeSIP トランスポートを使用して、Twilio などのプロバイダーからの SIP 通話をブリッジします。このトランスポートは、通信事業者が発行する SIP イベントと Realtime セッションを同期した状態に保ちます。

  1. OpenAIRealtimeSIP.buildInitialConfig() で初期セッション設定を生成し、着信を受け付けます。これにより、SIP 招待と Realtime セッションが同一のデフォルトを共有します
  2. OpenAIRealtimeSIP トランスポートを使用する RealtimeSession をアタッチし、プロバイダーの Webhook によって発行された callId で接続します
  3. セッションイベントをリッスンして、通話分析、文字起こし、またはエスカレーションロジックを駆動します
import OpenAI from 'openai';
import {
OpenAIRealtimeSIP,
RealtimeAgent,
RealtimeSession,
type RealtimeSessionOptions,
} from '@openai/agents/realtime';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY!,
webhookSecret: process.env.OPENAI_WEBHOOK_SECRET!,
});
const agent = new RealtimeAgent({
name: 'Receptionist',
instructions:
'Welcome the caller, answer scheduling questions, and hand off if the caller requests a human.',
});
const sessionOptions: Partial<RealtimeSessionOptions> = {
model: 'gpt-realtime',
config: {
audio: {
input: {
turnDetection: { type: 'semantic_vad', interruptResponse: true },
},
},
},
};
export async function acceptIncomingCall(callId: string): Promise<void> {
const initialConfig = await OpenAIRealtimeSIP.buildInitialConfig(
agent,
sessionOptions,
);
await openai.realtime.calls.accept(callId, initialConfig);
}
export async function attachRealtimeSession(
callId: string,
): Promise<RealtimeSession> {
const session = new RealtimeSession(agent, {
transport: new OpenAIRealtimeSIP(),
...sessionOptions,
});
session.on('history_added', (item) => {
console.log('Realtime update:', item.type);
});
await session.connect({
apiKey: process.env.OPENAI_API_KEY!,
callId,
});
return session;
}

Cloudflare Workers(workerd)に関する注意

Section titled “Cloudflare Workers(workerd)に関する注意”

Cloudflare Workers および他の workerd ランタイムは、グローバルの WebSocket コンストラクタを使用してアウトバウンド WebSockets を開くことができません。拡張機能パッケージの Cloudflare トランスポートを使用してください。これは内部で fetch() ベースのアップグレードを実行します。

import { CloudflareRealtimeTransportLayer } from '@openai/agents-extensions';
import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime';
const agent = new RealtimeAgent({
name: 'My Agent',
});
// Create a transport that connects to OpenAI Realtime via Cloudflare/workerd's fetch-based upgrade.
const cfTransport = new CloudflareRealtimeTransportLayer({
url: 'wss://api.openai.com/v1/realtime?model=gpt-realtime',
});
const session = new RealtimeSession(agent, {
// Set your own transport.
transport: cfTransport,
});

独自のトランスポート機構の構築

Section titled “独自のトランスポート機構の構築”

別の音声対音声 API を使用する場合や、独自のカスタムトランスポート機構を持つ場合は、RealtimeTransportLayer インターフェースを実装し、RealtimeTransportEventTypes イベントを発行して独自に作成できます。

Realtime API とのより直接的な連携

Section titled “Realtime API とのより直接的な連携”

OpenAI Realtime API を使用しつつ、Realtime API へのより直接的なアクセスが必要な場合は、次の 2 つの方法があります。

オプション 1 - トランスポートレイヤーへのアクセス

Section titled “オプション 1 - トランスポートレイヤーへのアクセス”

RealtimeSession のすべての機能の利点を得つつ、session.transport を通じてトランスポートレイヤーにアクセスできます。

トランスポートレイヤーは受信したすべてのイベントを * イベントの下で発行し、sendEvent() メソッドを使用して元のイベントを送信できます。

import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime';
const agent = new RealtimeAgent({
name: 'Greeter',
instructions: 'Greet the user with cheer and answer questions.',
});
const session = new RealtimeSession(agent, {
model: 'gpt-realtime',
});
session.transport.on('*', (event) => {
// JSON parsed version of the event received on the connection
});
// Send any valid event as JSON. For example triggering a new response
session.transport.sendEvent({
type: 'response.create',
// ...
});

オプション 2 — トランスポートレイヤーのみの使用

Section titled “オプション 2 — トランスポートレイヤーのみの使用”

自動ツール実行やガードレールなどが不要な場合は、接続と割り込みのみを管理する「薄い」クライアントとしてトランスポートレイヤーを使用できます。

import { OpenAIRealtimeWebRTC } from '@openai/agents/realtime';
const client = new OpenAIRealtimeWebRTC();
const audioBuffer = new ArrayBuffer(0);
await client.connect({
apiKey: '<api key>',
model: 'gpt-4o-mini-realtime-preview',
initialSessionConfig: {
instructions: 'Speak like a pirate',
voice: 'ash',
modalities: ['text', 'audio'],
inputAudioFormat: 'pcm16',
outputAudioFormat: 'pcm16',
},
});
// optionally for WebSockets
client.on('audio', (newAudio) => {});
client.sendAudio(audioBuffer);