음성 사서함 감지(Voicemail Detection)는 분류기입니다. 두 가지 오류 유형에 대한 계획이 필요합니다.
요약
음성 에이전트를 구축할 때, 특히 아웃바운드 캠페인의 경우 음성 사서함 감지(Voicemail Detection)가 핵심적인 분류기 역할을 합니다. 이 시스템은 '사람인지 기계인지'를 판단하며, 오분류 시 발생하는 두 가지 오류 유형(사람을 기계로, 기계를 사람으로)의 비용 분석이 중요합니다. 따라서 완벽한 감지에 집중하기보다, 어떤 실수가 더 저렴하고 생존 가능한지 설계하는 것이 핵심입니다.
핵심 포인트
- 음성 에이전트 구축 시 음성 사서함 감지는 필수적인 분류기이다.
- 오분류 유형(사람->기계 / 기계->사람)별 비용을 분석하여 시스템을 설계해야 한다.
- 에이전트는 상대방이 먼저 말하도록 유도하고, 도입부 발화를 짧게 유지하는 것이 좋다.
제가 구축하는 음성 에이전트 대부분은 전화를 받습니다. 즉, 누군가 비즈니스 번호로 전화를 걸었기 때문에 사람이 통화선에 연결되어 있는 상황이며, 여기서 어려운 문제는 지연 시간(latency), 착신 전환(transfers) 그리고 꾸며내는 것을 막는 것입니다.
아웃바운드(Outbound)의 경우는 다릅니다. 예약 알림, 리드 콜백(speed-to-lead callbacks), 리드 재활성화 등: 이러한 캠페인은 지금 당장 전화를 요청하지 않은 사람들에게 전화를 걸며, 그 통화 중 상당수는 사람에게 연결되지 않습니다. 대신 음성 사서함 인사말, 통신사의 기본 메시지, 통화 스크리닝(call screening) 또는 전화 트리(phone tree)에 도달합니다.
아웃바운드를 처음 구축할 때는 음성 사서함이 예외적인 경우처럼 느껴집니다. 하지만 그렇지 않습니다. 많은 목록에서 그것은 가장 흔한 결과입니다. 그리고 '사람인지 기계인지'를 결정하는 것은 분류기(classifier)이며, 이는 어느 방향으로든 때때로 틀릴 수 있다는 것을 의미합니다. 제가 그렇게 취급하기 시작하자, 디자인의 대부분이 저절로 정리되었습니다.
에이전트가 감지하지 못할 때 발생하는 문제들
만약 에이전트가 인사말을 사람과의 통화처럼 처리한다면 세 가지 일이 발생합니다.
녹음 파일에 말을 건다. 인사말에서
판단하는 방식은 대략 사람이 판단하는 방식과 비슷합니다. 사람이 짧게 "여보세요?"라고 말하고 멈추는 경우와, 기계가 잠시 동안 말을 하다가 비프음이 나는 경우가 있습니다. 이는 시스템이 확정하기 전에 몇 초간의 오디오를 필요로 하며, 속임수에 걸릴 수 있다는 것을 의미합니다:
- 상대방이 길게 "안녕하세요, 마이크입니다. 무엇을 도와드릴까요?"라고 응답하는 경우, 이는 인사말과 매우 흡사하게 들립니다.
- 일부 음성 사서함 인사말은 단어 하나로만 이루어져 있습니다.
- 통화 스크리닝이나 전화 트리(phone tree)는 어느 쪽에도 해당하지 않습니다.
따라서 잘못 판단할 수 있는 방식이 두 가지가 있으며, 각각의 비용이 다릅니다.
| 실수 유형 | 발생하는 일 | 비용 |
|---|---|---|
| 사람을 기계로 분류 | 상담원이 실제 사람에게 전화를 끊거나, 음성 사서함 스크립트를 읽기 시작합니다. | 실시간 리드(live lead)를 놓치고 시스템이 고장 난 것처럼 보입니다. |
| 기계를 사람으로 분류 | 상담원이 녹음된 메시지를 재생합니다. | 시간 낭비와 혼란스러운 음성 사서함을 남깁니다. |
이를 표로 보면, 설계 질문은 "어떻게 하면 감지(detection)를 완벽하게 만들까?" (불가능함)에서 "이 캠페인에 어떤 실수가 더 저렴한가, 그리고 두 가지 실수 모두 어떻게 생존 가능하게 만들 수 있을까?"로 바뀝니다.
첫 문장을 양쪽 답변에 맞게 조정하기
가장 유용한 변화는 처음 몇 초입니다.
상대방이 먼저 말하도록 하세요. 만약 상담원이 인사말과 함께 피치(pitch)를 시작하면, 감지 시스템이 여전히 듣고 있는 동안 그 녹음된 메시지가 인사말을 덮어버리고, "안녕하세요"라고 말한 사람의 목소리까지 덮어버립니다. 만약 기다린다면, 사람이 짧게 무언가를 말하고 기계가 인사말을 시작합니다. 어느 쪽이든 감지 시스템은 깨끗한 오디오를 얻습니다.
솔직히 말씀드리자면: 제가 직접 확인해 본 제 에이전트(agent) 내보내기 파일들 모두 start_speaker가 agent로 설정되어 있었습니다. 아웃바운드 통화도 마찬가지였습니다. 이것은 놓치기 쉬운데, 왜냐하면 자신의 휴대폰을 들고 전화를 받아 "안녕하세요"라고 말하는 테스트 통화는 어느 쪽이든 잘 작동하기 때문입니다.
첫 문장을 짧게 유지하세요. 사람인지 오분류된 기계인지 상관없이 "마이크인가요?"라는 질문은 괜찮습니다. 30초짜리 도입부는 그렇지 않습니다.
전화를 끊거나 메시지를 남기는 것은 제품 결정 사항입니다
제가 내보낸 에이전트 설정(agent configs)들은 모두 동일한 음성 사서함 처리 동작을 사용합니다:
"voicemail_option": { "action": { "type": "hangup" } }
이는 합리적인 기본값(default)이지만, 결정(decision)이어야 할 부분입니다. 캠페인에 따라 달라져야 합니다:
- 예약 알림: 짧은 메시지를 남깁니다. 고객은 비즈니스가 전화를 걸어올 것이라고 기대합니다.
- 신속한 리드 콜백: 짧은 메시지를 남기고 문자를 보냅니다. 이 리드는 방금 연락을 요청했습니다.
- 리드 재활성화: 첫 번째 시도에서는 끊고, 마지막 시도에서만 메시지를 남깁니다.
- 의료, 법률 또는 금융 관련 사항: 최소한의 메시지나 아무것도 남기지 않습니다. 음성 사서함은 전화를 가진 누구에게나 들립니다.
에이전트가 메시지를 남긴다면, 모델이 즉흥적으로 만드는 것이 아니라 고정된 스크립트여야 합니다. 즉흥적인 음성 메시지는 장황합니다. 제 규칙은 이렇습니다: 15초 미만, 첫 문장에 비즈니스 이름 포함, 통화 이유 한 가지, 콜백 번호 두 번 언급, 민감한 정보 없음, 고객이 단어 그대로 승인한 내용이어야 합니다.
그리고 많은 사람들이 음성 사서함을 전혀 확인하지 않기 때문에, 연락처가 문자 메시지 수신에 동의했다면 n8n이나 GoHighLevel을 통해 SMS와 결합합니다. 실제로 문자가 음성 사서함보다 더 많은 역할을 하는 경우가 많습니다. 이를 위한 시스템 구성(plumbing)은 제가 An AI Voice Agent Is Just Two Webhooks에서 설명한 것과 동일한 통화 후 웹훅(post-call webhook)을 사용합니다.
모든 통화는 정확히 하나의 결과로 끝난다
이것은 엔지니어로서 제가 가장 신경 쓰는 부분입니다. 왜냐하면 보고서가 진실을 말할지, 아니면 그렇지 않을지를 결정하는 곳이기 때문입니다.
저희 에이전시들이 고객에게 전달하기 위해 만든 포털인 VoiceDash에서는 모든 통화가 Retell에서 가져온 종료 사유(end reason)와 함께 저장됩니다:
endReason: call.disconnection_reason || call.call_status,
이는 디버깅에 유용하며 분석 페이지에 차트로 표시되지만, 원시 연결 끊김 사유는 비즈니스 결과가 아닙니다. '상담원이 전화를 끊었다'는 것은 예약이 성공했음을 의미할 수도 있고, 상담원이 비프음(beep)을 듣고 떠났음을 의미할 수도 있습니다. 클라이언트는 다른 필드가 필요합니다.
그래서 저는 닫힌 목록의 결과(outcome)를 정의하고 모든 통화가 정확히 하나의 항목에 기록되도록 합니다:
// 예시: 목표로 하는 형태이며, 특정 레포지토리의 코드는 아닙니다
type CallOutcome =
| "connected_goal_met"
...
Retell의 통화 후 분석은 녹취록에서 구조화된 필드를 추출할 수 있으며, 제 에이전트 설정은 이미 이를 qualified나 appointment_type 같은 용도에 사용하고 있습니다. 여기에 결과 열거형(outcome enum)을 추가하는 것은 비용이 적게 듭니다. 핵심은 이것이 자유 텍스트가 아니라 열거형이라는 점입니다. 따라서 눈대중으로 계산하는 대신 깔때기(funnel)를 계산할 수 있게 됩니다: 발신 시도, 연결 성공, 음성 사서함, 그리고 실제로 도달한 사람들 사이의 전환율을 말이죠.
적당한 연결률과 높은 연결 성공 후 전환율을 보이는 캠페인이 좋은 캠페인입니다. 만약 '발신된 통화 횟수'와 '예약된 약속'만 보여준다면, 이 수치를 숨기게 되고 에이전트가 리스트 문제로 비난받게 됩니다.
재시도(Retries)는 다른 옷을 입은 같은 문제입니다
통화가 음성 사서함에 도달했을 때, 무엇인가가 언제 그리고 다시 시도할지 결정해야 합니다. 제가 기본으로 설정한 규칙들은 다음과 같습니다:
- 캠페인당 연락처별로 2~3회 시도하며, 무제한은 아닙니다.
- 다른 요일과 다른 시간대에 시도합니다.
- 연락처당 음성 사서함 메시지는 한 번만 남기고, 시도 횟수만큼 남기지 않습니다. 동일한 번호로 세 개의 똑같은 메시지를 보내는 것은 비즈니스가 스팸으로 신고되는 방식입니다.
- 어떤 거부(opt-out)가 발생하면 해당 클라이언트의 모든 캠페인에서 연락처가 즉시 제거됩니다.
- 통화는 오직 연락처의 현지 주간 시간대에만 이루어집니다.
아웃바운드 통화 규칙은 국가 및 미국 주별로 다르며, AI 음성은 규제 기관의 특정 초점입니다. 저는 변호사가 아니라 엔지니어이므로, 어떤 리스트가 로드되기 전에는 동의(consent) 문제는 클라이언트와 그들의 법률 자문가에게 맡깁니다.
본인 전화기가 아닌 실제 인사말을 테스트하세요
제 개인적인 start_speaker 설정으로는 본인 전화로만 테스트하면 통과하기 쉽습니다. 따라서 캠페인을 라이브화하기 전에, 분류기(classifier)의 약점을 커버하는 소수의 번호로 전화를 걸어보세요:
- 개인 음성 사서함 인사말
- 통신사 기본 인사말
- 통화 스크리닝이 켜진 전화
- 전화나무(phone tree)가 있는 사업장 전화
- 길고 격식 있는 인사를 건네는 실제 사람
그리고 모든 녹음 파일을 들어보세요. 상담원이 기다렸나요? 감지(detection)는 올바르게 분류했나요? 메시지가 비프음 이후에 시작했고, 인사말 중간이 아니었나요? 결과(outcome) 필드는 올바른 버킷에 속했나요? 전화 통화는 나중에 재현하기가 어렵습니다. 이 점은 제가 There Is No Repro for a Phone Call에서 작성한 바 있습니다. 따라서 이는 목록이 라이브화된 후에 하는 것보다 이전에 하는 것이 더 저렴합니다.
아웃바운드(Outbound) 클라이언트들은 주로 로봇이 고객에게 무슨 말을 하고 있는지 알고 싶어 합니다. 이것이 바로 VoiceDash가 녹음 파일을 그들 앞에 두는 이유입니다. 병원 운영자는 상담원이 남긴 정확히 15초를 재생하고 궁금해하는 것을 멈출 수 있습니다.
첫 아웃바운드 빌드를 앞두고 스스로에게 말할 것들
음성 사서함 감지(Voicemail detection)는 분류기입니다. 두 가지 실수 중 어떤 것이 캠페인당 더 저렴한지 결정하고, 오프닝 라인이 둘 다 살아남도록 만들고, 메시지를 스크립트화하고, 통화당 하나의 결과(outcome)를 열거형(enum)으로 저장하며, 재시도 횟수를 제한하고, 본인의 인사말이 아닌 인사말을 대상으로 테스트하세요.
저는 VoiceDash 블로그에 이 내용의 더 길고 에이전시 대상 버전인 Retell AI voicemail detection을 작성했습니다.
만약 아웃바운드 음성 에이전트를 운영한다면,
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기