인공지능 기술의 발전으로 대화형 인터페이스가 우리 일상 생활에 깊숙이 파고들고 있습니다. 그 중심에 OpenAI의 혁신적인 Realtime API가 있습니다. 이 글에서는 Realtime API의 사용법과 예제를 통해 여러분이 어떻게 최첨단 실시간 대화형 챗봇을 만들 수 있는지 상세히 알아보겠습니다.
Realtime API란 무엇인가?
Realtime API는 OpenAI가 2024년 10월 1일에 공개한 최신 기술로, 개발자들이 빠른 응답 속도와 다중 모달리티를 지원하는 대화형 경험을 애플리케이션에 구현할 수 있게 해줍니다. 이 API는 텍스트와 오디오를 입력과 출력으로 모두 지원하며, 도구 호출 기능까지 제공합니다.
Realtime API의 주요 특징
- 네이티브 음성-음성 변환: 텍스트 중간 단계 없이 낮은 지연 시간과 뉘앙스 있는 출력을 제공합니다.
- 자연스럽고 조절 가능한 음성: 모델은 자연스러운 억양을 가지며 웃음, 속삭임 등을 표현할 수 있고 톤 지시에 따를 수 있습니다.
- 동시 다중 모달 출력: 텍스트는 모더레이션에 유용하며, 실시간보다 빠른 오디오 생성으로 안정적인 재생을 보장합니다.
Realtime API의 작동 원리
Realtime API는 WebSocket 인터페이스를 통해 서버에서 실행되도록 설계되었습니다. 이를 통해 클라이언트와 서버 간의 지속적인 연결을 유지하며 실시간으로 메시지를 교환할 수 있습니다.
연결 설정하기
Realtime API에 연결하기 위해서는 다음과 같은 파라미터가 필요합니다:
- URL:
wss://api.openai.com/v1/realtime
- 쿼리 파라미터:
?model=gpt-4o-realtime-preview-2024-10-01
- 헤더:
- Authorization:
Bearer YOUR_API_KEY
- OpenAI-Beta:
realtime=v1
- Authorization:
다음은 Node.js에서 ws
라이브러리를 사용하여 WebSocket 연결을 설정하는 간단한 예제 코드입니다:
import WebSocket from "ws";
const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01";
const ws = new WebSocket(url, {
headers: {
"Authorization": "Bearer " + process.env.OPENAI_API_KEY,
"OpenAI-Beta": "realtime=v1",
},
});
ws.on("open", function open() {
console.log("서버에 연결되었습니다.");
ws.send(JSON.stringify({
type: "response.create",
response: {
modalities: ["text"],
instructions: "사용자를 도와주세요.",
}
}));
});
ws.on("message", function incoming(message) {
console.log(JSON.parse(message.toString()));
});
Realtime API의 주요 개념
세션 (Session)
세션은 클라이언트와 서버 간의 단일 WebSocket 연결을 나타냅니다. 세션에는 기본 설정이 포함되어 있으며, 이는 언제든지 업데이트할 수 있습니다.
{
"id": "sess_001",
"object": "realtime.session",
"model": "gpt-4o",
"voice": "alloy"
}
대화 (Conversation)
대화는 항목(Item)들의 리스트로 구성됩니다. 기본적으로 세션 시작 시 하나의 대화가 생성됩니다.
{
"id": "conv_001",
"object": "realtime.conversation"
}
항목 (Item)
항목은 메시지, 함수 호출, 또는 함수 호출 출력의 세 가지 유형 중 하나입니다.
{
"id": "msg_001",
"object": "realtime.item",
"type": "message",
"status": "completed",
"role": "user",
"content": [{
"type": "input_text",
"text": "안녕하세요, 어떻게 지내세요?"
}]
}
Realtime API 사용 예제
사용자 메시지 보내기
const event = {
type: 'conversation.item.create',
item: {
type: 'message',
role: 'user',
content: [
{
type: 'input_text',
text: '안녕하세요!'
}
]
}
};
ws.send(JSON.stringify(event));
ws.send(JSON.stringify({type: 'response.create'}));
오디오 입력 처리하기
Realtime API는 24kHz의 1채널 little-endian 16비트 PCM 오디오와 8kHz의 G.711 (u-law 및 a-law) 두 가지 형식을 지원합니다. 오디오는 base64로 인코딩된 오디오 프레임의 청크로 전송해야 합니다.
다음은 Python에서 pydub
라이브러리를 사용하여 오디오 파일을 유효한 오디오 메시지 항목으로 변환하는 코드 예제입니다:
import io
import json
from pydub import AudioSegment
def audio_to_item_create_event(audio_bytes: bytes) -> str:
# 바이트 스트림에서 오디오 파일 로드
audio = AudioSegment.from_file(io.BytesIO(audio_bytes))
# 24kHz 모노 pcm16으로 리샘플링
pcm_audio = audio.set_frame_rate(24000).set_channels(1).set_sample_width(2).raw_data
# base64 문자열로 인코딩
pcm_base64 = base64.b64encode(pcm_audio).decode()
event = {
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [{
"type": "input_audio",
"audio": pcm_base64
}]
}
}
return json.dumps(event)
Realtime API의 고급 기능
함수 호출 (Function Calling)
Realtime API는 함수 호출을 지원하여 모델이 특정 작업을 수행하거나 외부 데이터를 가져올 수 있습니다. 함수는 세션 설정이나 응답 생성 시 도구로 전달될 수 있습니다.
{
"tools": [
{
"name": "get_weather",
"description": "주어진 위치의 날씨 정보를 가져옵니다",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "날씨를 확인할 위치",
},
"scale": {
"type": "string",
"enum": ['celsius', 'fahrenheit']
},
},
"required": ["location", "scale"],
},
}
]
}