Capstone 03 — 실시간 음성 비서(Real-Time Voice Assistant) — 음성 인식에서 LLM, 음성 합성까지(ASR to LLM to TTS)

제대로 느껴지는 음성 에이전트(voice agent)는 종단 간 지연(end-to-end latency)이 800ms 미만이고, 사용자가 말을 멈춘 시점을 정확히 알며, 끼어들기(barge-in)를 자연스럽게 처리하고, 도구를 호출하는 중에도 말이 멈칫거리지 않아야 합니다. Retell, Vapi, LiveKit Agents, Pipecat은 2026년 시점에 모두 이 기준을 충족합니다. 구조는 동일합니다. 스트리밍 음성 인식(streaming ASR), 발화 종료 감지기(turn detector), 스트리밍 LLM, 스트리밍 음성 합성(streaming TTS)을 WebRTC로 연결하고, 매 단계(hop)마다 공격적인 지연 예산(latency budget)을 둡니다. 이 캡스톤(capstone)에서는 그러한 파이프라인을 직접 만들고, 단어 오류율(Word Error Rate; WER), 평균 의견 점수(Mean Opinion Score; MOS), 잘못된 끊김 비율(false-cutoff rate)을 측정한 뒤, 패킷 손실(packet loss) 환경에서 실행해 봅니다.

유형: Capstone 언어: Python (에이전트 + 파이프라인), TypeScript (웹 클라이언트) 선수 지식: Phase 6 (음성과 오디오; speech and audio), Phase 7 (트랜스포머; transformers), Phase 11 (LLM 엔지니어링), Phase 13 (도구), Phase 14 (에이전트), Phase 17 (인프라) 활용되는 Phase: P6 · P7 · P11 · P13 · P14 · P17 소요 시간: 약 30시간

문제

음성은 2025-2026년에 AI 사용자 경험(UX) 중에서도 가장 빠르게 진화한 영역입니다. 기술 상한선은 분기마다 낮아졌습니다. OpenAI Realtime API, Gemini 2.5 Live, Cartesia Sonic-2, ElevenLabs Flash v3, LiveKit Agents 1.0, Pipecat 0.0.70은 모두 첫 오디오가 나오기까지의 지연(first-audio-out)을 800ms 이하로 끌어내는 일을 현실적인 목표로 만들었습니다. 그러나 기준은 지연 시간(latency)만이 아닙니다. 진짜 잣대는 상호작용의 느낌입니다. 사용자의 말을 자르지 않고, 에이전트도 끊기지 않으며, 문장 중간에서 발생한 끼어들기를 매끄럽게 회복하고, 대화 중 도구를 호출해도 오디오가 멈추지 않으며, 흔들리는 모바일 네트워크에서도 견뎌야 합니다.

세 번의 REST 호출(REST call)을 단순히 이어 붙여서는 이 수준에 도달할 수 없습니다. 아키텍처(architecture)는 처음부터 끝까지 파이프라인 형태로 스트리밍(pipelined streaming)되어야 합니다. 일단 그런 파이프라인을 만들고 나면 실패 양상(failure mode)이 비로소 눈에 들어옵니다. 전화 오디오에 맞춰진 음성 활동 감지기(Voice Activity Detector; VAD)가 배경의 TV 소리에 잘못 반응하거나, 발화 종료 감지기(turn-detector)가 결코 오지 않을 구두점을 기다리거나, 음성 합성기가 출력 전에 400ms 동안 버퍼링(buffering)하는 식의 문제가 그것입니다. 이 캡스톤의 목표는 부하 상황에서 이런 문제를 하나씩 잡아 가며, 지연과 품질에 대한 보고서(latency-and-quality report)를 공개하는 것입니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.실시간 음성 비서(real-time voice assistant)에서 '첫 오디오 출력 지연(first-audio-out latency)'은 무엇을 측정하나요?

2.음성 활동 감지기(VAD) 외에 발화 종료 감지기(turn detector)가 추가로 필요한 이유는 무엇인가요?

0/2 답변 완료

개념

파이프라인은 다섯 단계의 스트리밍 단계(streaming stage)로 구성됩니다. 오디오 입력(audio in) — 브라우저나 공중 전화망(Public Switched Telephone Network; PSTN)에서 WebRTC로 들어오는 음성, 음성 인식(ASR) — Deepgram Nova-3 또는 faster-whisper가 만들어 내는 스트리밍 부분 전사(streaming partial transcripts), 발화 종료 감지(turn detection) — VAD와 더불어 부분 전사를 읽고 완결 신호(completion cue)를 판단하는 작은 발화 종료 감지 모델(turn-detector model), LLM — 발화가 끝났다고 판단된 직후부터 토큰을 스트리밍, 음성 합성(TTS) — 첫 LLM 토큰이 나온 시점으로부터 약 200ms 안에 오디오를 스트리밍으로 내보내는 단계입니다.

가로지르는 세 가지 핵심 관심사(cross-cutting concern)가 있습니다. 첫째는 끼어들기(barge-in)입니다. 에이전트가 말하고 있는 도중 사용자가 새로 말을 시작하면, 음성 합성을 즉시 취소(cancel)하고 음성 인식이 곧바로 다시 활성화되어야 합니다. 둘째는 도구 사용(tool use)입니다. 대화 중간에 일어나는 함수 호출(function call; 예: 날씨, 캘린더)은 오디오를 멈추지 않도록 별도의 부수 채널(side channel)에서 실행되어야 합니다. 지연이 300ms를 넘으면 에이전트는 "잠시만요..." 같은 응답 토큰(acknowledgement token)을 먼저 흘려보내 침묵을 피합니다. 셋째는 역압(backpressure)입니다. 패킷 손실 상황에서는 부분 전사를 보류하고, VAD는 발화 게이트 임계값(speech-gate threshold)을 높이며, 에이전트는 아직 확인되지 않은 메시지 위에 덮어 말하지 않도록 합니다.

측정 기준은 정량적입니다. 15dB 신호 대 잡음비(Signal-to-Noise Ratio; SNR)의 Hamming VAD 벤치마크(Hamming VAD benchmark)에서 WER 8% 미만, 100개의 측정 통화(call)에서 첫 오디오 출력 지연 50백분위(p50)가 800ms 미만, 잘못된 끊김 비율(false-cutoff rate) 3% 미만, 음성 합성의 MOS 4.2 초과, 단일 g5.xlarge 인스턴스에서 50건의 동시 통화(concurrent calls)를 처리하는 것입니다. 이 숫자들이 곧 산출물입니다.

아키텍처

browser / Twilio PSTN
        |
        v
   WebRTC / SIP edge
        |
        v
  LiveKit Agents 1.0  (or Pipecat 0.0.70)
        |
   +----+--------------+--------------+-----------------+
   |                   |              |                 |
   v                   v              v                 v
  ASR              VAD v5         turn-detector     side-channel
(Deepgram         (Silero)          (LiveKit)        tools
 Nova-3 /         speech-gate    completion score    (weather,
 Whisper-v3)      per 20ms        on partials        calendar)
   |                   |              |
   +--------+----------+--------------+
            v
        LLM (streaming)
     GPT-4o-realtime / Gemini 2.5 Flash /
     cascaded Claude Haiku 4.5
            |
            v
        TTS streaming
     Cartesia Sonic-2 / ElevenLabs Flash v3
            |
            v
     audio back to caller
            |
            v
   OpenTelemetry voice traces -> Langfuse

스택

  • 전송 계층(transport): LiveKit Agents 1.0(WebRTC)과 Twilio 공중 전화망(PSTN) 게이트웨이의 조합, 대안 프레임워크로 Pipecat 0.0.70
  • 음성 인식(ASR): Deepgram Nova-3(스트리밍, 첫 부분 전사까지 300ms 미만) 또는 직접 호스팅하는 faster-whisper Whisper-v3-turbo
  • 음성 활동 감지(VAD): Silero VAD v5와 함께, 부분 전사를 읽는 작은 트랜스포머(transformer) 기반 LiveKit 발화 종료 감지기
  • LLM: 강한 통합(tight integration)을 위한 OpenAI GPT-4o-realtime, Gemini 2.5 Flash Live, 또는 음성 경로(audio path)를 분리한 단계적(cascaded) 구성의 Claude Haiku 4.5(스트리밍 생성)
  • 음성 합성(TTS): 첫 바이트(first-byte) 지연이 가장 짧은 Cartesia Sonic-2, ElevenLabs Flash v3, 또는 자체 호스팅(self-host)용 오픈 소스 Orpheus
  • 도구(tools): 날씨, 캘린더, 예약을 위한 FastMCP 부수 채널. 도구 응답이 300ms를 넘으면 에이전트가 먼저 응답 필러(filler)를 흘려보냄
  • 관측성(observability): OpenTelemetry 음성 스팬(voice span), 오디오 재생이 가능한 Langfuse 음성 추적(voice traces)
  • 배포(deployment): 자체 호스팅한 Whisper와 Orpheus를 위한 단일 g5.xlarge(VRAM 24GB) 인스턴스, 가장 낮은 지연이 필요할 때는 호스팅 API 사용

만들어보기

  1. WebRTC 세션. LiveKit 룸(room)을 띄우고, 마이크 오디오를 스트리밍하는 웹 클라이언트를 함께 구성합니다. 서버 측에서는 같은 룸에 참여하는 에이전트 워커(agent worker)를 붙입니다.

  2. 음성 인식 스트리밍. 20ms 단위의 PCM 프레임(PCM frame)을 Deepgram Nova-3 또는 GPU에서 동작하는 faster-whisper로 보냅니다. 부분 전사(partial transcript)와 최종 전사(final transcript)를 구독하고, 부분 전사별 지연을 기록합니다.

  3. VAD와 발화 종료 감지기. 프레임 스트림 위에서 Silero VAD v5를 실행합니다. 발화 종료(speech-end) 이벤트가 발생하면 가장 최근의 부분 전사에 대해 LiveKit 발화 종료 감지기를 한 번 더 실행합니다. VAD가 500ms 이상 침묵을 보고하고 발화 종료 점수(completion score)가 0.6을 넘을 때만 "발화 종료"로 확정(commit)합니다.

  4. LLM 스트림. 발화 종료가 확정된 순간 누적된 대화 이력과 최종 전사를 함께 묶어 LLM을 호출합니다. 응답 토큰(token)을 스트리밍으로 받고, 첫 토큰이 도착하는 즉시 음성 합성으로 인계(hand off)합니다.

  5. TTS 스트림. Cartesia Sonic-2가 오디오 청크(audio chunk)를 스트리밍으로 되돌려 보냅니다. 첫 청크는 첫 LLM 토큰이 도착한 시점으로부터 200ms 이내에 서버를 떠나야 합니다. 청크는 LiveKit 룸으로 송출되고, 클라이언트는 WebRTC 지터 버퍼(jitter buffer)를 통해 재생합니다.

  6. 끼어들기. TTS가 재생되는 동안 VAD가 새로운 사용자 음성을 감지하면, TTS 스트림을 즉시 취소하고, 남아 있는 LLM 출력을 폐기하며, 음성 인식을 다시 준비합니다. 이때 tts_canceled 스팬을 발행해 추적할 수 있게 합니다.

  7. 도구 부수 채널. 날씨와 캘린더를 함수 호출(function-calling) 도구로 등록합니다. 도구가 호출되면 동시에 실행하고, 300ms 안에 응답이 돌아오지 않으면 LLM이 "잠시만요, 확인해볼게요" 같은 응답 필러를 먼저 내보내게 합니다. 도구가 결과를 반환하면 답변을 이어서 합성합니다.

  8. 평가 하니스(eval harness). 100건의 통화를 녹음합니다. 사전에 보관해 둔(held-out) 전사를 기준으로 WER을, 사용자가 문장 중간이었는데 TTS가 취소된 비율로 잘못된 끊김 비율을, 첫 오디오 출력의 50백분위 지연을, 사람 평가 또는 자동화된 음성 품질 추정 모델(Non-Intrusive Speech Quality Assessment; NISQA)을 통한 MOS를, 그리고 패킷 3%를 인위적으로 떨어뜨린 지터-손실 테스트(jitter-loss test)를 함께 계산합니다.

  9. 부하 테스트(load test). 합성 통화 발생기(synthetic caller)로 단일 g5.xlarge에서 50건의 동시 통화를 구동하고, 지속 가능한 첫 오디오 출력의 95백분위(p95) 지연을 측정합니다.

사용해보기

caller: "what is the weather in tokyo tomorrow"
[asr  ] partial @280ms: "what is the"
[asr  ] partial @540ms: "what is the weather"
[turn ] completion score 0.82 at @820ms; commit
[llm  ] first token @960ms
[tool ] weather.tokyo tomorrow -> 68/52 partly cloudy @1140ms
[tts  ] first audio-out @1040ms: "Tokyo tomorrow will be partly cloudy..."
turn latency: 1040ms user-stop -> audio-out

제출하기

제출 산출물은 outputs/skill-voice-agent.md입니다. 도메인(고객 지원, 일정 예약, 키오스크)이 주어지면, 측정 기준에 맞도록 조율된 ASR/VAD/LLM/TTS 파이프라인을 갖춘 LiveKit 에이전트를 띄웁니다. 평가 루브릭(rubric)은 다음과 같습니다.

가중치평가 항목측정 방법
25종단 간 지연100건의 녹음 통화에서 첫 오디오 출력 50백분위가 800ms 미만
20발화 전환(turn-taking) 품질Hamming VAD 벤치마크에서 잘못된 끊김 비율 3% 미만
20도구 사용 정확성대화 중 도구 호출이 오디오를 멈추지 않고 올바른 데이터를 반환
20패킷 손실 환경에서의 신뢰성패킷 3% 손실을 주입했을 때 WER과 발화 전환 안정성 유지
15평가 하니스 완성도공개된 설정(config)으로 재현 가능한 측정
100

연습문제

  1. (쉬움) Deepgram Nova-3를 g5.xlarge에서 동작하는 faster-whisper v3 turbo로 교체합니다. 지연과 WER 차이를 측정하고, CPU와 GPU 선택이 어느 지점에서 결정적인 영향을 주는지 식별합니다.

  2. (중간) 끼어들기 중재 정책(interruption-arbitration policy)을 추가합니다. 도구 호출 중 사용자가 끼어들었을 때 에이전트는 어떻게 행동해야 할까요? 세 가지 정책(즉시 취소(hard cancel), 도구 완료 후 중단(finish-tool-then-stop), 다음 발화로 큐잉(queue next turn))을 비교합니다.

  3. (중간) 적대적 발화 종료 감지(adversarial turn-detector) 테스트를 수행합니다. 사용자가 문장 중간에 긴 정적을 두도록 만들고, 900ms를 넘지 않으면서 잘못된 끊김 비율을 최소화하도록 VAD 침묵 임계값과 발화 종료 점수 임계값을 조정합니다.

  4. (어려움) 동일한 에이전트를 Twilio를 통해 공중 전화망(PSTN)에 배포합니다. PSTN의 첫 오디오 출력 지연을 WebRTC와 비교하고, 지터 버퍼와 코덱(codec) 차이를 설명합니다.

  5. (어려움) 비영어권 언어(일본어, 스페인어)에 대한 음성 활동 감지를 추가합니다. Silero VAD v5의 잘못된 트리거 비율(false-trigger rate)을 언어별 미세 조정(language-specific fine-tune) 모델과 비교 측정합니다.

핵심 용어

용어흔한 설명실제 의미
발화 종료 감지(turn detection)"발화 끝(end of utterance)"VAD의 침묵 신호와 부분 전사를 함께 보고 사용자가 말을 마쳤는지 판별하는 분류기(classifier)이다
끼어들기(barge-in)"끼어들기 처리(interruption handling)"VAD가 새로운 사용자 음성을 감지했을 때 재생 중인 음성 합성을 취소하는 것이다
첫 오디오 출력(first-audio-out)"지연(latency)"사용자가 말을 멈춘 시점부터 첫 오디오 패킷이 서버를 떠날 때까지의 시간이다
VAD(음성 활동 감지)"발화 게이트(speech gate)"오디오 프레임을 발화와 침묵으로 분류하는 모델로, 2026년 표준은 Silero VAD v5이다
지터 버퍼(jitter buffer)"오디오 평활화(audio smoothing)"네트워크 변동을 흡수하기 위해 패킷을 잠시 보관하는 클라이언트 측 버퍼이다
응답 필러(filler)"응답 토큰(acknowledgment token)"도구가 느릴 때 침묵을 피하려고 에이전트가 미리 내보내는 짧은 문구이다
MOS(평균 의견 점수)"Mean opinion score"사람이 지각하는 음성 품질 점수이며, NISQA는 이를 자동화한 대체 지표(proxy)이다

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

voice-agent

Build a real-time voice agent with sub-800ms first-audio-out, barge-in handling, and mid-conversation tool use.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.400ms가 걸리는 도구 호출(tool call) 중에 에이전트는 침묵을 피해야 합니다. 응답 필러(filler) 메커니즘은 어떻게 작동하나요?

2.에이전트가 말하는 도중 사용자가 새로 말하기 시작합니다(끼어들기; barge-in). 파이프라인은 즉시 무엇을 해야 하나요?

3.3% 패킷 손실(packet loss) 환경에서 파이프라인은 단어 오류율(WER)과 발화 전환 안정성을 유지해야 합니다. 어떤 역압(backpressure) 메커니즘이 도움이 되나요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다