전화망을 넘어: WebRTC와 WebSocket으로 짓는 초저지연 음성 스트리밍


음성 AI에서 '전송 계층'은 모델이 만들어 낸 소리를 사용자의 귀까지 실어 나르는 운반 경로를 가리킵니다. 모델 자체는 이제 발화가 끝나기 무섭게 답을 내놓을 만큼 빨라졌지만, 정작 대화가 굼뜨게 느껴지는 원인은 모델이 아니라 이 운반 계층에 숨어 있는 경우가 많습니다. 레이턴시 진단의 기본은 1편에서, 체감 지연을 줄이는 보정 기법은 3편에서 다뤘으니, 이번 편은 그 한 칸 아래 네트워크 전송 계층을 정면으로 봅니다. 어떤 프로토콜로 오디오를 나르느냐는 레이턴시 예산의 가장 과소평가된 항목이며, 한 번 잘못 고르면 그 위에서 아무리 최적화해도 천장이 생깁니다.

[시리즈] S2S·LLM 음성 에이전트 엔지니어링 63편 · 현재 4-2편

← 이전: 4-1 동적 컨텍스트 윈도우 관리 / 다음 → 4-3 비동기 이벤트 루프와 동시 콜 처리

전체 목차 펼치기 (63편)

Part 1 — 음성 AI가 느린 이유: 레이턴시 진단 (4편)

Part 2 — 텍스트를 넘어: End-to-End S2S의 원리 (4편)

Part 3 — 실시간 대화와 에이전트화: 인터럽트·MCP·도구 (5편)

Part 4 — 인프라·세션·보안: 프로덕션 백엔드 (5편)

Part 5 — 운영·품질·평가: 에이전틱 워크플로우와 신뢰성 (7편)

Part 6 — 음성 경험 고도화·실전 통합: 한국어·UX·전화망·엣지 (5편)

Part 7 — S2S 도입 전략·구매 의사결정 (4편)

Part 8 — LLM 콜봇 PoC 현장 (6편)

Part 9 — 상담어시스트: 상담사 화면을 바꾸는 실시간 AI (7편)

Part 10 — 직접 만든 롤플레이 챗봇: RAG 에이전트 구축기 (8편)

Part 11 — KMS 실무 — 지식관리시스템의 설계와 운영 현실 (8편)

왜 전통 전화망(SIP/RTP)만으로는 부족한가

전화 통화를 떠받쳐 온 SIP(세션 제어)와 RTP(미디어 전송) 조합은 수십 년간 검증된 자산입니다. 호 설정, 미디어 협상, 코덱 교섭이 표준화돼 있고 안정성도 높습니다. 문제는 실시간 AI 음성 에이전트가 요구하는 그림이 조금 다르다는 데 있습니다.

첫째, 클라이언트가 더 이상 전화기만은 아닙니다. 웹 브라우저와 모바일 앱이 직접 음성 채널의 한쪽 끝이 되는데, 브라우저는 RTP를 날것으로 다루지 못합니다. 둘째, 전통 전화망은 음성을 통신망 코덱으로 압축해 좁은 대역에 맞추도록 설계됐기에, 모델이 기대하는 넓은 대역의 깨끗한 오디오와는 결이 다릅니다. 셋째, 연결 셋업과 미디어 경로가 통신 사업자 인프라를 전제하는 경우가 많아, 인터넷 너머의 임의 클라이언트와 곧장 양방향으로 붙이기에는 손이 많이 갑니다. 그래서 실무에서는 전화망을 게이트웨이로 받아들이되, 실시간 AI 구간은 웹 친화적인 전송 계층으로 다시 구성하는 흐름이 일반적입니다.

그렇다면 이런 질문이 자연스레 따라붙습니다. 굳이 별도로 짤 것 없이, 음성봇용 녹취·스트리밍을 기존 상담 녹취 인프라에 그대로 얹으면 안 될까요? 답은 대개 "안 된다"입니다. "같은 음성인데 왜 따로 만드냐"는 직관과 달리, 실시간 AI 구간은 패킷이 흐르는 단위와 세션·이벤트가 오가는 흐름, 그리고 콜이 맺어지고 끊기는 구조 자체가 기존 녹취 파이프라인과 다릅니다. 기존 녹취는 통화가 끝난 뒤의 파일·구간 단위 처리에 맞춰져 있는데, 음성봇은 발화가 진행되는 동안의 패킷·이벤트를 실시간으로 받아 모델에 흘려보내야 하니, 처리 시점도 데이터 단위도 어긋납니다. 그래서 직관과 달리 두 인프라를 한 갈래로 합치지 못하고 나란히 두게 되는 일이 흔합니다. 처음 설계할 때부터 "녹취는 녹취대로, 실시간 음성 구간은 그 구간대로" 분리해 잡는 편이, 억지로 합쳤다가 되돌리는 것보다 비용이 적습니다.

WebRTC vs WebSocket: 같은 실시간인데 무엇이 다른가

이름이 비슷해 헷갈리지만 둘은 태생이 다릅니다. WebSocket은 TCP 위에서 동작하는 양방향 '메시지' 채널입니다. 순서와 도착을 보장하므로 제어 신호나 텍스트 이벤트에 이상적입니다. 다만 TCP의 신뢰성은 대가가 있어, 패킷 하나가 늦으면 뒤따르는 데이터가 줄줄이 기다리는 헤드 오브 라인 블로킹이 생깁니다. 실시간 오디오에서는 이 한 박자가 곧 끊김으로 들립니다.

WebRTC는 미디어를 위해 설계됐습니다. 기본적으로 UDP 위 SRTP로 오디오를 나르므로, 패킷 하나가 사라져도 멈추지 않고 다음 패킷을 재생합니다. 음성에서는 "조금 깨져도 빨리"가 "완벽하지만 늦게"보다 거의 항상 낫기 때문에, 이 손실 허용 성질이 결정적인 장점이 됩니다. 대신 NAT·방화벽 통과를 위한 셋업이 복잡하고, 구현 난도도 WebSocket보다 높습니다.

구분WebRTCWebSocket전통 전화망(SIP/RTP)
전송 계층주로 UDP(SRTP)TCPUDP(RTP)
손실/지연 내성손실 허용, 저지연순서·신뢰 보장, HoL 블로킹손실 허용
브라우저·앱 직결기본 지원지원(미디어는 직접 처리)직접 불가
NAT 통과ICE/STUN/TURN 내장불필요(서버 접속)별도 설계 필요
적합 용도클라이언트↔서버 실시간 오디오서버 간·제어 이벤트통신망 연동 게이트웨이

클라이언트↔AI 서버 WebRTC 양방향 스트리밍 구성

WebRTC로 사용자 단말과 AI 서버를 잇는 흐름은 크게 세 단계입니다. 먼저 양쪽이 서로의 미디어 능력과 후보 경로를 교환하는 시그널링이 필요합니다. 이때 주고받는 명세가 SDP이고, 가능한 네트워크 경로 후보를 모으는 절차가 ICE입니다. 직접 연결이 안 되면 STUN으로 공인 주소를 알아내고, 그래도 막히면 TURN 서버가 트래픽을 중계합니다.

[클라이언트]                         [AI 서버]
   │  1) 시그널링 채널로 SDP offer 전송  │
   │ ───────────────────────────────▶ │
   │  2) SDP answer 회신                │
   │ ◀─────────────────────────────── │
   │  3) ICE 후보 교환(STUN/TURN)        │
   │ ◀──────────────────────────────▶ │
   ├─ 4) 양방향 오디오 트랙 개설 ────────┤
   │   업스트림: 사용자 음성 →           │
   │   다운스트림: ← 합성된 응답 음성     │
저지연 오디오 전달 스택 위에서 아래로 브라우저 마이크, WebRTC 전송, 미디어 서버, STT 엔진 네 층이 수직으로 쌓여 있다. 각 층 사이에는 RTP/SRTP 또는 내부 스트림으로 오디오가 전달되는 방식이 표시된다. 브라우저 마이크WebRTC 전송미디어 서버 STT 엔진 RTP/SRTPRTP/SRTP내부 스트림

그림 1. 마이크 입력이 STT 엔진에 도달하기까지 거치는 전송 계층과 각 구간의 프로토콜.

연결이 서면 업스트림으로 사용자의 음성이 서버로 흐르고, 서버가 만든 응답 음성이 다운스트림으로 돌아옵니다. 두 트랙이 동시에 살아 있으므로, 사용자가 말하는 도중에도 서버가 즉시 반응할 수 있는 구조가 됩니다. 사용자가 말을 끊고 끼어드는 상황의 처리 로직은 9편에서 다뤘지만, 그 끼어듦이 지연 없이 감지되려면 애초에 업스트림이 끊김 없이 흐르는 전송 계층이 전제됩니다.

이렇게 업스트림과 다운스트림이 트랙으로 갈려 들어오는 구조는, 후처리에서도 한 가지 이점을 줍니다. 화자 분리 문제입니다. 굳이 트랙을 나눠 받을 필요가 있을까 싶겠지만, 사용자와 봇(또는 상담사)의 소리가 좌우 트랙처럼 물리적으로 분리되어 들어오면 누가 말했는지 가르는 일이 사실상 필요 없어집니다. 트랙 자체가 화자 라벨 역할을 하기 때문입니다. 반대로 두 목소리가 하나의 채널로 합쳐진 단일 스트림은, 나중에 알고리즘으로 화자를 가르려 해도 발화가 겹치는 구간이나 비슷한 음색에서 한계가 큽니다. 그래서 가능하면 녹음·수신 단계에서부터 채널을 분리해 저장해 두는 편이, 합쳐 받은 뒤 후처리로 떼어 내려 애쓰는 것보다 품질이 훨씬 높습니다. 전송 계층을 설계할 때 "어차피 두 트랙이 따로 흐른다"는 사실을 그냥 흘려보내지 말고, 받는 쪽 저장 구조까지 그 분리를 살려 두는 것이 좋습니다.

그렇다면 WebSocket은 언제 쓰나

WebRTC가 만능은 아닙니다. 서버와 서버 사이, 예컨대 음성 게이트웨이와 모델 백엔드를 잇는 구간처럼 네트워크가 안정적이고 경로가 통제된 곳에서는 WebSocket이 더 단순하고 충분합니다. 실제로 여러 실시간 음성 API가 서버 측 연동에 WebSocket 스트리밍을 제공합니다. 다만 어떤 API가 어떤 전송 방식을 지원하는지는 2026년 6월 시점의 공개 자료를 기준으로 한 이야기라, 연동 전에 각 벤더의 최신 문서를 확인해 두는 편이 안전합니다.

실무에서 자주 쓰는 패턴은 채널을 둘로 나누는 것입니다. 깨져도 빠른 게 중요한 오디오 비트는 WebRTC 미디어 트랙으로, 절대 누락되면 안 되는 제어 이벤트(끼어들기 신호, 발화 종료 표시, 도구 호출 결과 같은 메타데이터)는 신뢰성 있는 채널로 분리해 보냅니다. 미디어와 제어를 같은 파이프에 욱여넣지 않는 것만으로도 지연과 정합성을 동시에 잡기 쉬워집니다.

지터·패킷 손실에 무너지지 않게: 인프라 노하우

공용 인터넷은 패킷이 들쭉날쭉 도착하고(지터) 일부는 아예 사라집니다(손실). 전송 계층의 진짜 실력은 이 거친 환경에서 음성을 매끄럽게 유지하는 데서 드러납니다. 핵심 도구는 다음과 같습니다.

  • 지터버퍼: 들어온 패킷을 잠깐 모았다가 일정 간격으로 재생해 도착 시간의 들쭉날쭉함을 흡수합니다. 버퍼를 키우면 끊김은 줄지만 지연이 늘고, 줄이면 반대가 됩니다. 그래서 네트워크 상태에 맞춰 크기를 자동 조절하는 적응형 지터버퍼가 사실상 표준입니다.
  • 재전송(NACK): 빠진 패킷을 다시 요청합니다. 왕복 시간이 짧을 때만 효과가 있으므로, 늦게 도착할 바엔 포기하는 판단이 함께 필요합니다.
  • 손실 은닉(PLC): 사라진 짧은 구간을 직전 음성으로 그럴듯하게 메워, 작은 손실을 귀로는 못 느끼게 합니다.
  • 전진 오류 정정(FEC): 약간의 여분 데이터를 미리 실어 보내 재전송 없이 손실을 복구합니다. 대역을 더 쓰는 대신 지연을 늘리지 않습니다.
  • 적응 비트레이트: 대역이 좁아지면 음질을 낮춰서라도 끊김을 막습니다.

이 모든 장치의 공통 축은 결국 '지연과 품질의 맞교환'입니다. 보이스봇에서는 짧은 손실 은닉은 후하게, 지연을 키우는 큰 버퍼나 무한정 재전송은 보수적으로 가는 균형이 일반적입니다. 사람은 미세한 음질 저하보다 한 박자 늦은 응답을 훨씬 더 거슬려 하기 때문입니다.

전송 계층 선택에서 자주 무너지는 지점

지금까지의 논의를 실무에서 반복되는 실패 패턴으로 정리하면 이렇게 압축됩니다.

  • 브라우저 클라이언트를 RTP로 직접 붙이려다 막힙니다.
  • 오디오까지 TCP로 날라 헤드 오브 라인 블로킹을 자초합니다.
  • 미디어와 제어 이벤트를 한 채널에 욱여넣어 꼬입니다.

결국 전송 계층은 모델 뒤에 숨은 배경이 아니라, 음성 에이전트의 체감 품질을 처음부터 가르는 1급 설계 대상입니다.

댓글

이 블로그의 인기 게시물

STT 인식률 93%의 함정 — 왜 그 숫자는 콜봇 목표가 될 수 없는가

AI 보이스봇이 답답한 이유: Cascaded 구조 레이턴시 완전 분석

음성 토큰(Audio Token)이란? LLM이 소리를 이해하는 원리