---
title: "ใช้ ThunderPhone กับไคลเอนต์ OpenAI Realtime"
description: "กำหนดให้ไคลเอนต์เซิร์ฟเวอร์ที่รองรับ OpenAI Realtime เชื่อมต่อกับ ThunderPhone โดยใช้เอเจนต์ที่บันทึกไว้หรือการกำหนดค่าเซสชันแบบอินไลน์"
---

ThunderPhone รองรับชุดย่อยที่มุ่งเน้นของโมเดลเหตุการณ์ OpenAI Realtime
ไคลเอนต์ฝั่งเซิร์ฟเวอร์ที่มีอยู่สามารถคงโฟลว์เหตุการณ์ WebSocket เสียง เซสชัน และ
การตอบกลับไว้ได้ ขณะใช้งานเอเจนต์เสียง ThunderPhone

## ก่อนเชื่อมต่อ

คุณต้องมีคีย์ API ลับขององค์กร ThunderPhone และรันไทม์ของเซิร์ฟเวอร์ที่
สามารถเปิด WebSocket ได้ ห้ามเชื่อมต่อจากโค้ดเบราว์เซอร์หรือเปิดเผยคีย์ให้
เบราว์เซอร์ หากต้องการใช้เอเจนต์ที่บันทึกไว้ ให้ปรับใช้ก่อนแล้วคัดลอก ID เอเจนต์แบบตัวเลข

เชื่อมต่อไปยัง:

```text
wss://api.thunderphone.com/v1/realtime
```

ตรวจสอบสิทธิ์การอัปเกรด WebSocket จากเซิร์ฟเวอร์ของคุณ:

```http
Authorization: Bearer sk_live_YOUR_API_KEY
```

มีการตรวจสอบสิทธิ์ผ่านสตริงคำค้นหาสำหรับไคลเอนต์ที่ไม่สามารถตั้งค่าส่วนหัว
ของการจับมือได้ แต่ URL รั่วไหลไปยังบันทึกได้ง่ายกว่า

## เลือกผู้ที่เป็นเจ้าของการกำหนดค่า

| โหมด | เชื่อมต่อด้วย | แหล่งที่มาของการกำหนดค่า |
| --- | --- | --- |
| เอเจนต์ที่บันทึกไว้ | `?agent_id=12` | พรอมป์ต์ที่ปรับใช้แล้ว เสียง ผลิตภัณฑ์ ภาษา ความรู้ และเครื่องมือที่เข้ากันได้ซึ่งทำงานบนเซิร์ฟเวอร์ |
| อินไลน์ | ไม่มี `agent_id` | `session.update` รายการแรกจากไคลเอนต์ของคุณที่ได้รับการยอมรับ |

### เอเจนต์ที่บันทึกไว้

เชื่อมต่อด้วย ID ของเอเจนต์ที่ปรับใช้แล้ว:

```text
wss://api.thunderphone.com/v1/realtime?agent_id=12
```

เอเจนต์จะเริ่มทำงานระหว่างที่ซ็อกเก็ตเชื่อมต่อ คำทักทายของเอเจนต์ยังคงพร้อมใช้งาน
แต่ Realtime จะปิดใช้งานการทักตรวจสอบความเงียบด้วยเสียง และจะไม่รวม `transfer_call`
และ `send_keypad_input` เครื่องมือที่เข้ากันได้อื่นจะทำงานบน ThunderPhone ห้าม
ส่งคำสั่งอินไลน์หรือเครื่องมือที่ไคลเอนต์เรียกใช้งานสำหรับโหมดนี้

ตั้งค่าเสียงบนการเชื่อมต่อก่อนเอเจนต์เริ่มทำงานด้วยพารามิเตอร์คำค้นหา
`input_audio_format`, `output_audio_format`, `input_rate` และ `output_rate` คุณ
ไม่สามารถเปลี่ยนการกำหนดค่าที่บันทึกไว้หรือรูปแบบเสียงหลังเชื่อมต่อได้

### เซสชันอินไลน์

หากไม่มี `agent_id` ให้รอ `session.created` แล้วส่ง `session.update`:

```json
{
  "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 อย่างเป็นทางการ

ส่ง URL ฐานของ WebSocket ที่ลงท้ายด้วย `/v1`; SDK จะต่อท้าย `/realtime` ค่า
`model` เป็นชื่อเพื่อความเข้ากันได้และไม่ได้เลือกผลิตภัณฑ์ ThunderPhone
เลือกผลิตภัณฑ์ในการกำหนดค่าเซสชันหรือเอเจนต์ที่บันทึกไว้

การตรวจสอบการเชื่อมต่อนี้จะสร้างเซสชัน Bolt แบบอินไลน์ พิมพ์เหตุการณ์จนถึง
`session.updated` รายการแรก แล้วปิด ใช้ [ไคลเอนต์ Python
ขั้นต่ำ](/api-reference/realtime#minimal-python-client) เพื่อสตรีมเสียง

```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())
```

คงการจัดการเดิมของคุณสำหรับการต่อท้ายเสียงขาเข้า เดลต้าเสียงการตอบกลับ
การขัดจังหวะ การเรียกใช้ฟังก์ชัน ข้อผิดพลาด และการปิดซ็อกเก็ตอย่างถูกต้อง
ฟังก์ชันแบบกำหนดเองอินไลน์จะทำงานในไคลเอนต์ของคุณ ให้ส่งผลลัพธ์กลับผ่าน
โปรโตคอล Realtime เครื่องมือของเอเจนต์ที่บันทึกไว้จะทำงานบน ThunderPhone

## วงจรชีวิตของเซสชันและความล้มเหลว

WebSocket หนึ่งรายการแทนหนึ่งสาย การระบุ ID เอเจนต์ไม่ถูกต้องหรือการกำหนดค่า
อินไลน์ถูกปฏิเสธจะสร้างเหตุการณ์ `error` รอ `session.updated` ก่อนถือว่า
เซสชันพร้อมใช้งาน ระบุรูปแบบและอัตราการสุ่มตัวอย่างของอินพุตและเอาต์พุตจริง:
อัตรา PCM ไม่ตรงกันจะเล่นเสียงเร็วหรือช้าเกินไป แทนที่จะสร้างข้อผิดพลาด
การตรวจสอบความถูกต้อง

หลังจากเซสชันเริ่มต้น ให้ปิดซ็อกเก็ตอย่างถูกต้องเมื่อแอปพลิเคชันของคุณเสร็จสิ้น
เซสชันอินไลน์สามารถใช้ฟังก์ชันที่ทำงานในไคลเอนต์ได้ เซสชันเอเจนต์ที่บันทึกไว้
ใช้เครื่องมือที่เข้ากันได้ซึ่งทำงานบน ThunderPhone และไม่มีการโอนสายหรือ
การป้อนข้อมูลด้วยแป้นกด

## ทดสอบการผสานรวม

เริ่มต้นด้วย [ไคลเอนต์ Python WAV
ขั้นต่ำ](/api-reference/realtime#minimal-python-client) และไฟล์ WAV PCM16 โมโน
ที่มีอัตราตามที่ระบุ ตรวจสอบว่า:

1. เซิร์ฟเวอร์ยอมรับการกำหนดค่าและส่ง `session.updated`
2. อินพุตสร้างเหตุการณ์ข้อความถอดเสียงและเสียงการตอบกลับด้วยความเร็วที่คาดไว้
3. การขัดจังหวะและการยกเลิกการตอบกลับหยุดเสียงเอาต์พุตที่เหลือ
4. ผลลัพธ์ของฟังก์ชันอินไลน์หรือผลลัพธ์เครื่องมือของเอเจนต์ที่บันทึกไว้ส่งกลับไปยังโมเดล
5. อินพุตที่ไม่ถูกต้องสร้างเหตุการณ์ `error` ที่ไคลเอนต์ของคุณจัดการ
6. ไคลเอนต์ของคุณปิดซ็อกเก็ตและสายปรากฏใน[ประวัติ
   สาย](/th/guides/review-calls)

[ข้อมูลอ้างอิง Realtime WebSocket](/api-reference/realtime) แสดงรายการเหตุการณ์
รูปแบบเสียง ฟิลด์เซสชัน และตัวอย่างฉบับสมบูรณ์ที่ยอมรับ

## ค่าใช้จ่าย

สาย Realtime ใช้อัตราปกติต่อนาทีของผลิตภัณฑ์ที่เลือก การเปิดใช้เดลต้าข้อความ
ถอดเสียงแบบสดจะเพิ่มค่าบริการต่อนาทีสำหรับทั้งเซสชัน ดูอัตราได้ที่[ข้อความ
ถอดเสียงแบบสด](/api-reference/realtime#live-transcripts) และดูอัตราผลิตภัณฑ์ได้ที่
[ราคา](/th/guides/pricing)

`POST /v1/realtime/sessions` เป็นเส้นทาง LiveKit ที่มีการจัดการแยกต่างหาก
ซึ่งสร้างห้องและโทเค็นผู้เข้าร่วมแบบกำหนดขอบเขต โดยไม่จำเป็นสำหรับการเชื่อมต่อ
WebSocket โดยตรง

สำหรับการผสานรวมกับเฟรมเวิร์ก ดู[ใช้ ThunderPhone จาก Pipecat](/th/guides/use-with-pipecat)
และ[ใช้ ThunderPhone จาก LiveKit Agents](/th/guides/use-with-livekit)
