---
title: "Sử dụng ThunderPhone với ứng dụng khách OpenAI Realtime"
description: "Trỏ ứng dụng khách máy chủ tương thích với OpenAI Realtime đến ThunderPhone, bằng cách sử dụng tác nhân AI đã lưu hoặc cấu hình phiên nội tuyến."
---

ThunderPhone triển khai một tập con có trọng tâm của mô hình sự kiện OpenAI Realtime.
Ứng dụng khách phía máy chủ hiện có có thể giữ nguyên luồng sự kiện WebSocket, âm thanh, phiên và
phản hồi khi sử dụng tác nhân AI ThunderPhone.

## Trước khi kết nối

Bạn cần khóa API bí mật của tổ chức ThunderPhone và một môi trường chạy máy chủ có thể
mở WebSocket. Không kết nối từ mã trình duyệt hoặc để lộ khóa cho trình duyệt. Để sử dụng
tác nhân đã lưu, hãy triển khai tác nhân trước rồi sao chép ID tác nhân dạng số.

Kết nối tới:

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

Xác thực quá trình nâng cấp WebSocket từ máy chủ của bạn:

```http
Authorization: Bearer sk_live_YOUR_API_KEY
```

Xác thực bằng chuỗi truy vấn có sẵn cho các ứng dụng khách không thể đặt header bắt tay,
nhưng URL dễ bị rò rỉ vào nhật ký hơn.

## Chọn bên sở hữu cấu hình

| Chế độ | Kết nối bằng | Nguồn cấu hình |
| --- | --- | --- |
| Tác nhân đã lưu | `?agent_id=12` | Prompt, giọng nói, sản phẩm, ngôn ngữ, kiến thức và công cụ tương thích chạy trên máy chủ đã triển khai |
| Nội tuyến | Không có `agent_id` | `session.update` được chấp nhận đầu tiên từ ứng dụng khách của bạn |

### Tác nhân đã lưu

Kết nối bằng ID tác nhân đã triển khai:

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

Tác nhân bắt đầu hoạt động trong khi socket kết nối. Lời chào của tác nhân vẫn khả dụng,
nhưng Realtime tắt các lượt kiểm tra im lặng bằng giọng nói và bỏ qua `transfer_call`
và `send_keypad_input`. Các công cụ tương thích khác chạy trên ThunderPhone. Không gửi
hướng dẫn nội tuyến hoặc công cụ do ứng dụng khách thực thi cho chế độ này.

Đặt âm thanh trên đường truyền trước khi tác nhân khởi động bằng các tham số truy vấn
`input_audio_format`, `output_audio_format`, `input_rate` và `output_rate`. Bạn
không thể thay đổi cấu hình đã lưu hoặc định dạng âm thanh sau khi kết nối.

### Phiên nội tuyến

Không có `agent_id`, hãy chờ `session.created`, sau đó gửi `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"
    }
  }
}
```

Bản cập nhật được chấp nhận đầu tiên sẽ cấp phép cuộc gọi. `session.updated` nghĩa là
phiên đang hoạt động. Hướng dẫn, giọng nói, sản phẩm, công cụ và định dạng âm thanh không thể
thay đổi sau thời điểm đó.

Phiên nội tuyến không có lời chào tự động hoặc lượt kiểm tra im lặng bằng giọng nói. Để
tác nhân nói trước, hãy thêm tin nhắn hệ thống hoặc người dùng rồi gửi
`response.create`. Một phiên hoàn toàn không hoạt động vẫn kết thúc tại giới hạn cuộc gọi
im lặng của nền tảng, mặc định là 600 giây.

## Sử dụng SDK OpenAI chính thức

Truyền URL cơ sở WebSocket kết thúc bằng `/v1`; SDK sẽ thêm `/realtime`. Giá trị
`model` là tên tương thích và không chọn sản phẩm ThunderPhone. Chọn sản phẩm trong cấu hình phiên hoặc tác nhân đã lưu.

Kiểm tra kết nối này tạo một phiên Bolt nội tuyến, in các sự kiện cho đến
`session.updated` đầu tiên rồi đóng. Dùng [client Python tối
giản](/api-reference/realtime#minimal-python-client) để truyền trực tuyến audio.

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

Giữ nguyên cách xử lý hiện có của bạn cho việc thêm audio đầu vào, delta audio phản hồi,
ngắt quãng, lệnh gọi hàm, lỗi và đóng socket sạch. Các hàm tùy chỉnh nội tuyến
chạy trong client của bạn; trả kết quả của chúng qua giao thức Realtime. Công cụ của tác nhân đã lưu chạy trên ThunderPhone.

## Vòng đời phiên và lỗi

Mỗi WebSocket đại diện cho một cuộc gọi. ID tác nhân không hợp lệ hoặc cấu hình nội tuyến
bị từ chối sẽ tạo sự kiện `error`. Chờ `session.updated` trước khi
coi phiên là đang hoạt động. Khai báo định dạng đầu vào và đầu ra thực tế cùng tốc độ lấy mẫu:
tốc độ PCM không khớp sẽ phát audio quá nhanh hoặc quá chậm thay vì
tạo lỗi xác thực.

Sau khi phiên bắt đầu, hãy đóng socket sạch khi ứng dụng của bạn hoàn tất.
Phiên nội tuyến có thể sử dụng các hàm do client thực thi. Phiên tác nhân đã lưu
sử dụng các công cụ tương thích do ThunderPhone chạy và không hỗ trợ chuyển cuộc gọi hoặc nhập bằng bàn phím.

## Kiểm thử tích hợp

Bắt đầu với [client WAV Python tối giản](/api-reference/realtime#minimal-python-client)
và WAV PCM16 đơn kênh ở tốc độ đã khai báo. Xác minh:

1. Máy chủ chấp nhận cấu hình và gửi `session.updated`.
2. Đầu vào tạo sự kiện bản chép lời và audio phản hồi ở tốc độ dự kiến.
3. Ngắt quãng và hủy phản hồi dừng audio đầu ra còn lại.
4. Kết quả hàm nội tuyến hoặc kết quả công cụ của tác nhân đã lưu được trả về model.
5. Đầu vào không hợp lệ tạo sự kiện `error` mà client của bạn xử lý.
6. Client của bạn đóng socket và cuộc gọi xuất hiện trong [Lịch sử
   cuộc gọi](/vi/guides/review-calls).

[Tài liệu tham khảo WebSocket Realtime](/api-reference/realtime) liệt kê các
sự kiện được chấp nhận, định dạng audio, trường phiên và ví dụ hoàn chỉnh.

## Chi phí

Cuộc gọi Realtime sử dụng mức giá theo phút thông thường của sản phẩm đã chọn. Bật
delta bản chép lời trực tiếp sẽ thêm phụ phí theo phút cho toàn bộ phiên; xem [Bản chép lời
trực tiếp](/api-reference/realtime#live-transcripts) để biết mức phí và
[Bảng giá](/vi/guides/pricing) để biết mức giá sản phẩm.

`POST /v1/realtime/sessions` là một tuyến LiveKit được quản lý riêng. Tuyến này tạo
một phòng và token người tham gia có phạm vi; không bắt buộc cho kết nối WebSocket trực tiếp.

Để tích hợp framework, xem [Sử dụng ThunderPhone từ Pipecat](/vi/guides/use-with-pipecat)
và [Sử dụng ThunderPhone từ LiveKit Agents](/vi/guides/use-with-livekit).
