Skip to main content

介紹

即時對話透過 WebSocket(一種在用戶端與伺服器端之間保持長連線、可雙向推送資料的協定)建立持久連線,把你的音訊或文字輸入即時送入對話模型,模型再以增量方式推送文字與語音回覆,適合語音助理、即時問答、口語練習等需要來回互動的情境。 它與即時語音轉錄同樣走 WebSocket,但用途不同: 可用模型:
  • gpt-realtime-2.1:語音對話模型,支援音訊與文字輸入,即時輸出文字與語音回覆。
本 API 面向伺服器端整合,瀏覽器無法直接連線。 基於安全考量,閘道會校驗並拒絕帶 Origin 標頭的連線、拒絕 openai-insecure-api-key 子協定,金鑰只接受標準 Authorization 標頭。瀏覽器發起的 WebSocket 會自動附帶 Origin 標頭,因此會被拒絕。若需在前端做即時對話,請在你自己的伺服器端建立到閘道的連線,再把音訊與結果在前端與伺服器端之間轉發。

快速開始

連線端點

  • model=gpt-realtime-2.1必填,模型在連線時由 URL 參數固定,工作階段中不可再更改(見下方約束)。
  • 注意與轉錄的區別:對話端點不帶 intent=transcription

鑑權

握手時透過標準 HTTP 標頭傳入金鑰:

音訊格式要求

目前音訊輸入與輸出均只支援一種格式,發送前請將音訊轉換為:
  • 編碼:PCM16(16 位元有符號整數,小端序)
  • 取樣率:24000 Hz
  • 聲道:單聲道(mono)
audio/pcm@24000。輸入或輸出宣告為其它格式(如 G.711/µ-law)會被拒絕並關閉工作階段。
與轉錄不同,對話工作階段支援語音活動偵測(turn_detection / VAD)。開啟後模型會自動判斷一段話何時結束並觸發回覆;關閉(設為 null)則由你手動控制何時提交音訊、何時請求回覆。二者按需選擇即可。

工作階段設定(session.update)

連線建立後,用戶端可發送一幀 session.update 設定對話參數(如語音音色、系統指令、是否開啟 VAD)。對話工作階段的模型已由連線 URL 錨定,因此不發送 session.update 也能直接對話;需要自訂音色或指令時再發送。

設定參數

string
必填
工作階段類型,對話情境為 realtime
string
系統指令,用於設定模型角色、語氣與回答約束。
string[]
輸出模態,取值為 ["audio"]["text"]:傳 ["audio"](預設)時模型輸出語音,回覆文字隨 response.output_audio_transcript.delta 事件返回;傳 ["text"] 時只輸出文字,文字隨 response.output_text.delta 事件返回。其它組合(如 ["audio", "text"])會被拒絕並返回 error 事件。
object
必填
輸入音訊格式,固定為 { "type": "audio/pcm", "rate": 24000 }
object | null
語音活動偵測。傳入 { "type": "server_vad" } 開啟自動斷句;傳入 null 關閉,由用戶端手動提交與請求回覆。
object
必填
輸出音訊格式,固定為 { "type": "audio/pcm", "rate": 24000 }
string
回覆語音的音色。首次回覆開始後不可再更改:工作階段進入產生狀態後,再次發送的 voice 會被忽略(其餘設定正常生效)。因此如需指定音色,請在首次請求回覆前設定。
以下能力本期暫不支援,設定後工作階段將被關閉(關閉碼 1008):在工作階段內開啟內嵌轉寫(audio.input.transcription,原因 input_transcription_not_supported)、透過工作階段項目注入音訊(原因 item_audio_not_supported)或圖像(原因 image_input_not_supported)、文字以外的其它內容項目類型(原因 unsupported_content_part)。音訊輸入請統一走 input_audio_buffer.append 通道。

發送輸入

發送音訊

將 PCM16 音訊切成小片(如每 100ms 一片),base64 編碼後透過 input_audio_buffer.append 事件持續發送:
開啟 VAD 時,模型會自動判斷說話結束並觸發回覆;關閉 VAD 時,發完一段音訊後需手動提交並請求回覆:

發送文字

也可以直接注入一則文字訊息,再請求回覆:

接收回覆

伺服器端會持續推送事件,關鍵事件類型:
event
工作階段建立、設定更新的確認。收到 session.created 後即可開始傳送音訊與文字。
event
工作階段項目寫入完成:使用者輸入與模型回覆各產生一條工作階段項目。
event
開啟 VAD 時,伺服器端偵測到使用者開始、結束說話。speech_started 通常意味著使用者正在打斷模型,處理方式見打斷與截斷
event
一輪回覆開始產生。
event
本輪回覆的輸出項目開始、結束。added 事件裡的 item.id 是後續截斷音訊時要引用的工作階段項目 ID。
event
回覆語音的增量片段(base64 編碼的 PCM16 音訊)與結束標記,可邊收邊播。
event
與回覆語音逐句對應的文字稿增量與結束標記,欄位 delta 是本次新增的文字。開啟語音輸出時,回覆文字從這個事件取,可用於邊播語音邊上字幕。
event
純文字回覆的增量與結束標記,僅在把輸出模態設為純文字(output_modalities: ["text"])時出現。
event
一輪回覆完成。該事件攜帶本輪的 token 用量(usage),是計費的依據。
event
截斷請求已生效的確認,見打斷與截斷
event
錯誤事件,包含錯誤碼與說明。請求本身有問題(如 output_modalities 取值非法)時只回一幀 error,工作階段繼續可用;涉及策略(如改模型、餘額耗盡)時關閉工作階段。
取回覆文字要認準事件。 預設(輸出含語音)時模型只推 response.output_audio_transcript.delta不會response.output_text.delta;把輸出模態設為純文字後,文字才走 response.output_text.delta。兩種模式都建議一併監聽,避免漏字(見下方執行結果)。

打斷與截斷

使用者在模型說話途中開口時,已經產生但還沒播放的內容會與使用者的下一句錯位。WebSocket 連線由用戶端負責播放,打斷後的收尾需要用戶端完成。 開啟 VAD 時,伺服器端偵測到使用者開口後會推送 input_audio_buffer.speech_started。用戶端收到該事件後:
  1. 立即停止本地播放,並記錄這一輪回覆已播放到的位置(毫秒)。
  2. 傳送 conversation.item.truncate,把未播放的音訊從工作階段中移除,避免下一輪對話裡模型認為這些內容已經說過。
  • item_id:本輪回覆的工作階段項目 ID,取自 response.output_item.added 事件的 item.id
  • content_index:音訊內容項目的下標,固定為 0
  • audio_end_ms:保留的音訊長度,單位毫秒,按用戶端實際播放到的位置填寫。
伺服器端處理完成後返回 conversation.item.truncated。截斷只影響這一輪回覆的音訊與對應文字稿,工作階段本身不受影響,之後可以繼續下一輪對話。使用 OpenAI SDK 時對應 conn.conversation.item.truncate(item_id=..., content_index=0, audio_end_ms=...) 關閉 VAD(如按鍵說話)時,按下按鍵即表示打斷:用戶端在按下時傳送 response.cancel 取消進行中的回覆,再按上面的步驟截斷;鬆開按鍵後依序傳送 input_audio_buffer.appendinput_audio_buffer.commitresponse.create

完整範例

以下給出三種寫法,任選其一:
  • OpenAI 官方 SDK(推薦):無需手寫 WebSocket,把 websocket_base_url(SDK 的 WebSocket 基底參數)指向閘道即可重用官方函式庫。
  • OpenAI Agents SDK:官方 agent 框架的即時語音形態,把 model_config 裡的 url 換成閘道位址即可。
  • 原生 websockets:不裝 SDK,直接按協定收發幀,依賴最少、便於排查。
為什麼要在連線時傳模型名? AiHubMix 閘道在 WebSocket 握手那一刻就要用 model 選擇模型推理廠商、鑑權、預留額度,而 session.update 是握手完成之後才到、來不及。所以用 SDK 時要給 connect() 顯式傳 model(SDK 會把它拼進 URL query);缺了它閘道在握手期就會拒絕,連線根本建不起來。與轉錄不同,對話端點不需要 intent=transcription
把任意音訊轉成本 API 要求的裸 PCM 格式,可用 ffmpeg:

重用官方範例

OpenAI 官方發布的即時對話範例多數只依賴 SDK 的基底參數,把位址換成 AiHubMix 端點即可重用:

執行結果(線上實測)

以下為 OpenAI SDK 範例在 aihubmix.com 線上環境(模型 gpt-realtime-2.1)的真實執行結果。工作階段開啟 server_vad,prompt 與語音均為英文。 文字輸入
音訊輸入
兩種設定的實測差異
實測確認:預設(輸出含語音)時回覆文字只從 response.output_audio_transcript.delta 逐字返回,response.output_text.delta 不出現;response.done 攜帶本輪 usage;握手耗時約 2 至 4 秒,為建立工作階段時的額度預留開銷。

計費說明

  • 按 token 計費:對話工作階段在每輪回覆完成時隨 response.done 事件返回本輪 token 用量(usage),據此計費。用量按音訊輸入 / 音訊輸出 / 文字輸入 / 文字輸出等組件分別計量,各組件單價以模型詳情頁即時掛牌價為準。
  • 邊用邊結算:這是一條長連線,費用在整個工作階段過程中隨每輪回覆即時扣除,無需等工作階段結束再一次性結算。建立工作階段時會先做一次約 1 分鐘用量的額度預留(僅作准入校驗,不是真實扣費),工作階段結束後釋放剩餘預留。因此帳戶可用餘額至少要夠約 1 分鐘的用量,工作階段才能建立。
  • 用量與帳單的消費明細裡可以逐條查看每次即時對話的計費記錄。

限制與約束

  1. 單一工作階段時長:一條 WebSocket 連線最長 62 分鐘,到時伺服器端主動關閉(關閉碼 1000,原因 session_duration_limit);需要更長請分段重連。
  2. 空閒斷線:用戶端與模型雙方都沒有活動持續 5 分鐘時,伺服器端關閉工作階段(關閉碼 1008,原因 idle_timeout)。任一方有活動都會重置計時,模型持續輸出的長回覆不會因此中斷。
  3. 餘額不足建立工作階段時可用餘額不足以覆蓋約 1 分鐘的預留額度,握手直接被拒(HTTP 403),工作階段不會建立;工作階段進行中若餘額耗盡,已建立的連線會被立即關閉。
  4. 僅伺服器端:不支援瀏覽器直接連線(校驗 Origin 標頭),請在伺服器端整合。
  5. 模型鎖定:模型在連線 URL 固定,工作階段中透過 session.update 改模型會被拒絕並關閉工作階段。
  6. 格式鎖定:音訊輸入與輸出均僅支援 audio/pcm@24000 單聲道,其它格式會被拒絕。
  7. 音色鎖定voice 在首次回覆開始後不可更改,請在首次請求回覆前設定。
  8. 暫不支援:工作階段內的內嵌轉寫、透過工作階段項目注入音訊或圖像內容、以及文字以外的其它內容項目類型。
  9. 單輪回覆:同一工作階段同一時刻只允許一輪進行中的回覆,上一輪未完成時再次傳送 response.create 會被拒絕並關閉工作階段(關閉碼 1008,原因 response_already_active)。

常見錯誤


更新時間:2026-09-21