음성 비서는 침묵 속에서 설계된다
요약
음성 비서 시스템의 사용자 경험을 결정짓는 핵심 요소인 '응답 지연(latency)'과 이를 측정하기 위한 세부 지표들을 다룹니다. 단순한 모델 속도보다 서비스 간의 매끄러운 연결과 실시간 파이프라인 최적화의 중요성을 강조합니다.
핵심 포인트
- 음성 비서의 품질은 개별 모델 성능보다 대화 차례(Conversational Turn)의 매끄러움에 달려 있음
- 단순한 '첫 오디오 도달 시간' 대신 세분화된 지연 시간 지표 측정이 필요함
- STT, LLM, TTS 과정이 직렬적이지 않고 중첩되어 작동하는 반응형 시스템 설계가 중요함
- 사용자 경험을 위해 차례 결정, STT 최종화, LLM 토큰 생성 등 각 단계의 지연을 관리해야 함
음성 비서는 기술적으로는 정확할 수 있지만, 여전히 고장 난 것처럼 느껴질 수 있습니다.
실패는 종종 사용자가 말을 마친 직후에 시작됩니다. 극적인 일은 일어나지 않습니다. 그저 일시적인 멈춤(pause)이 있을 뿐입니다. 사용자가 시스템이 자신의 말을 들었는지 의구심을 가질 만큼 길지만, 각 서비스 대시보드에는 허용 가능한 결과로 보고될 만큼은 짧은 멈춤 말입니다.
그 멈춤이 바로 제품입니다.
사용자는 음성 인식 (Speech Recognition), 언어 모델 (Language Model), 도구 호출 (Tool Call), 그리고 음성 합성 (Speech Synthesis)을 별개의 서비스로 경험하지 않습니다. 그들은 하나의 대화 차례 (Conversational Turn)를 경험합니다. 만약 어떤 인계 (Handoff) 과정이라도 늦거나, 불확실하거나, 취소하기 어렵다면, 전체 상호작용은 대화라기보다 자동 응답 시스템 (Phone Tree)처럼 느껴지기 시작합니다.
따라서 유용한 질문은 "어떤 모델이 가장 빠른가?"가 아닙니다. 다음과 같습니다:
시스템이 얼마나 빨리 신뢰할 수 있고 말할 수 있는 응답을 시작할 수 있는가?
이 글은 기존의 음성 비서 아키텍처 가이드에서 그 아이디어를 발전시켰지만, 개발자가 프로덕션 파이프라인 (Production Pipeline)에서 측정하고, 계측하고, 변경할 수 있는 것에 초점을 맞춥니다.
이 가이드는 실시간 음성 모델과 음성 에이전트 (Voice-agent) 시스템에 집중하는 Smallest.ai에 의해 게시되었습니다.
네 개의 서비스가 아닌, 한 번의 차례를 측정하라
전형적인 계단식 비서 (Cascaded Assistant)는 단순해 보입니다:
마이크 (Microphone)
→ 스트리밍 음성-텍스트 변환 (Streaming Speech-to-Text, STT)
→ 차례 결정 (Turn Decision)
→ 언어 모델 (Language Model) 및 선택적 도구 (Optional Tools)
→ 안정적인 텍스트 버퍼 (Stable Text Buffer)
→ 스트리밍 텍스트-음성 변환 (Streaming Text-to-Speech, TTS)
→ 중단 가능한 재생 (Interruptible Playback)
모든 화살표를 깔끔하고 직렬적인 경계로 취급할 때 다이어그램은 오해의 소지가 생깁니다. 반응형 시스템 (Responsive System)에서는 유용한 작업들이 중첩됩니다. 사용자가 말하는 동안 오디오가 전사 (Transcribed)됩니다. 모델은 차례가 확정된 후, 모든 전사 결과물이 확정되기 전이라도 시작될 수 있습니다. TTS는 전체 답변을 기다리는 대신, 안정적이고 말할 수 있는 절 (Clause)이 존재할 때 시작할 수 있습니다.
이 모든 것을 단 하나의 모호한 "첫 오디오 도달 시간 (Time to First Audio)" 지표로 압축하지 마십시오. 경계들을 별도로 기록하십시오:
차례 결정 지연 (Turn-decision delay): 사용자의 마지막 음성 프레임부터 시스템이 차례를 확정하는 시점까지.
STT 최종화 지연 (STT finalization delay): 다운스트림(downstream)으로 보내기에 안전한 전사(transcript)를 생성하는 데 필요한 시간.
LLM 첫 토큰 생성 시간 (LLM time to first token, TTFT): 모델 요청부터 첫 번째 토큰이 생성될 때까지의 시간.
첫 발화 가능 청크까지의 시간 (Time to first speakable chunk): 모델 요청부터 TTS가 안전하게 렌더링할 수 있는 첫 번째 안정적인 절(clause)이 나올 때까지의 시간.
TTS 첫 오디오 생성 시간 (TTS time to first audio): 합성(synthesis) 요청부터 재생 가능한 첫 번째 오디오 청크가 나올 때까지의 시간.
차례 종료 후 재생까지 (End-of-turn-to-playback): 사용자의 마지막 음성 프레임부터 클라이언트에서 실제로 오디오가 시작될 때까지의 시간.
마지막 측정값은 사용자가 체감하는 결과입니다. 나머지 지표들은 왜 그런 결과가 발생했는지를 설명합니다.
차례 감지 (Turn detection)는 VAD와 동일하지 않습니다.
음성 활동 감지 (Voice activity detection, VAD)는 좁은 범위의 질문에 답합니다: 이 오디오 프레임에 음성이 포함되어 있는가?
차례 감지 (Turn detection)는 더 어려운 질문에 답합니다: 화자가 생각을 마쳤는가?
VAD는 증거를 제공할 수 있지만, 침묵만으로는 충분하지 않습니다. 실제 서비스용 차례 감지기(turn detector)는 다음과 같은 요소들도 사용할 수 있습니다:
- 확정된(finalized) 및 중간(interim) 전사 타이밍;
- 신뢰도(confidence) 또는 전사 안정성;
- 문장 부호 또는 의미론적 완결성;
- 계속 이어질 수 있는 전화번호와 같은 도메인 특화 패턴;
- 사용자의 말하기 속도 및 최근의 일시 정지 동작;
- 현재 워크플로우에서 중단하는 비용과 기다리는 비용의 비교.
이 구분이 중요한 이유는 고정된 침묵 임계값(silence threshold)이 서로 상반된 실패 모드(failure modes)를 만들기 때문입니다. 너무 빨리 확정하면 어시스턴트가 문장 중간에 잠시 멈춘 사용자의 말을 끊어버립니다. 너무 오래 기다리면 모든 차례가 머뭇거리는 것처럼 느껴집니다.
엔드포인팅 (Endpointing)은 여전히 휴리스틱(heuristic)에 의존합니다. 배경 소음은 신뢰할 수 있는 침묵 감지를 방해할 수 있는 반면, 전사 기반의 간격 감지(transcript-based gap detection)는 다르게 동작하며 일부 발화에는 더 유용할 수 있습니다. 올바른 임계값은 업계 공통의 상수가 아닙니다. 배포 환경의 실제 오디오를 바탕으로 튜닝하십시오.
STT 정확도는 결과적인 오류에 관한 것입니다.
단어 오류율 (Word error rate, WER)은 유용하지만, 어시스턴트에 대한 보편적인 합격/불합격 점수로 취급되어서는 안 됩니다.
잘못된 채움말(filler word)은 다운스트림에 아무런 영향을 미치지 않을 수도 있습니다.
계좌 번호의 숫자 하나가 틀리거나, 성(surname)의 철자가 잘못되거나, 부정어가 뒤바뀌는 것만으로도 전체 동작이 바뀔 수 있습니다. 전통적인 단어 오류율 (WER)은 의미와 가독성에 미치는 영향이 매우 다른 오류들에 대해 동일한 가중치를 부여하므로, 엔티티 수준 (entity-level) 및 태스크 수준 (task-level) 평가와 병행되어야 합니다.
음성 에이전트의 경우, 최소한 다음 세 가지 계층을 평가해야 합니다:
- 전사 품질 (Transcription quality): WER 또는 기타 적절한 자동 음성 인식 (ASR) 지표.
- 엔티티 정확도 (Entity accuracy): 이름, 날짜, 금액, 식별자, 주소 및 도메인 전문 용어.
- 태스크 성공 여부 (Task success): 다운스트림 시스템이 의도 (intent)를 이해하고 올바른 동작을 수행했는지 여부.
사용자가 실제로 생성할 오디오 환경에서 테스트하십시오: 소음이 있는 방, 전화기 코덱 (phone codecs), 약한 연결, 억양, 망설임, 그리고 겹치는 음성 등이 포함됩니다. 깨끗한 스튜디오 녹음은 배포 테스트 세트 (deployment test set)를 대신할 수 없습니다.
스트리밍 ASR은 방출 지연 (emission delay)을 줄일 수 있지만, 불안정한 부분 가설 (partial hypotheses)을 도입합니다. FastEmit와 같은 연구는 지연 시간 (latency)과 인식 품질이 함께 평가되어야 함을 보여줍니다. 해당 연구에서 측정된 이점은 테스트된 모델과 데이터셋에 국한된 것이며, 모든 스트리밍 구현에 적용되는 것은 아닙니다.
첫 번째 토큰이 곧 음성 답변인 것은 아닙니다.
LLM의 첫 토큰 생성 시간 (TTFT)은 중요하지만, 그것이 모델 단계의 끝은 아닙니다.
모델이 다음과 같이 출력한다고 가정해 봅시다:
물론이죠 — 제가...
첫 번째 토큰이 도착했지만, 어시스턴트는 여전히 유용한 말을 할 수 있는 상태가 아닙니다. TTS 또한 나중에 어색하거나 틀리게 될 서두를 합성하지 않도록 안정적인 절 (clause)이 나올 때까지 기다려야 할 수도 있습니다.
더 나은 음성 프롬프트는 답변을 앞부분에 배치합니다:
예약이 목요일 오후 3시로 확정되었습니다.
원하신다면 알림을 보내드릴 수도 있습니다.
첫 번째 문장이 완전하고, 유용하며, 독립적으로 발화 가능합니다.
이는 추적할 가치가 있는 또 다른 지표를 만들어냅니다: 첫 번째 발화 가능 청크까지의 시간 (time to first speakable chunk). 여기에는 모델의 TTFT와 안전한 합성 경계 (synthesis boundary)를 축적하는 데 필요한 시간이 포함됩니다.
단순한 절 버퍼 (clause buffer)는 다음과 같을 수 있습니다:
const boundary = /[.!?]\s$|[,;:)]\s$/;
let pending = "";
function onModelToken(token: string) {
pending += token;
const enoughText = pending.trim().length >= 24;
const hasBoundary = boundary.test(pending);
if (enoughText && hasBoundary) {
tts.enqueue(pending);
pending = "";
}
}
function onModelComplete() {
if (pending.trim()) tts.enqueue(pending);
}
이는 의도적으로 단순하게 작성되었습니다. 실제 서비스용 버퍼 (production buffer)는 약어, 숫자, 마크업 (markup), 발음 힌트, 언어별 문장 부호, 최대 대기 시간, 그리고 이미 대기열에 추가된 음성을 취소할 수 있는지 여부도 고려해야 합니다.
도구 지연 (Tool latency)은 임계 경로 (critical path)를 차단할 때만 문제가 됩니다.
도구 호출 (Tool calls)은 흔히 가산적인 지연 (additive delay)으로 묘사됩니다. 즉, 300ms의 조회 (lookup)가 턴 (turn)에 정확히 300ms를 추가한다는 식입니다.
이는 조회가 직렬 임계 경로 (serial critical path)에 있을 때만 사실입니다.
일부 작업은 다음과 같은 방법을 통해 숨기거나 줄일 수 있습니다:
- 세션이 시작된 후 발생 가능성이 높은 컨텍스트 (context)를 미리 가져오기 (prefetching);
- 명확한 신선도 정책 (freshness policy)을 가진 결과 캐싱 (caching);
- 독립적인 도구들을 병렬 (parallel)로 실행하기;
- 느린 작업이 계속되는 동안 안전한 구두 확인 (verbal acknowledgement) 시작하기;
- 모델의 결정이 불필요할 때 결정론적 라우팅 (deterministic routing) 사용하기;
- 사용자가 방향을 바꿀 때 오래된 작업 취소하기.
임의적인 지연을 숨기기 위해 채움말 (filler speech)을 사용하지 마세요. "실시간 재고를 확인해 보겠습니다"와 같은 확인 문구는 실제 진행 상황을 전달하고 근거 없는 약속을 하지 않을 때에만 유용합니다.
모든 도구 호출을 대기열 시간 (queue time), 네트워크 시간 (network time), 서버 시간 (server time), 결과 크기 (result size), 캐시 상태 (cache status), 재시도 횟수 (retry count), 그리고 첫 번째 발화 가능한 청크 (speakable chunk)를 차단했는지 여부와 함께 추적하세요. 마지막 필드는 단순히 지속 시간 (duration)만 확인하는 것보다 더 많은 정보를 제공합니다.
스트리밍 (Streaming)은 제어된 중첩 (controlled overlap)입니다.
"모든 단계를 스트리밍하라"는 말은 매력적으로 들리지만 너무 절대적입니다.
부분적인 출력 (Partial output)은 그것이 유용하고 안전하게 되돌릴 수 있을 때만 가치가 있습니다. 어떤 도구들은 원자적 결과 (atomic results)를 반환합니다. 부분적인 전사 (transcripts)는 변경될 수 있습니다. 성급한 TTS는 모델이 수정했을 법한 텍스트를 말해버릴 수 있습니다. 추측 (Speculation)은 비용을 증가시키고 취소를 더 어렵게 만들 수도 있습니다.
더 나은 규칙은 다음과 같습니다:
부분적인 출력 (partial output)이 유용할 때 스트리밍(Stream)하고, 오류를 제어하거나 되돌릴 수 있을 때만 작업을 중첩(overlap)하십시오.
점진적 TTS (Incremental TTS) 연구는 이후의 세그먼트가 여전히 생성되는 동안 부분적인 텍스트로부터 합성이 어떻게 시작될 수 있는지를 보여줍니다. Prefix-to-prefix TTS 연구는 해당 아키텍처(architecture)에 대한 유용한 증거가 되지만, 이것이 모든 모델, 문장, 장치 또는 네트워크에 대해 보편적인 밀리초(millisecond) 단위의 절감을 정당화하지는 않습니다.
저지연 (low-latency) 음성 시스템 뒤에 숨겨진 엔지니어링 작업은 추론 (inference) 그 이상으로 확장됩니다. 미디어 전송 (Media transport), 지터 (jitter), 패킷 손실 (packet loss), 세션 소유권 (session ownership), 라우팅 (routing), WebRTC 동작, 그리고 인프라 배치 (infrastructure placement) 모두가 일시 정지 (pause)에 영향을 미치며 동일한 설계 논의에 포함되어야 합니다.
명시적인 지연 시간 예산 (latency budget) 구축하기
지연 시간 예산은 출시 후에 만들어지는 차트가 아니라 설계 제약 조건 (design constraint)입니다. 발화 종료 후 재생 (end-of-turn-to-playback) 목표치로 시작한 다음, 임계 경로 (critical path) 상의 단계들에 임시 제한을 할당하십시오.
다음은 의도적으로 공격적으로 설정한 800 ms 예산의 예시입니다. 이는 계획을 위한 예시일 뿐, 업계 벤치마크 (benchmark)가 아닙니다:
단계
예시 예산
발화 결정 (Turn decision)
150 ms
전사 안정화 (Transcript stabilization)
100 ms
첫 번째 발화 가능한 모델 청크 (First speakable model chunk)
300 ms
첫 번째 재생 가능한 TTS 오디오 (First playable TTS audio)
150 ms
전송 및 클라이언트 버퍼링 (Transport and client buffering)
100 ms
합계
800 ms
할당량은 제품에 따라 변경될 것입니다. 핸즈프리(hands-free) 명령은 속도를 우선시할 수 있습니다. 의료 접수 흐름(medical intake flow)은 화자를 방해하지 않기 위해 더 긴 대기 시간을 허용할 수 있습니다. 도구 사용이 많은 트랜잭션(tool-heavy transaction)은 최종 답변 전에 확인(acknowledgement)이 필요할 수 있습니다.
평균값보다는 분포를 측정하십시오. 최소한 다음 항목별로 p50, p95, p99를 보고해야 합니다:
상호작용 유형 (interaction type);
지리적 위치 및 네트워크 (geography and network);
언어 (language);
장치 또는 전화 서비스 제공업체 (device or telephony provider);
도구 미사용 대 도구 의존 턴 (tool-free versus tool-dependent turns);
성공, 중단, 취소 및 재시도된 턴 (successful, interrupted, cancelled, and retried turns).
수용 가능한 p50이 고통스러운 p95를 숨길 수 있습니다.
전체 턴을 계측(Instrument)하기
다음 TypeScript 예제는 구현을 특정 STT, 모델 또는 TTS 제공업체에 종속시키지 않고 이벤트 경계(event boundaries)를 기록합니다:
const marks = new Map();
function mark(name: string, at = performance.now()) {
marks.set(name, at);
}
function duration(start: string, end: string) {
const a = marks.get(start);
const b = marks.get(end);
return a === undefined || b === undefined ? undefined : b - a;
}
function voiceTurnMetrics() {
return {
turnDecisionMs: duration("speech_last_frame", "turn_committed"),
transcriptReadyMs: duration("turn_committed", "stt_final"),
llmTtftMs: duration("llm_started", "llm_first_token"),
firstSpeakableMs: duration("llm_started", "first_speakable_chunk"),
ttsFirstAudioMs: duration("tts_started", "tts_first_audio"),
clientBufferMs: duration("tts_first_audio", "playback_started"),
endToEndMs: duration("speech_last_frame", "playback_started"),
};
}
Call mark() from the actual callbacks in the pipeline:
mark("speech_last_frame", vad.lastSpeechTimestamp());
mark("turn_committed");
mark("stt_final");
mark("llm_started");
mark("llm_first_token");
mark("first_speakable_chunk");
mark("tts_started");
mark("tts_first_audio");
mark("playback_started");
Use one trace ID across the browser or phone gateway, STT, orchestration layer, tools, model, TTS, and playback client. Without cross-service correlation, teams often optimize the service with the most visible dashboard rather than the stage responsible for the user's wait.
만약 관리형 스택(managed stack)과 사용자 지정 파이프라인(custom pipeline)을 비교한다면, Smallest.ai의 음성 에이전트 플랫폼은 평가할 수 있는 통합 구현체 중 하나입니다. 단순히 통합된 스택이라고 해서 자동으로 낮은 지연 시간을 가진다고 가정하기보다는, 동일한 이벤트 경계와 p50, p95, 그리고 p99 측정값을 적용해야 합니다.
바지인(Barge-in)은 이전 턴을 취소해야 함
풀-듀플렉스(full-duplex) 어시스턴트의 경우, 인바운드 오디오 캡처와 음성 감지는 일반적으로 에이전트가 말하는 동안에도 활성화 상태를 유지합니다. 새로운 사용자 음성이 확인되면, 시스템은 이전 응답을 현재 진행 중인 것으로 취급하는 것을 중단해야 합니다.
제어 경로는 다음과 유사할 수 있습니다:
async function onUserSpeechStarted() {
generation.abort();
await tts.cancel();
playback.stopAndFlush();
tools.cancelNonReusableWork();
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기