WebSocket과 WebRTC는 모두 연결을 열어 두어, 오디오 조각마다 새 요청을 보내지 않고도 양방향으로 오디오를 주고받게 해 줍니다. 차이는 네트워크가 말썽을 부릴 때 무슨 일이 일어나느냐입니다. WebSocket은 TCP 위에서 동작하므로 기다리는 한이 있어도 모든 바이트가 순서대로 도착합니다. WebRTC는 보통 UDP 위에서 동작하고 미디어를 위해 만들어졌기 때문에, 늦게 온 패킷은 버리거나 보정하고 재생을 이어 갑니다.
음성 에이전트에서는 이 차이가 각각의 자리를 정합니다. WebRTC는 사람의 기기와 서버 사이, 즉 Wi-Fi와 모바일 네트워크가 패킷을 잃는 구간을 위한 것입니다. WebSocket은 패킷 손실이 거의 없는 서버 간 구간, 그리고 단순하고 순서가 보장된 메시지 흐름이 필요한 모든 곳을 위한 것입니다. 실제 서비스 중인 음성 에이전트 대부분은 둘 다 사용합니다.
이 가이드는 음성 에이전트나 실시간 음성 기능의 전송 방식을 고르는 엔지니어를 위한 글입니다. 각 프로토콜의 작동 방식, 오디오에서 중요한 비교 포인트, 그리고 팀들이 실제로 운영하는 아키텍처를 다룹니다.
WebRTC vs WebSocket 한눈에 보기
| WebSocket | WebRTC | |
|---|---|---|
| 정체 | 양방향 메시지 채널 | 실시간 미디어를 위한 프로토콜 묶음 |
| 전송 계층 | TCP (wss://는 TLS 포함) | 보통 UDP. 대체 경로로 TURN 릴레이를 통한 TCP 또는 TLS |
| 전달 방식 | 모든 메시지를 순서대로 | 패킷이 버려질 수 있고, 늦은 오디오는 보정됨 |
| 패킷 손실 시 | 손실된 데이터가 재전송될 때까지 스트림이 멈춤 | 짧은 잡음은 있어도 오디오가 계속 재생됨 |
| 오디오 처리 | 없음. 형식, 버퍼, 재생을 직접 정함 | Opus 코덱, 지터 버퍼, 손실 보정 내장 |
| 연결 설정 | HTTP 업그레이드 요청 한 번 | 시그널링, ICE 후보, 흔히 STUN과 TURN 서버 |
| 서버 측 | 어떤 웹 서버나 언어든 가능 | 보통 미디어 서버나 호스팅 플랫폼 |
| 적합한 용도 | 서버 간 통신, API, 텍스트와 제어 메시지 | 통제할 수 없는 네트워크의 브라우저·모바일 오디오 |
WebSocket의 작동 방식
WebSocket은 Upgrade 헤더가 붙은 평범한 HTTP 요청으로 시작합니다. 서버가 수락하면 같은 TCP 연결이 계속 열려 있고, 양쪽 모두 언제든 메시지를 보낼 수 있습니다. 프로토콜은 RFC 6455에 정의되어 있으며, 모든 브라우저에 WebSocket API가 있습니다.
WebSocket은 오디오에 대해 아무것도 모릅니다. 메시지는 텍스트나 바이너리 프레임이고, 내용은 애플리케이션이 정합니다. 음성 API는 보통 base64로 인코딩한 PCM을 담은 JSON 이벤트나 원시 바이너리 프레임을 보냅니다. 코드는 마이크를 캡처하고, 조각을 인코딩해 보내고, 반대편에서는 돌아온 오디오를 재생 큐에 넣습니다.
장점은 단순함입니다. WebSocket은 대부분의 프록시와 로드 밸런서를 통과하고, 어떤 언어에서든 쓸 수 있으며, 메시지를 직접 읽을 수 있어 디버깅도 쉽습니다. 대가는 TCP의 전달 보장입니다. 패킷이 손실되면 TCP가 재전송하고, 그때까지 뒤따르는 데이터는 애플리케이션에 도달하지 않습니다. 파일 다운로드라면 정확히 원하는 동작입니다. 하지만 실시간 음성에서 200밀리초 재전송은 200밀리초의 침묵, 그리고 이어서 한꺼번에 몰려오는 오디오를 뜻합니다.
WebRTC의 작동 방식
WebRTC는 피어 간에 오디오, 비디오, 데이터를 실시간으로 보내기 위한 표준 묶음입니다(개요는 RFC 8825). 미디어 처리의 대부분은 브라우저가 맡습니다.
- 코덱. 브라우저는 오디오용으로 Opus와 G.711을 반드시 지원해야 합니다(RFC 7874). Opus는 음성을 잘 압축하고 네트워크에 맞춰 비트레이트를 조절합니다.
- 전송. 미디어는 SRTP로, 보통 UDP 위에서 전송되며 키는 DTLS로 협상합니다. 암호화는 필수입니다.
- 지터 버퍼와 손실 보정. 수신 측은 수십 밀리초 분량의 오디오를 쌓아 두고 불규칙한 도착을 고르게 만들며, 작은 빈틈은 멈추지 않고 메웁니다.
- NAT 통과. ICE는 먼저 직접 경로를 시도하고, STUN으로 공인 주소를 알아내며, 아무것도 통하지 않으면 TURN 릴레이로 대체합니다.
- 에코 제거와 잡음 억제. 브라우저는 WebRTC 통화에 이를 기본으로 적용합니다.
WebRTC가 정의하지 않는 것은 시그널링입니다. 미디어가 흐르기 전에 두 피어가 세션 설명과 네트워크 후보를 교환하는 방법이죠. 이 부분은 직접 만들어야 하고, 아주 흔히 WebSocket을 씁니다. 그래서 “WebRTC vs WebSocket”은 조금 이상한 비교입니다. 많은 WebRTC 앱 안에 WebSocket이 들어 있으니까요.
또 하나의 걸림돌은 서버 측입니다. WebRTC는 브라우저 간 통화를 위해 설계되었습니다. 상대 “피어”가 음성 에이전트라면 WebRTC를 말할 줄 아는 서버가 필요합니다. LiveKit 같은 미디어 서버(SFU)나 Daily 같은 호스팅 플랫폼이죠. TURN 서버와 미디어 서버를 직접 운영하는 것은 상당한 인프라 작업입니다.
음성 AI에서 중요한 쪽은 어디인가
음성 에이전트에는 최소 세 개의 네트워크 구간이 있고, 모두 같은 전송 방식을 쓸 필요는 없습니다.
사용자 기기에서 서버까지. 집 Wi-Fi, 사무실 네트워크, 기차 안의 휴대폰을 거치는 구간입니다. 여기서는 패킷 손실과 지터가 일상입니다. WebRTC는 바로 이 구간을 위해 만들어졌습니다. 패킷이 사라져도 오디오가 계속 흐르고, 대역폭이 떨어지면 Opus가 비트레이트를 낮추며, 브라우저가 사용자 마이크에서 에이전트의 목소리를 제거합니다. 사용자가 브라우저나 모바일 앱으로 에이전트와 대화한다면, WebRTC가 설정 비용을 회수하는 곳이 여기입니다.
서버에서 음성 모델까지. 에이전트는 음성 인식 모델에 오디오를, 음성 합성 모델에 텍스트를 스트리밍합니다. 이 연결은 데이터 센터 사이를 오가고 패킷 손실이 드물기 때문에, TCP의 순서 보장 전달은 거의 비용이 들지 않습니다. 게다가 오디오와 함께 순서대로 오는 텍스트·제어 이벤트, 요청 컨텍스트, 간단한 인증처럼 WebSocket이 주는 이점도 필요합니다. Cartesia를 포함한 음성 API들이 WebSocket으로 스트리밍하는 이유입니다.
전화 통화. 전화선으로 거는 사람은 전화망을 거쳐 SIP와 RTP, 또는 통신 사업자의 미디어 스트림으로 서버에 도달합니다. 예를 들어 Twilio Media Streams는 통화 오디오를 8 kHz μ-law로 WebSocket을 통해 서버에 전달합니다. 발신자 쪽에는 WebRTC도 WebSocket도 없습니다. 전화 에이전트의 전송 방식을 고르고 있다면 SIP 트렁킹 가이드를 읽어 보세요.
결국 물어야 할 것은 불안정한 네트워크가 어디에 있느냐입니다. 그 구간에 WebRTC를 두고, 나머지는 모두 WebSocket을 쓰세요.
클라이언트에서 WebSocket으로 충분한 경우
브라우저의 모든 음성 기능에 WebRTC가 필요한 것은 아닙니다. 다음과 같은 경우에는 클라이언트에서 바로 WebSocket을 쓰는 것도 합리적인 선택입니다.
- 네트워크가 예측 가능할 때. 사내 도구, 키오스크, 사무실 네트워크의 데스크톱 앱, 데모.
- 프로토타입을 만들 때. 연결 하나, 미디어 서버 없음, TURN 없음, 모든 이벤트를 로그로 남길 수 있습니다.
- 대화형 오디오가 아닐 때. 소리 내어 읽기용 스트리밍 음성 합성이나, 짧은 끊김이 대화를 망치지 않는 받아쓰기.
- 클라이언트가 서버일 때. 다른 곳의 오디오를 중계하는 백엔드나 엣지 함수.
이 방법을 택한다면 오디오는 작은 조각으로 보내고, 재생 버퍼는 짧게 유지하며, 사용자가 끼어들면 즉시 재생을 멈추세요. 출시 전에는 패킷 손실이 있는 네트워크에서 테스트하세요. 브라우저 개발자 도구는 대역폭과 지연은 제한할 수 있지만 패킷을 버릴 수는 없으니, OS 수준의 네트워크 컨디셔너나 휴대폰 핫스팟을 사용하세요.
실제로 쓰이는 아키텍처
프런트엔드는 WebRTC, 백엔드는 WebSocket. 가장 흔한 운영 구성입니다. 사용자의 브라우저나 앱이 LiveKit 또는 Daily의 WebRTC 룸에 들어갑니다. 에이전트는 서버에서 실행되어 같은 룸에 들어가고, 음성 모델에는 WebSocket으로 스트리밍합니다. LiveKit Agents와 Pipecat이 모두 이렇게 동작하며, 각각의 Cartesia 플러그인은 서버에서 Cartesia로 WebSocket을 엽니다. LiveKit과 Pipecat을 만든 Daily는 모두 Cartesia 고객입니다. Daily의 CEO Kwindla Hultman은 이렇게 말했습니다. “Cartesia Sonic is the best voice model today for real-time multimodal use cases.”
처음부터 끝까지 WebSocket. 브라우저가 WebSocket으로 서버에 오디오를 보내고, 서버도 음성 모델과 WebSocket으로 통신합니다. 가장 단순한 스택으로, 프로토타입과 통제된 네트워크에 잘 맞습니다. Cartesia Managed Agents도 WebSocket 연결을 직접 받으므로, 신뢰할 수 있는 서버나 짧은 수명의 액세스 토큰을 가진 브라우저가 에이전트 코드를 실행하지 않고도 호스팅된 에이전트와 대화할 수 있습니다.
입구는 전화, 내부는 WebSocket. 전화 에이전트에서는 통화가 SIP나 통신 사업자를 통해 들어오고, 에이전트와 음성 모델 사이의 연결은 WebSocket으로 유지됩니다. 전화 쪽은 Managed Agents가 Cartesia 번호, Twilio, 또는 직접 운영하는 SIP 트렁크를 통해 처리합니다.
WebSocket으로 Cartesia에 오디오 스트리밍하기
Cartesia의 실시간 API는 WebSocket으로 스트리밍합니다.
- 음성 합성:
wss://api.cartesia.ai/tts/websocket은 LLM에서 도착하는 대로 텍스트를 받아 오디오 조각을 돌려줍니다. 연결 하나로 여러 컨텍스트를 다룰 수 있고, continuation을 쓰면 LLM이 답변을 끝내기 전에 Sonic이 문장을 말하기 시작할 수 있습니다. - 음성 인식: Ink-2는 WebSocket으로 들어오는 원시 PCM 스트림을 받아쓰고, 턴 감지도 기본으로 처리합니다.
- Managed Agents:
wss://api.cartesia.ai/v1/agents/websocket/{agent_id}는 애플리케이션을 호스팅된 에이전트에 연결합니다. base64 오디오를 20~100밀리초 조각으로 나눠audio_input이벤트로 보내고,audio_output이벤트를 재생합니다. 사용자가 에이전트의 말에 끼어들기 시작하면 Cartesia가audio_output_clear를 보내고, 클라이언트는 재생을 멈춥니다.
에이전트 WebSocket은 헤더 없는 모노 오디오를 pcm_16000, pcm_24000, pcm_44100, mulaw_8000 중 하나로 받고, 같은 형식으로 오디오를 돌려줍니다.
{
"type": "session_create",
"audio": {
"input_format": "pcm_16000",
"output_delivery": "speaking_pace"
}
}
브라우저에서는 절대 클라이언트 코드에 API 키를 넣지 마세요. 브라우저는 WebSocket 헤더를 설정할 수 없으므로, 서버가 짧은 수명의 액세스 토큰을 발급하고 클라이언트는 이를 쿼리 매개변수로 전달합니다. 전체 세션 예시는 WebSocket API 가이드에 있습니다.
직접 해 보려면 Cartesia playground에서 에이전트를 만들거나, API 키를 발급받아 음성 합성 빠른 시작으로 첫 오디오를 스트리밍해 보세요.