Open in
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소켓이 연결되는 동안 에이전트가 시작됩니다. 인사말은 계속 사용할 수
있지만, 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())입력 오디오 추가, 응답 오디오 델타, 중단, 함수 호출, 오류 및 소켓의 정상 종료에 대한 기존 처리는 유지합니다. 인라인 사용자 지정 함수는 클라이언트에서 실행되며, 결과는 Realtime 프로토콜을 통해 반환합니다. 저장된 에이전트 도구는 ThunderPhone에서 실행됩니다.
세션 수명 주기 및 실패
하나의 WebSocket은 하나의 통화를 나타냅니다. 잘못된 에이전트 ID 또는 거부된 인라인
구성은 error 이벤트를 발생시킵니다. 세션이 활성 상태라고 처리하기 전에
session.updated를 기다립니다. 실제 입력 및 출력 형식과 샘플링 레이트를 선언합니다.
PCM 레이트가 일치하지 않으면 유효성 검사 오류가 발생하는 대신 오디오가 너무 빠르거나
느리게 재생됩니다.
세션이 시작된 후 애플리케이션 작업이 끝나면 소켓을 정상적으로 닫습니다. 인라인 세션은 클라이언트에서 실행되는 함수를 사용할 수 있습니다. 저장된 에이전트 세션은 호환되는 ThunderPhone 실행 도구를 사용하며 통화 전환 또는 키패드 입력을 제공하지 않습니다.
통합 테스트
최소 Python WAV 클라이언트와 선언된 레이트의 모노 PCM16 WAV로 시작합니다. 다음을 확인합니다.
- 서버가 구성을 수락하고
session.updated를 전송합니다. - 입력이 예상 속도로 트랜스크립트 및 응답 오디오 이벤트를 생성합니다.
- 중단 및 응답 취소가 남은 출력 오디오를 중지합니다.
- 인라인 함수 결과 또는 저장된 에이전트 도구 결과가 모델로 반환됩니다.
- 잘못된 입력이 클라이언트에서 처리하는
error이벤트를 생성합니다. - 클라이언트가 소켓을 닫고 통화가 통화 기록에 표시됩니다.
Realtime WebSocket 참조에는 허용되는 이벤트, 오디오 형식, 세션 필드 및 전체 예제가 나열되어 있습니다.
비용
Realtime 통화에는 선택한 제품의 일반 분당 요금이 적용됩니다. 실시간 트랜스크립트 델타를 활성화하면 전체 세션에 분당 추가 요금이 적용됩니다. 요금은 실시간 트랜스크립트를, 제품 요금은 가격을 참조합니다.
POST /v1/realtime/sessions는 별도의 관리형 LiveKit 경로입니다. 이 경로는 룸과 범위가
지정된 참가자 토큰을 생성하며, 직접 WebSocket 연결에는 필요하지 않습니다.
프레임워크 통합은 Pipecat에서 ThunderPhone 사용 및 LiveKit Agents에서 ThunderPhone 사용을 참조합니다.