跳转到内容

传输机制

默认传输层使用 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 });
}

对于更底层的自定义,OpenAIRealtimeWebRTC 也接受 changePeerConnection,它允许你在生成 offer 之前检查或替换新创建的 RTCPeerConnection

在创建会话时传入 transport: 'websocket'OpenAIRealtimeWebSocket 的实例,以使用 WebSocket 连接替代 WebRTC。这非常适合服务器端场景,例如使用 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 音频字节。

对于高级集成,OpenAIRealtimeWebSocket 接受 createWebSocket(),以便你提供自定义的 socket 实现;当该自定义连接器负责将 socket 切换到已连接状态时,可使用 skipOpenEventListeners@openai/agents-extensions 中的 Cloudflare 传输即基于这些钩子实现。

使用 OpenAIRealtimeSIP 传输将来自 Twilio 等提供商的 SIP 呼叫进行桥接。该传输会将 Realtime 会话与电话提供商发出的 SIP 事件保持同步。

  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 构造函数发起出站 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 事件来创建你自己的传输层。

如果你想使用 OpenAI Realtime API,同时对 Realtime API 拥有更直接的访问方式,有两种选择:

如果你仍希望受益于 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',
// ...
});

如果你不需要自动工具执行、护栏等功能,也可以仅使用传输层作为一个“轻量”客户端,它只负责连接管理和中断处理。

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',
outputModalities: ['text', 'audio'],
audio: {
input: {
format: 'pcm16',
},
output: {
format: 'pcm16',
voice: 'ash',
},
},
},
});
// optionally for WebSockets
client.on('audio', (newAudio) => {});
client.sendAudio(audioBuffer);