---
title: "OpenAI Realtime 클라이언트에서 ThunderPhone 사용"
description: "저장된 에이전트 또는 인라인 세션 구성을 사용하여 OpenAI Realtime 호환 서버 클라이언트를 ThunderPhone에 연결합니다."
---

ThunderPhone은 OpenAI Realtime 이벤트 모델의 핵심 하위 집합을 구현합니다.
기존 서버 측 클라이언트는 ThunderPhone 음성 에이전트를 사용하면서 WebSocket, 오디오, 세션 및
응답 이벤트 흐름을 유지할 수 있습니다.

## 연결 전 준비 사항

ThunderPhone 조직 비밀 API 키와 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 사용

`/v1`로 끝나는 WebSocket 기본 URL을 전달합니다. 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)와 선언된 레이트의
모노 PCM16 WAV로 시작합니다. 다음을 확인합니다.

1. 서버가 구성을 수락하고 `session.updated`를 전송합니다.
2. 입력이 예상 속도로 트랜스크립트 및 응답 오디오 이벤트를 생성합니다.
3. 중단 및 응답 취소가 남은 출력 오디오를 중지합니다.
4. 인라인 함수 결과 또는 저장된 에이전트 도구 결과가 모델로 반환됩니다.
5. 잘못된 입력이 클라이언트에서 처리하는 `error` 이벤트를 생성합니다.
6. 클라이언트가 소켓을 닫고 통화가 [통화
   기록](/ko/guides/review-calls)에 표시됩니다.

[Realtime WebSocket 참조](/api-reference/realtime)에는 허용되는 이벤트, 오디오 형식, 세션
필드 및 전체 예제가 나열되어 있습니다.

## 비용

Realtime 통화에는 선택한 제품의 일반 분당 요금이 적용됩니다. 실시간 트랜스크립트 델타를
활성화하면 전체 세션에 분당 추가 요금이 적용됩니다. 요금은 [실시간
트랜스크립트](/api-reference/realtime#live-transcripts)를, 제품 요금은
[가격](/ko/guides/pricing)을 참조합니다.

`POST /v1/realtime/sessions`는 별도의 관리형 LiveKit 경로입니다. 이 경로는 룸과 범위가
지정된 참가자 토큰을 생성하며, 직접 WebSocket 연결에는 필요하지 않습니다.

프레임워크 통합은 [Pipecat에서 ThunderPhone 사용](/ko/guides/use-with-pipecat) 및
[LiveKit Agents에서 ThunderPhone 사용](/ko/guides/use-with-livekit)을 참조합니다.
