음성 활동 감지인 VAD는 오디오 스트림에서 발화를 식별합니다. 음성 에이전트에서는 “누군가 말하고 있는가?”에 답하는 데 도움이 됩니다. 더 어려운 질문은 “말을 끝냈는가?”입니다.
통화자가 “제 주소는…”이라고 말한 뒤 건물 번호를 확인하려고 멈춥니다. 감지기가 무음을 정확하게 보고해도 에이전트는 잘못 판단해 말을 시작할 수 있습니다. 누구도 자신만만한 끼어들기를 원하지 않습니다.
대화형 에이전트를 만든다면 발화 경계가 필요한 곳에 VAD를 사용하고, 대화 차례를 주고받는 정책을 명시적으로 선택하세요. 각 요소의 관계, 독립 감지기가 유용한 곳, 통화를 맡기기 전에 테스트할 사항을 살펴보겠습니다.
음성 활동 감지의 원리
VAD는 짧은 오디오 구간을 처리하여 발화가 포함되어 있는지 추정합니다. 구현에 따라 이진 판단, 확률, 또는 그 판단을 모은 발화 타임스탬프 집합을 출력합니다.
단순한 에너지 임계값은 충분히 큰 소리를 발화로 취급합니다. 계산 비용은 낮지만 큰 소리는 문을 세게 닫는 소리일 수도 있습니다. 더 정교한 감지기는 음향 특성이나 신경망 모델로 발화와 다른 소리를 구분합니다. 현대 VAD는 음량 측정에만 국한되지 않습니다.
앱은 보통 감지기 주변에 로직을 추가합니다. 여러 발화 프레임을 확인한 뒤 구간을 시작하거나, 감지 전의 짧은 오디오 버퍼를 보관하거나, 잠깐의 무음을 기다린 뒤 구간을 닫을 수 있습니다. 이 로직은 사용자가 듣는 결과에 영향을 줍니다. 버퍼가 없으면 발화를 정확하게 감지해도 너무 늦어 단어의 시작을 놓칠 수 있습니다.
VAD는 단어를 전사하거나 특정 화자를 식별하거나 녹음의 잡음을 제거하지 않습니다. 이는 별도 작업입니다. TV 목소리를 발화로 정확하게 인식해도 통화자만 들어야 하는 에이전트에서는 잘못된 동작을 유발할 수 있습니다.
VAD, 엔드포인팅, 의미 기반 발화 차례 감지
이 용어들은 서로 다른 판단을 뜻합니다.
| 구성 요소 | 답하는 질문 | 고려할 한계 |
|---|---|---|
| 음성 활동 감지 | 이 오디오에 발화가 있는가? | 쉼만으로는 생각을 끝냈는지 거의 알 수 없습니다. |
| 무음 기반 엔드포인팅 | 차례를 끝내도 될 만큼 발화가 오래 멈췄는가? | 고정 타임아웃은 생각하는 쉼과 끝난 문장을 비슷하게 취급합니다. |
| 의미 기반 발화 차례 감지 | 오디오와 언어 맥락상 화자가 말을 끝냈는가? | 예측은 여전히 빠르거나 늦을 수 있어 앱에 복구 동작이 필요합니다. |
| 끼어들기 처리 | 발화가 시작되면 에이전트의 현재 응답을 멈춰야 하는가? | 재생 버퍼와 진행 중인 생성도 멈추거나 버려야 합니다. |
무음 기반 엔드포인터는 합리적인 출발점인 경우가 많습니다. 절충은 명확합니다. 짧은 타임아웃은 빨리 응답하지만 생각 중인 사람의 말을 끊을 위험이 있습니다. 긴 타임아웃은 여유를 주지만 완성된 답변 뒤에도 응답을 늦춥니다.
의미 기반 발화 차례 감지는 추가 맥락으로 이 경우들을 구별합니다. “제 이메일은…”과 “이게 전부예요, 감사합니다”는 뒤의 쉼이 같아도 기다리는 방식이 달라야 할 수 있습니다. 그래도 추정일 뿐이며 통화자가 절대 마음을 바꾸지 않는다고 가정할 근거는 아닙니다.
Cartesia의 Ink 2 발표는 음성 인식에 의미 기반 엔드포인팅을 통합한 이유를 설명합니다. 제품의 목표는 사람이 생각을 끝까지 말하고 적시에 응답을 받는 대화입니다. 발화 프레임 정확도만 최적화해서는 그런 경험을 만들 수 없습니다.
독립 VAD를 사용할 때
발화를 찾은 뒤 처리 방식을 정해야 한다면 독립 감지기가 유용합니다. 녹음의 발화 구간 표시, 발화 중 표시기, 자체 에이전트 파이프라인에 발화 시작 이벤트 제공 등이 예입니다. 로컬 감지는 해당 처리 단계를 기기 안에서 수행하게 할 수도 있습니다. 그렇다고 클라우드 연결 에이전트의 나머지 부분까지 비공개나 오프라인이 되지는 않습니다.
평가할 만한 두 구현은 py-webrtcvad를 통한 WebRTC VAD와 Silero VAD입니다.
| 구현 | 입력과 실행 환경 고려사항 | 앱에서 확인할 사항 |
|---|---|---|
| WebRTC VAD | Python 래퍼는 8, 16, 32, 48 kHz의 16비트 모노 PCM을 10, 20, 30 ms 프레임으로 받습니다. 네 가지 감지 강도 모드가 있습니다. | 강한 필터링이 작은 발화를 놓치는지, 수집 경로가 유효한 프레임을 제공하는지 확인하세요. |
| Silero VAD | PyTorch와 ONNX 옵션이 있는 신경망 감지기입니다. 프로젝트는 8 및 16 kHz 지원을 문서화합니다. | 대상 기기의 모델 및 런타임 비용, 청크 요구사항, 실제 오디오의 오탐을 확인하세요. |
형식 요구사항은 구현마다 다릅니다. WAV 헤더는 PCM 샘플이 아니며 MP3 패킷도 WebRTC VAD에 바로 전달할 프레임이 아닙니다. 입력에 필요하다면 감지 전에 디코딩하고 변환하세요. 브라우저 마이크의 기본 샘플레이트가 허용된다고 가정하지 말고 현재 구현 문서를 확인하세요.
어느 감지기도 완전한 대화 관리자는 아닙니다. 엔드포인팅, 끼어들기 처리, 통화자가 계속 말할 때 복구하는 방식이 여전히 필요합니다.
Ink의 내장 발화 차례 감지 사용
스트리밍 전사와 발화 경계가 함께 필요하다면 Cartesia의 Realtime Speech-to-Text (Auto) API가 둘 다 제공합니다. 이 경계를 위해 별도 VAD를 사용할 필요는 없습니다.
이벤트 수명 주기는 가능한 종료와 확정된 종료를 구분합니다.
| 이벤트 | 앱에서 처리할 사항 |
|---|---|
turn.start | 통화자가 발화를 시작했습니다. 활성 응답에 끼어들기 정책을 적용하세요. |
turn.update | 이 차례의 표시 또는 저장된 전사를 갱신하세요. |
turn.eager_end | 차례가 끝났을 수 있습니다. 추측에 기반한 응답 생성을 시작할 수 있습니다. |
turn.resume | 통화자가 말을 이어갔습니다. 잠정 종료에 기반한 작업을 취소하거나 버리세요. |
turn.end | 감지기가 차례 종료를 확정했습니다. 완성된 전사로 다음 처리를 진행하세요. |
예를 들어 “취소해야겠어요” 뒤의 잠정 종료 다음에 “첫 번째 말고 두 번째 예약을요”가 이어질 수 있습니다. 지연시간에 도움이 된다면 응답을 준비하되 종료가 확정될 때까지 재생은 보류하세요. 예약 취소처럼 결과가 중요한 동작에는 앱의 검증 및 확인 규칙을 적용하세요. 이른 종료 예측은 사용자의 승인이 아닙니다.
놓치기 쉬운 통합 세부 사항이 두 가지 있습니다. 첫째, 전사를 담는 이벤트는 해당 차례의 누적 전사를 포함합니다. 현재 차례의 텍스트를 교체하세요. 매 업데이트를 이어 붙이면 단어가 반복됩니다. 둘째, API는 무음을 포함한 연속 오디오를 기대합니다. 앞단 VAD로 무음 청크를 제거하지 마세요. 오디오가 없으면 통화자가 멈춘 증거가 아니라 추가 입력을 기다리는 상태로 처리합니다.
발화 차례 감지 문서는 임계값, 취소, 연결 종료 시 버퍼 이벤트 비우기를 설명합니다. 기본값에서 시작하고 녹음된 대화 실패 사례로 설정을 하나씩 바꾸세요.
감지기만이 아니라 대화 테스트
임계값을 고르기 전에 원하는 상호작용을 정하세요. 주소를 수집하는 접수 에이전트는 통화자가 찾아볼 시간을 줘야 합니다. 짧은 예·아니요 문답은 덜 기다려도 될 수 있습니다. 하나의 전역 무음 타임아웃으로 모든 요구를 표현할 수는 없습니다.
적절한 허가를 받아 수집한 녹음을 사용하고 에이전트가 실제 사용할 마이크나 전화 연결을 포함하세요. 분리된 발화 클립뿐 아니라 전체 대화를 들으세요.
| 상황 | 찾아야 할 실패 |
|---|---|
| 무음 뒤 작은 첫 음절 | 녹음이나 전사에서 단어의 시작이 사라집니다. |
| 주소 중간의 쉼 | 통화자가 끝내기 전에 에이전트가 답합니다. |
| 짧지만 완성된 답변 | 차례가 분명히 끝났는데도 에이전트가 기다립니다. |
| 에이전트가 말할 때 “아니요, 목요일로 할게요” | 수정 발화 위로 버퍼에 있는 오디오를 계속 재생합니다. |
| 배경 대화, 키보드 소음, 스피커 에코 | 잘못된 소리에 에이전트가 멈추거나 응답을 시작합니다. |
| 다양한 억양, 발화 속도, 망설임 | 테스트 작성자에게 맞는 설정이 다른 통화자의 말을 끊습니다. |
응답 지연과 함께 너무 이른 종료와 놓친 끼어들기를 추적하세요. 차례 종료 전의 지연을 LLM, 도구 호출, 음성 생성, 재생 시간과 분리하세요. VAD 타임아웃을 줄여도 느린 일정 조회가 빨라지지는 않습니다.
에이전트의 말이 끊기면 출력 경로 전체를 확인하세요. 텍스트 생성을 취소해도 클라이언트에 이미 쌓인 오디오가 지워지는 것은 아닙니다. “멈춰”라고 말한 통화자는 어느 서버 작업이 취소를 받았는지가 아니라 소리가 언제 멈추는지에 관심이 있습니다.
통합 발화 차례 감지를 시험하려면 Ink 브라우저 데모에서 문장 중간에 일부러 쉬어 보세요. 그다음 자신의 오디오 조건으로 Realtime STT 예제를 실행하세요. 유용한 테스트는 에이전트가 사용자의 말을 끝까지 듣고 준비되었을 때 응답하는지 확인하는 것입니다.