전송 방식
기본 전송 계층
섹션 제목: “기본 전송 계층”WebRTC 연결
섹션 제목: “WebRTC 연결”기본 전송 계층은 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 });}WebSocket 연결
섹션 제목: “WebSocket 연결”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 오디오 바이트를 처리하려면 임의의 녹음/재생 라이브러리를 사용하세요.
SIP 연결
섹션 제목: “SIP 연결”OpenAIRealtimeSIP 전송을 사용하여 Twilio 같은 공급자에서 오는 SIP 통화를 브리지하세요. 이 전송은 통신사에서 발생하는 SIP 이벤트와 Realtime 세션을 동기화 상태로 유지합니다.
OpenAIRealtimeSIP.buildInitialConfig()로 초기 세션 구성을 생성하여 수신 전화를 수락합니다. 이렇게 하면 SIP 초대와 Realtime 세션이 동일한 기본값을 공유합니다.OpenAIRealtimeSIP전송을 사용하는RealtimeSession을 연결하고, 공급자 웹훅에서 발급된callId로 연결합니다.- 세션 이벤트를 수신하여 통화 분석, 전사, 에스컬레이션 로직을 구동합니다.
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) 참고 사항
섹션 제목: “Cloudflare Workers (workerd) 참고 사항”Cloudflare Workers 및 기타 workerd 런타임은 전역 WebSocket 생성자를 사용해 아웃바운드 WebSocket 을 열 수 없습니다. 확장 패키지의 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,});사용자 정의 전송 메커니즘 구축
섹션 제목: “사용자 정의 전송 메커니즘 구축”다른 음성 간 API 를 사용하거나 자체 전송 메커니즘이 필요한 경우, RealtimeTransportLayer 인터페이스를 구현하고 RealtimeTransportEventTypes 이벤트를 발생시켜 직접 만들 수 있습니다.
Realtime API 를 더 직접적으로 상호작용
섹션 제목: “Realtime API 를 더 직접적으로 상호작용”OpenAI Realtime API 를 사용하면서도 더 직접적으로 접근하고 싶다면 두 가지 옵션이 있습니다:
옵션 1 - 전송 계층에 접근
섹션 제목: “옵션 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 responsesession.transport.sendEvent({ type: 'response.create', // ...});옵션 2 — 전송 계층만 사용
섹션 제목: “옵션 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 WebSocketsclient.on('audio', (newAudio) => {});
client.sendAudio(audioBuffer);