Open in
使用 ThunderPhone 配合 OpenAI Realtime 用戶端
將與 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。