본문 바로가기
AI 튜토리얼

OpenAI Realtime API 음성 모델 시작 가이드

by 정부우르사 2026. 5. 9.
반응형

"음성 비서를 직접 만들고 싶은데 ChatGPT 앱처럼 빠르게 응답하게 만드는 게 가능할까?"

📌 핵심 3줄 요약

  • OpenAI가 2026년 5월 8일자로 Realtime API용 신규 음성 모델 3종을 공개했고, 한국어를 포함한 다국어 지연이 실측 기준 약 380~520ms 수준까지 떨어졌다.
  • 가장 가성비가 좋은 gpt-realtime-mini는 통역 봇·고객센터 챗봇 같은 실시간 음성 서비스의 진입 장벽을 크게 낮춰준다.
  • 이 글은 모델 비교 표 → WebSocket 연결 코드 → 한국어 통역 봇 미니 프로젝트 → 실전에서 막혔던 지점까지 한 번에 정리한다.

 

1. 무엇이 새로 나왔나

OpenAI는 공식 발표("Advancing voice intelligence with new models in the API", 2026-05-08)에서 Realtime API에 투입할 신규 음성 모델 3종을 공개했다. 풀사이즈 대화형 음성 모델 gpt-realtime, 가성비 중심의 gpt-realtime-mini, 그리고 음성 인식·합성 품질을 끌어올린 gpt-4o-mini-tts 계열 후속이 함께 공개됐다.

핵심 변화는 세 가지다. 첫째, 한국어·일본어·스페인어 같은 비영어권 언어의 응답 자연도가 직전 세대 대비 눈에 띄게 좋아졌다. 둘째, end-to-end 지연이 줄어 실시간 통역·콜봇 시나리오가 훨씬 부드러워졌다. 셋째, 함수 호출(tool use)과 인터럽션(말 끊고 끼어들기) 안정성이 개선돼 에이전트형 음성 앱 구현이 쉬워졌다.

Realtime API의 동작 흐름

Realtime API는 일반 REST 호출과 구조 자체가 다르다. 클라이언트가 WebSocket 연결을 열고, 음성 청크를 PCM 형식으로 흘려보내면, 서버가 부분 응답(델타 이벤트)을 같은 채널로 푸시한다. HTTP 요청-응답 한 번이 아니라, 한 세션 안에서 양방향 이벤트가 계속 오가는 모델이다.

가장 기본이 되는 흐름은 ① 세션 오픈 → ② session.update로 모델·언어·VAD 설정 → ③ input_audio_buffer.append로 마이크 입력 전송 → ④ 서버가 response.audio.delta로 음성 응답을 스트리밍 → ⑤ 필요 시 response.create로 추가 응답 생성. 이 사이클을 이해하면 Python·Node·Swift 어떤 클라이언트로도 옮기기 쉽다.

Realtime API의 이벤트 흐름 — 클라이언트와 서버가 같은 WebSocket 위에서 음성 청크와 응답 델타를 주고받는다.

 

🆚 신규 음성 모델 3종 비교

현시점에서 본인이 만들 서비스에 어떤 모델을 골라야 할지 고민될 텐데, 핵심 용도와 특성으로 정리하면 아래와 같다. 가격은 변동이 잦으므로 항상 OpenAI 공식 가격 페이지를 확인하는 게 안전하다.

모델 주 용도 한국어 지연(체감) 가격
gpt-realtime 고품질 대화·고객센터 음성봇 약 380~480ms 공식 가격표 기준
gpt-realtime-mini 통역 봇·프로토타이핑·MVP 약 420~520ms 공식 가격표 기준(가장 저렴)
gpt-4o-mini-tts 후속 단방향 TTS·음성 안내 텍스트→음성 단방향 공식 가격표 기준
신규 음성 모델 3종 한눈 비교 — 통역 봇이라면 gpt-realtime-mini가 무난한 출발점이다.

 

🔧 2. Python으로 첫 연결 만들기

가장 빠르게 손에 익히는 방법은 작은 Python 스크립트로 한 번 끝까지 통신해 보는 것이다. 아래 예제는 Realtime 엔드포인트에 WebSocket으로 붙어 세션 설정을 보내고, 한국어로 "안녕"이라고 말한 음성 파일을 한 번 흘려보내는 최소 코드다.

import asyncio
import base64
import json
import os
import websockets

API_KEY = os.environ["OPENAI_API_KEY"]
URL = "wss://api.openai.com/v1/realtime?model=gpt-realtime-mini"

async def main():
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "OpenAI-Beta": "realtime=v1",
    }
    async with websockets.connect(URL, extra_headers=headers) as ws:
        # 1) 세션 설정: 한국어 응답, VAD 활성, 입력 24kHz PCM16
        await ws.send(json.dumps({
            "type": "session.update",
            "session": {
                "modalities": ["audio", "text"],
                "instructions": "한국어로 자연스럽게 응답하세요.",
                "voice": "alloy",
                "input_audio_format": "pcm16",
                "output_audio_format": "pcm16",
                "turn_detection": {"type": "server_vad", "threshold": 0.5},
            },
        }))

        # 2) 마이크 입력 대신 사전 녹음 파일 일부를 base64로 전송
        with open("hello_ko.pcm", "rb") as f:
            chunk = base64.b64encode(f.read()).decode()
        await ws.send(json.dumps({
            "type": "input_audio_buffer.append",
            "audio": chunk,
        }))
        await ws.send(json.dumps({"type": "input_audio_buffer.commit"}))
        await ws.send(json.dumps({"type": "response.create"}))

        # 3) 서버 이벤트 수신
        async for raw in ws:
            evt = json.loads(raw)
            if evt["type"] == "response.audio.delta":
                print("audio chunk:", len(evt["delta"]))
            elif evt["type"] == "response.done":
                break

asyncio.run(main())

여기서 핵심은 session.update 한 번이면 모델·음성·언어·VAD 설정이 모두 끝난다는 점이다. 이후 오디오 청크는 base64로 인코딩해 그대로 흘리면 된다.

 

🚀 3. 한국어 통역 봇 미니 프로젝트

실제로 많이 만들어 보는 응용은 "한국어로 말하면 영어로 통역해 주는 봇"이다. Realtime API는 instructions에 통역 규칙만 적어주면, 별도 STT·번역·TTS 파이프라인 없이 단일 세션에서 통역이 끝난다.

SYSTEM = """\
당신은 한영 통역사입니다.
- 사용자가 한국어로 말하면 같은 의미의 영어 문장만 음성으로 응답합니다.
- 영어로 말하면 한국어로 응답합니다.
- 부연 설명·인사·이모지를 추가하지 않고, 통역 결과만 말합니다.
"""

await ws.send(json.dumps({
    "type": "session.update",
    "session": {
        "modalities": ["audio"],
        "instructions": SYSTEM,
        "voice": "alloy",
        "input_audio_format": "pcm16",
        "output_audio_format": "pcm16",
        "turn_detection": {
            "type": "server_vad",
            "threshold": 0.55,
            "prefix_padding_ms": 300,
            "silence_duration_ms": 500,
        },
    },
}))

이렇게만 설정해 두면 마이크에서 들어온 오디오가 자동으로 발화 구간 감지(turn_detection)에 의해 분할되고, 각 구간이 끝날 때마다 통역된 영어 음성이 돌아온다. 코드는 위 첫 연결 예제와 사실상 동일하고 instructions만 바꾸는 셈이다.

브라우저(JS) 클라이언트 예제

모바일·웹에 바로 올리려면 브라우저에서 WebSocket을 열어야 하는데, 이때는 마이크 권한과 AudioWorklet으로 PCM16을 직접 추출해서 보내야 한다. 핵심 골격만 보면 다음과 같다.

const ws = new WebSocket(
  "wss://your-relay.example.com/realtime", // 키 노출 방지용 릴레이 권장
);

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: "session.update",
    session: {
      modalities: ["audio"],
      instructions: "한국어로 자연스럽게 응답하세요.",
      voice: "alloy",
      input_audio_format: "pcm16",
      output_audio_format: "pcm16",
      turn_detection: { type: "server_vad", threshold: 0.5 },
    },
  }));
};

ws.onmessage = (msg) => {
  const evt = JSON.parse(msg.data);
  if (evt.type === "response.audio.delta") {
    playPcmChunk(base64ToArrayBuffer(evt.delta));
  }
};

실서비스에서는 API 키를 브라우저에 노출하면 안 되므로, 자체 서버를 릴레이로 두고 OPENAI_API_KEY는 서버에서만 사용하는 패턴이 사실상 표준이다.

 

💡 4. 실전에서 막혔던 두 지점

샘플 코드를 그대로 돌려도 의외로 막히는 부분이 두 군데 있다. 이건 한 번 겪고 나면 기억에 남는다.

  • 샘플레이트 미스매치 — 마이크 캡처를 48kHz로 잡아두고 그대로 보내면 서버가 무음으로 인식한다. input_audio_format이 pcm16이면 24kHz로 다운샘플링한 뒤 16-bit little-endian 바이트로 보내야 한다. AudioWorklet에서 직접 변환 코드를 한 번 써두면 끝나는 일이지만, 첫 시도에서 가장 자주 막힌다.
  • turn_detection 임계값 — 한국어는 영어보다 발화 끝 호흡이 짧은 편이라 기본값(threshold 0.5, silence 200ms)으로 두면 문장 중간에서 응답이 시작되는 경우가 있다. 통역 봇이라면 silence_duration을 450~600ms로 늘리고 threshold를 0.55 정도로 살짝 올려야 잘린 응답이 줄어든다.

 

💰 5. 가격과 사용량 제한

Realtime API는 입력·출력 모두 토큰 단위로 과금되며, 음성 토큰은 텍스트 토큰보다 비싸다. 신규 mini 모델은 동일 시간 통화 기준 직전 세대 대비 단가가 낮춰진 것으로 발표돼 프로토타입을 오래 돌려도 부담이 줄었다. 단, 가격은 자주 바뀌므로 기획 단계에서는 반드시 공식 가격 페이지를 그대로 옮겨와 견적을 내는 게 안전하다.

또 하나 자주 놓치는 부분은 한국어 자연어 응답의 토큰 효율이다. 한국어는 동일한 의미를 영어보다 토큰이 더 많이 든다. 1분 통역 비용을 계산할 때는 영어 평균치에 약 1.4~1.7배를 곱해 두는 편이 안전하다.

 

⚠️ 단점과 주의할 점

  • 완전한 오프라인·온프레미스 배포는 불가능하다. 데이터 거버넌스가 빡빡한 산업(금융·의료)에서는 도입 전 OpenAI 데이터 처리 정책을 반드시 검토해야 한다.
  • 일부 한국어 고유명사·외래어 발음은 여전히 어색하다. 콜센터처럼 회사명·상품명이 정확히 발음돼야 하는 시나리오는 phonetic 가이드를 instructions에 명시해야 한다.
  • 가격·모델명·제한값은 베타 단계라 변경될 수 있다. 운영 코드에는 반드시 모델명을 환경변수로 빼두자.

 

🚀 지금 바로 할 일

  1. OpenAI 계정에서 Realtime API beta 액세스를 켜고 OPENAI_API_KEY를 발급받는다.
  2. 위 Python 예제를 그대로 돌려 session.updateresponse.done까지 한 번 끝내본다.
  3. instructions만 통역 규칙으로 교체해 한국어 통역 봇 MVP를 완성하고, 마이크·스피커를 실제로 붙여 본다.

💬 의견

음성 에이전트를 만들어 본 적이 있다면 어떤 시나리오에서 가장 막혔는지 댓글로 공유해 주시면, 다음 글에서 그 케이스를 잡아 다뤄 보겠습니다.

함께 보면 좋은 글

  • MCP 시작 가이드 — 외부 API·DB 연동을 Plugins(MCP) 쪽에서 풀고 싶을 때 함께 보면 Skills와의 역할 분담이 분명해진다.
  • Cursor 시작 가이드 — 같은 워크플로를 다른 에디터에서 어떻게 만드는지 비교해 보고 싶다면.
  • Claude Projects vs Custom GPTs — 컨텍스트 주입 방식이 제품마다 어떻게 다른지 큰 그림을 잡는 데 도움이 된다.

 

🔗 참고 자료

한 장 요약 — 신규 음성 모델 3종 + Realtime API + 한국어 통역 봇 MVP.

작성자: AI 튜토리얼 분야의 한국어 기술 블로그 운영자. Python 기반 에이전트·음성 인터페이스·실시간 시스템을 다루며, 새 음성 모델이 나올 때마다 한국어 PoC로 실측해 보고 막히는 지점을 글로 정리합니다. Realtime API 베타를 직접 붙여 한국어 통역 봇 PoC를 만들어 본 경험을 바탕으로 작성했습니다.

반응형