即時互動
透過 Realtime WebSocket 處理即時文字、音訊與函式呼叫。
OpenAI Realtime 使用持久連線和雙向事件處理即時文字、音訊與函式呼叫。用戶端傳送工作階段、音訊緩衝區、對話項和回應控制事件,伺服器端持續回傳工作階段狀態、轉錄、文字、音訊、函式參數和錯誤事件。
本頁以 WebSocket 作為主要連線方式。連線時請將 MODEL_ID 替換為目前帳戶可見且支援 Realtime 的模型 ID。
典型情境包括即時語音對話、會議即時轉錄與語音助理、即時翻譯、語音轉錄、即時程式碼互動以及伺服器端即時整合。連線可同時承載文字與音訊,並透過事件處理 VAD、函式呼叫和狀態更新。
wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID認證與連線
WebSocket 認證
伺服器端應用透過 Bearer API Key 建立 WSS 連線,並在握手請求中帶上 Realtime Beta Header。
| 項目 | 值 |
|---|---|
| 連線位址 | wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID |
| Authorization | Bearer your-api-key |
| OpenAI-Beta | realtime=v1 |
長期 API Key 只應在可信伺服器端使用,不要將它寫入瀏覽器、行動應用程式套件或公開程式碼儲存庫。所有連線都應使用 HTTPS/WSS。
暫時權杖
用戶端連線時,可先由可信伺服器端建立有效期為一分鐘、僅用於單一連線的暫時權杖。
POST https://api.agtcloud.cn/v1/realtime/sessions
Content-Type: application/json
Authorization: Bearer your-api-key
{
"model": "MODEL_ID",
"voice": "verse"
}連線流程
WebSocket 主流程由伺服器端直接使用 API Key 建立連線,握手成功後在同一連線中傳送用戶端事件並接收伺服器端事件。
WebRTC 流程則由用戶端先向自己的應用程式伺服器請求暫時權杖,應用程式伺服器呼叫工作階段 API 建立權杖;用戶端隨後產生 SDP Offer、提交至 Realtime 端點並接收 SDP Answer,最後透過 oai-events 資料通道交換 JSON 事件。
WebSocket 連線範例
下列範例分別展示 Node.js、Python、事件傳送和事件接收。建立連線後,用戶端傳送 JSON 事件,伺服器端也會以 JSON 事件持續回傳結果。
import WebSocket from 'ws';
const ws = new WebSocket('wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID', {
headers: {
Authorization: 'Bearer your-api-key',
'OpenAI-Beta': 'realtime=v1',
},
});
ws.on('open', () => {
console.log('Connected to server.');
});
ws.on('message', (message) => {
console.log(JSON.parse(message.toString()));
});WebRTC 串接說明
目前建議使用 WebSocket。使用 WebRTC 前,請先確認目標模型是否支援;以下範例說明暫時權杖、SDP、音訊軌道和資料通道的基本連線架構。
WebRTC 連線網址為 https://api.agtcloud.cn/v1/realtime?model=MODEL_ID。用戶端使用暫時權杖提交 application/sdp,資料通道名稱為 oai-events,事件格式為 JSON;輸入音訊透過 addTrack() 傳送,輸出音訊透過 ontrack 接收。
瀏覽器用戶端與 SDP 交換
async function init() {
const tokenResponse = await fetch('/session');
const data = await tokenResponse.json();
const ephemeralKey = data.client_secret.value;
const pc = new RTCPeerConnection();
const audioElement = document.createElement('audio');
audioElement.autoplay = true;
pc.ontrack = (event) => {
audioElement.srcObject = event.streams[0];
};
const mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
pc.addTrack(mediaStream.getTracks()[0]);
const dataChannel = pc.createDataChannel('oai-events');
dataChannel.addEventListener('message', (event) => {
console.log(JSON.parse(event.data));
});
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(
'https://api.agtcloud.cn/v1/realtime?model=MODEL_ID',
{
method: 'POST',
body: offer.sdp,
headers: {
Authorization: `Bearer ${ephemeralKey}`,
'Content-Type': 'application/sdp',
},
},
);
await pc.setRemoteDescription({
type: 'answer',
sdp: await response.text(),
});
}
init();伺服器端建立暫時權杖
import express from 'express';
const app = express();
app.get('/session', async (_request, response) => {
const result = await fetch('https://api.agtcloud.cn/v1/realtime/sessions', {
method: 'POST',
headers: {
Authorization: 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'MODEL_ID',
voice: 'verse',
}),
});
response.send(await result.json());
});
app.listen(3000);資料通道事件收發
const dataChannel = pc.createDataChannel('oai-events');
dataChannel.addEventListener('message', (event) => {
const realtimeEvent = JSON.parse(event.data);
console.log(realtimeEvent);
});
dataChannel.send(JSON.stringify({
type: 'response.create',
response: {
modalities: ['text'],
instructions: 'Write a haiku about code',
},
}));類瀏覽器執行環境的標準 WebSocket 範例
Deno、Cloudflare Workers 等類瀏覽器執行環境可透過子協議傳遞認證資訊。使用前請確認目前執行環境和節點是否支援;不建議在一般瀏覽器頁面中放置長期 API Key。
const ws = new WebSocket(
'wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID',
[
'realtime',
'openai-insecure-api-key.your-api-key',
'openai-organization.ORGANIZATION_ID',
'openai-project.PROJECT_ID',
'openai-beta.realtime-v1',
],
);
ws.addEventListener('open', () => {
console.log('Connected to server.');
});
ws.addEventListener('message', (event) => {
console.log(JSON.parse(event.data));
});工作階段、音訊與對話
Realtime 支援純文字、語音以及文字與音訊混合對話。工作階段設定可以包含輸入和輸出音訊格式、語音、溫度、最大輸出長度、工具以及 VAD 參數。
- 輸入與輸出音訊格式:
pcm16、g711_ulaw、g711_alaw。 - 範例語音選項:
alloy、echo、shimmer。 - VAD 設定包括閾值、語音前綴填充和靜音持續時間。
- 對話由工作階段、對話項、內容部分和回應事件共同推進。
具體事件欄位請在下方事件瀏覽器中檢視;共用參數和值域集中列在「共用類型」。
事件 Reference
選擇事件以檢視欄位定義和 JSON 範例。可以切換事件方向、依類別篩選或搜尋事件名稱。
session.update
更新工作階段的預設設定。
| 欄位 | 類型 | 必填 | 說明 | 範例值 |
|---|---|---|---|---|
event_id | 字串 | 否 | 用戶端產生的事件識別碼 | event_123 |
type | 字串 | 否 | 事件類型 | session.update |
modalities | 字串陣列 | 否 | 模型可回應的模態類型 | ["text", "audio"] |
instructions | 字串 | 否 | 預設到模型呼叫前的系統指令 | "請用簡潔、準確的語言回答。" |
voice | 字串 | 否 | 模型使用的語音類型 | alloy、echo、shimmer |
input_audio_format | 字串 | 否 | 輸入音訊格式 | pcm16、g711_ulaw、g711_alaw |
output_audio_format | 字串 | 否 | 輸出音訊格式 | pcm16、g711_ulaw、g711_alaw |
input_audio_transcription.model | 字串 | 否 | 用於轉錄的模型 | whisper-1 |
turn_detection.type | 字串 | 否 | 語音檢測類型 | server_vad |
turn_detection.threshold | 數字 | 否 | VAD 激活閾值(0.0-1.0) | 0.8 |
turn_detection.prefix_padding_ms | 整數 | 否 | 語音開始前包含的音訊長度 | 500 |
turn_detection.silence_duration_ms | 整數 | 否 | 檢測語音停止的靜音持續時間 | 1000 |
tools | 陣列 | 否 | 模型可用的工具清單 | [] |
tool_choice | 字串 | 否 | 模型選擇工具的方式 | auto/none/required |
temperature | 數字 | 否 | 模型取樣溫度 | 0.8 |
max_output_tokens | 字串或整數 | 否 | 單次回應最大token數 | "inf"/4096 |
{
"event_id": "event_123",
"type": "session.update",
"modalities": [
"text",
"audio"
],
"instructions": "請用簡潔、準確的語言回答。",
"voice": "alloy",
"input_audio_format": "pcm16",
"output_audio_format": "pcm16",
"input_audio_transcription": {
"model": "whisper-1"
},
"turn_detection": {
"type": "server_vad",
"threshold": 0.8,
"prefix_padding_ms": 500,
"silence_duration_ms": 1000
},
"tools": [],
"tool_choice": "auto",
"temperature": 0.8,
"max_output_tokens": "inf"
}共用類型
以下折疊區匯總速率限制、函式呼叫、音訊、VAD、工具、模型、事件、工作階段、對話項、內容、回應、轉錄、音訊流和 WebRTC 參數表。
速率限制事件參數表4 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
name | 字串 | 是 | 限制名稱 | 範例值:requests_per_min |
limit | 整數 | 是 | 限制值 | 範例值:60 |
remaining | 整數 | 是 | 剩餘可用量 | 範例值:45 |
reset_seconds | 整數 | 是 | 重置時間(秒) | 範例值:35 |
函式呼叫參數表4 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
type | 字串 | 是 | 函數類型 | 範例值:function |
name | 字串 | 是 | 函數名稱 | 範例值:get_weather |
description | 字串 | 否 | 函數描述 | 範例值:Get the current weather |
parameters | 物件 | 是 | 函數參數定義 | 範例值:{"type": "object", "properties": {...}} |
音訊格式參數表4 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
sample_rate | 整數 | — | 取樣率 | 可選值:8000, 16000, 24000, 44100, 48000 |
channels | 整數 | — | 聲道數 | 可選值:1 (單聲道), 2 (立體聲) |
bits_per_sample | 整數 | — | 取樣位數 | 可選值:16 (pcm16), 8 (g711) |
encoding | 字串 | — | 編碼方式 | 可選值:pcm16, g711_ulaw, g711_alaw |
語音檢測參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
threshold | 浮點數 | — | VAD 激活閾值 | 預設值:0.5;範圍:0.0-1.0 |
prefix_padding_ms | 整數 | — | 語音前綴填充(毫秒) | 預設值:500;範圍:0-5000 |
silence_duration_ms | 整數 | — | 靜音檢測長度(毫秒) | 預設值:1000;範圍:100-10000 |
工具選擇參數表2 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
tool_choice | 字串 | — | 工具選擇方式 | 可選值:auto, none, required |
tools | 陣列 | — | 可用工具清單 | 可選值:[{type, name, description, parameters}] |
模型設定參數表4 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
temperature | 浮點數 | — | 取樣溫度 | 範圍/可選值:0.0-2.0;預設值:1.0 |
max_output_tokens | 整數或字串 | — | 最大輸出長度 | 範圍/可選值:1-4096/"inf";預設值:"inf" |
modalities | 字串陣列 | — | 回應模態 | 範圍/可選值:["text", "audio"];預設值:["text"] |
voice | 字串 | — | 語音類型 | 範圍/可選值:alloy, echo, shimmer;預設值:alloy |
事件通用參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
event_id | 字串 | 是 | 事件的唯一識別碼 | 範例值:event_123 |
type | 字串 | 是 | 事件類型 | 範例值:session.update |
timestamp | 整數 | 否 | 事件發生的時間戳(毫秒) | 範例值:1677649363000 |
工作階段狀態參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
status | 字串 | — | 工作階段狀態 | 可選值:active, ended, error |
error | 物件 | — | 錯誤資訊 | 可選值:{"type": "error_type", "message": "error message"} |
metadata | 物件 | — | 工作階段中繼資料 | 可選值:{"client_id": "web", "session_type": "chat"} |
對話項目狀態參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
status | 字串 | — | 對話項目狀態 | 可選值:completed, in_progress, incomplete |
role | 字串 | — | 傳送者角色 | 可選值:user, assistant, system |
type | 字串 | — | 對話項目類型 | 可選值:message, function_call, function_call_output |
內容類型參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
type | 字串 | — | 內容類型 | 可選值:text, audio, transcript |
format | 字串 | — | 內容格式 | 可選值:plain, markdown, html |
encoding | 字串 | — | 編碼方式 | 可選值:utf-8, base64 |
回應狀態參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
status | 字串 | — | 回應狀態 | 可選值:completed, cancelled, failed, incomplete |
status_details | 物件 | — | 狀態詳情 | 可選值:{"reason": "user_cancelled"} |
usage | 物件 | — | 使用統計 | 可選值:{"total_tokens": 50, "input_tokens": 20, "output_tokens": 30} |
音訊轉錄參數表4 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
enabled | 布林值 | — | 是否啟用轉錄 | 範例值:true |
model | 字串 | — | 轉錄模型 | 範例值:whisper-1 |
language | 字串 | — | 轉錄語言 | 範例值:en, zh, auto |
prompt | 字串 | — | 轉錄提示詞 | 範例值:"Transcript of a conversation" |
音訊流參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
chunk_size | 整數 | — | 音訊塊大小(位元組) | 可選值:1024, 2048, 4096 |
latency | 字串 | — | 延遲模式 | 可選值:low, balanced, high |
compression | 字串 | — | 壓縮方式 | 可選值:none, opus, mp3 |
WebRTC 設定參數表3 個欄位
| 欄位 | 類型 | 必填 | 說明 | 選用值或範例 |
|---|---|---|---|---|
ice_servers | 陣列 | — | ICE 伺服器清單 | 預設值:[{"urls": "stun:stun.l.google.com:19302"}] |
audio_constraints | 物件 | — | 音訊約束 | 預設值:{"echoCancellation": true} |
connection_timeout | 整數 | — | 連線逾時(毫秒) | 預設值:30000 |
錯誤處理與恢復
Realtime 錯誤通常來自連線、認證、音訊或工作階段四類問題:
| 類型 | 常見原因 | 處理方向 |
|---|---|---|
| 連線錯誤 | 網路中斷、握手失敗或連線設定錯誤 | 檢查 WSS 網址、網路和握手請求,依有限次數重新連線 |
| 認證錯誤 | API Key 無效、暫時權杖過期或與 API 網址不相符 | 更新認證資訊,並確保 API Key 與請求使用的 API 網址相符 |
| 音訊錯誤 | 裝置權限、格式不支援或編解碼不相符 | 檢查裝置權限、取樣與編碼設定,再重新建立音訊鏈路 |
| 工作階段錯誤 | 工作階段超時、併發限制或事件狀態不一致 | 保存錯誤事件,重新建立工作階段,必要時降級到非即時API |
恢復策略可以包括自動重連、工作階段恢復、有限重試和功能降級。發生錯誤時,應優先讀取 error 事件,保存其 event_id、error.type、error.code、error.message 和關聯事件資訊,再決定是否重發。