Open in
搭配 OpenAI Realtime 用戶端使用 ThunderPhone
使用已儲存的智慧體或內嵌工作階段設定,將相容於 OpenAI Realtime 的伺服器用戶端指向 ThunderPhone。
ThunderPhone 實作了 OpenAI Realtime 事件模型中專注的一部分。 既有的伺服器端用戶端可在使用 ThunderPhone 語音智慧體時,保留其 WebSocket、音訊、工作階段與回應事件流程。
連線前
你需要 ThunderPhone 組織的私密 API 金鑰,以及可開啟 WebSocket 的伺服器執行環境。請勿從瀏覽器程式碼連線,或將金鑰暴露給瀏覽器。若要使用已儲存的智慧體,請先部署並複製其數字智慧體 ID。
連線至:
wss://api.thunderphone.com/v1/realtime從你的伺服器驗證 WebSocket 升級:
Authorization: Bearer sk_live_YOUR_API_KEY無法設定交握標頭的用戶端可使用查詢字串驗證,但 URL 更容易洩漏至日誌中。
選擇由誰管理設定
| 模式 | 連線方式 | 設定來源 |
|---|---|---|
| 已儲存的智慧體 | ?agent_id=12 | 已部署的提示、語音、產品、語言、知識,以及相容的伺服器端執行工具 |
| 內嵌 | 無 agent_id | 用戶端第一個被接受的 session.update |
已儲存的智慧體
使用已部署的智慧體 ID 連線:
wss://api.thunderphone.com/v1/realtime?agent_id=12智慧體會在 Socket 連線期間啟動。其問候語仍可使用,
但 Realtime 會停用其語音靜默確認,並省略 transfer_call
與 send_keypad_input。其他相容工具會在 ThunderPhone 上執行。請勿為此模式
傳送內嵌指示或由用戶端執行的工具。
在智慧體啟動前,使用 input_audio_format、
output_audio_format、input_rate 與 output_rate 查詢參數設定傳輸音訊。你
無法在連線後變更已儲存的設定或音訊格式。
內嵌工作階段
不使用 agent_id 時,請等待 session.created,然後傳送 session.update:
{
"type": "session.update",
"session": {
"type": "realtime",
"instructions": "Answer questions clearly and keep responses brief.",
"audio": {
"input": {
"format": { "type": "audio/pcm", "rate": 24000 }
},
"output": {
"format": { "type": "audio/pcm", "rate": 24000 },
"voice": "olivia"
}
},
"config": {
"product": "bolt"
}
}
}第一個被接受的更新會佈建通話。session.updated 表示
工作階段已啟用。在此之後,指示、語音、產品、工具與音訊格式均無法
變更。
內嵌工作階段沒有自動問候語或語音靜默確認。若要讓智慧體先說話,請附加一則系統或使用者訊息,並傳送
response.create。完全閒置的工作階段仍會在平台的靜默通話限制時結束,預設為 600 秒。
使用官方 OpenAI SDK
傳入以 /v1 結尾的 WebSocket 基礎 URL;SDK 會附加 /realtime。model 值是相容性名稱,不會選取 ThunderPhone 產品。請在工作階段設定或已儲存的智慧體中選擇產品。
這項連線檢查會建立內嵌 Bolt 工作階段、列印事件直到第一個 session.updated,然後關閉。請使用最精簡 Python 用戶端串流音訊。
import asyncio
import os
from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI(
api_key=os.environ["THUNDERPHONE_API_KEY"],
websocket_base_url="wss://api.thunderphone.com/v1",
)
async with client.realtime.connect(
model="thunderphone-realtime"
) as connection:
await connection.session.update(session={
"type": "realtime",
"instructions": "Listen to the caller and help them complete the call.",
"config": {"product": "bolt"},
})
async for event in connection:
print(event.type)
if event.type == "session.updated":
break
if __name__ == "__main__":
asyncio.run(main())保留你現有的輸入音訊附加、回應音訊增量、中斷、函式呼叫、錯誤處理,以及正常關閉 Socket 的邏輯。內嵌自訂函式會在你的用戶端中執行;請透過 Realtime 通訊協定回傳其結果。已儲存智慧體的工具會在 ThunderPhone 上執行。
工作階段生命週期與失敗情況
一個 WebSocket 代表一通通話。無效的智慧體 ID 或遭拒絕的內嵌設定會產生 error 事件。在將工作階段視為已啟用前,請先等待 session.updated。請宣告實際的輸入與輸出格式及取樣率:PCM 取樣率不符會使音訊播放過快或過慢,而不會產生驗證錯誤。
工作階段開始後,當你的應用程式完成作業時,請正常關閉 Socket。內嵌工作階段可使用由用戶端執行的函式。已儲存智慧體工作階段使用相容且由 ThunderPhone 執行的工具,且不提供轉接或按鍵輸入。
測試整合
先使用最精簡 Python WAV 用戶端,以及符合其宣告取樣率的單聲道 PCM16 WAV。請確認:
- 伺服器接受設定並傳送
session.updated。 - 輸入會以預期速度產生逐字稿與回應音訊事件。
- 中斷與取消回應會停止剩餘的輸出音訊。
- 內嵌函式結果或已儲存智慧體工具結果會回傳給模型。
- 無效輸入會產生你的用戶端能處理的
error事件。 - 你的用戶端會關閉 Socket,且該通話會顯示在通話紀錄中。
Realtime WebSocket 參考文件列出可接受的事件、音訊格式、工作階段欄位與完整範例。
費用
Realtime 通話採用所選產品的一般每分鐘費率。啟用即時逐字稿增量會為整個工作階段加收每分鐘附加費;費率請參閱即時逐字稿,產品費率請參閱定價。
POST /v1/realtime/sessions 是獨立的受管理 LiveKit 路徑。它會建立房間與具範圍限制的參與者權杖;直接 WebSocket 連線不需要使用它。
如需框架整合,請參閱從 Pipecat 使用 ThunderPhone與從 LiveKit Agents 使用 ThunderPhone。