ThunderPhone 2.0 正式上線。自助開通,每分鐘 2¢ 起。查看公告

Connect tools & data

搭配 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。請確認:

  1. 伺服器接受設定並傳送 session.updated。
  2. 輸入會以預期速度產生逐字稿與回應音訊事件。
  3. 中斷與取消回應會停止剩餘的輸出音訊。
  4. 內嵌函式結果或已儲存智慧體工具結果會回傳給模型。
  5. 無效輸入會產生你的用戶端能處理的 error 事件。
  6. 你的用戶端會關閉 Socket,且該通話會顯示在通話紀錄中。

Realtime WebSocket 參考文件列出可接受的事件、音訊格式、工作階段欄位與完整範例。

費用

Realtime 通話採用所選產品的一般每分鐘費率。啟用即時逐字稿增量會為整個工作階段加收每分鐘附加費;費率請參閱即時逐字稿,產品費率請參閱定價。

POST /v1/realtime/sessions 是獨立的受管理 LiveKit 路徑。它會建立房間與具範圍限制的參與者權杖;直接 WebSocket 連線不需要使用它。

如需框架整合,請參閱從 Pipecat 使用 ThunderPhone與從 LiveKit Agents 使用 ThunderPhone。