
Voice AI는 장애가 나도 통화를 이어가야 한다: 병원 AI 상담원의 실패 복구 설계
환자가 병원에 전화해 묻습니다.
“내일 오후에 예약할 수 있나요?”
그 순간 예약 시스템의 응답이 늦어집니다. AI가 몇 초 동안 침묵하다가 통화를 끊어 버린다면 환자에게는 어떤 서버가 느렸는지가 중요하지 않습니다. 그저 병원에 전화했지만 도움을 받지 못한 경험으로 남습니다.
Voice AI의 한 문장 뒤에는 여러 시스템이 연결되어 있습니다.
- 환자의 음성을 문자로 바꾸는 STT
- 의도와 대화 흐름을 판단하는 LLM
- 답변을 음성으로 만드는 TTS
- 환자와 예약 정보를 조회하는 병원 업무 API
- 사람 상담원에게 전화를 넘기는 SIP와 전환 시스템
- 통화 녹음과 사후 분석을 담당하는 저장·메시징 시스템
이 중 하나라도 언제든 느려지거나 실패할 수 있습니다. 모든 구성 요소가 항상 정상이라는 가정으로 만든 Voice AI는 데모에서는 잘 동작해도 운영 환경에서는 쉽게 멈춥니다.
그래서 안정적인 AI 상담원이 갖춰야 할 능력은 단순합니다.
장애를 없애는 것이 아니라, 장애의 범위를 통화 전체로 번지지 않게 막는 것.
이 글에서는 와이즈에이아이 인바운드 에이전트의 실제 구조를 바탕으로, 실패를 어떻게 구분하고 언제 재시도하며 어떤 대체 경로로 환자와의 통화를 이어가야 하는지 살펴보겠습니다.
1. 모든 실패가 통화 종료를 의미하지는 않는다
Voice AI에서 가장 먼저 해야 할 일은 오류를 하나의 종류로 취급하지 않는 것입니다.
FAQ를 가져오지 못한 것과 환자의 음성을 전혀 인식하지 못하는 것은 영향 범위가 다릅니다. 통화 녹음 시작에 실패한 것과 예약 확정 요청의 결과를 알 수 없는 것도 대응 방식이 달라야 합니다.
| 실패한 구성 요소 | 여전히 가능한 일 | 제한되거나 위험한 일 |
|---|---|---|
| 병원 FAQ | 예약, 기본 통화 Context 안내 | FAQ 기반 운영 정보 안내 |
| 예약 조회 API | 일반 문의, 메시지 남기기 | 실시간 일정 안내와 예약 확정 |
| 상담원 전환 | AI 상담, 메시지 접수 | 즉시 사람에게 연결 |
| 녹음·사후 분석 | 환자와의 실시간 상담 | 통화 품질 분석과 기록 |
| LLM | 고정 안내 재생, 안전한 종료 | 새로운 대화 판단 |
| TTS | 준비된 음성 재생 | 새로운 문장의 음성 합성 |
| STT | DTMF 입력, 고정 안내 | 자유로운 음성 대화 |
즉, 어떤 기능이 실패했다고 해서 통화 전체가 반드시 실패한 것은 아닙니다.
좋은 실패 복구는 장애를 숨기는 것이 아닙니다. 지금 할 수 있는 일과 할 수 없는 일을 정확히 구분해, 가능한 범위 안에서 환자를 계속 돕는 것입니다.
2. 복구 전략은 재시도 하나가 아니다
장애가 발생하면 가장 먼저 떠올리는 대응은 재시도입니다. 하지만 재시도는 여러 선택지 중 하나일 뿐입니다.
Voice AI가 선택할 수 있는 대응은 크게 다섯 가지입니다.
- Retry: 같은 요청을 잠시 후 다시 시도합니다.
- Fallback: 다른 모델이나 제공자로 요청을 넘깁니다.
- Graceful Degradation: 실패한 기능을 제외하고 제한된 상태로 통화를 계속합니다.
- Alternative Path: 상담원 연결, 메시지 접수 등 다른 업무 경로를 제안합니다.
- Safe Termination: 더 진행하면 위험할 때 상황을 설명하고 안전하게 종료합니다.
중요한 것은 무조건 성공할 때까지 재시도하지 않는 것입니다. 음성 통화에서 긴 침묵은 시스템 입장에서는 대기 시간이지만 환자에게는 서비스가 멈춘 시간입니다.
재시도에는 반드시 다음 경계가 필요합니다.
- 한 번의 시도에 허용할 최대 시간
- 전체 재시도 횟수와 총 대기 시간
- 재시도 중 환자에게 들려줄 안내
- 중복 실행이 위험한 업무인지 여부
- 끝내 복구되지 않았을 때 이동할 다음 경로
3. LLM이 실패하면 다른 모델로 넘긴다
LLM은 환자의 의도를 이해하고 다음 행동을 결정하는 핵심 구성 요소입니다. 이 연결이 실패하면 AI 상담원은 새로운 질문에 답하거나 업무 Tool을 선택하기 어렵습니다.
현재 와이즈에이아이 인바운드 에이전트는 LLM을 하나만 사용하지 않습니다. 기본 모델에 연결할 수 없거나 요청이 실패하면 서로 다른 제공자의 보조 모델을 사용할 수 있도록 LiveKit의 LLM Fallback Adapter를 적용하고 있습니다.
LiveKit의 Agent Fallback Adapter는 연결 실패, Timeout, HTTP 오류와 스트리밍 중 연결 해제 등을 감지해 다음 제공자로 전환할 수 있습니다. 실패한 제공자는 일시적으로 비정상 상태로 두고, 복구 여부를 백그라운드에서 확인합니다. 자세한 동작은 LiveKit Fallback Strategies 공식 문서에서 확인할 수 있습니다.
다만 LLM Fallback에는 중요한 제약이 있습니다.
이미 환자에게 답변 일부를 보내거나 Tool 호출을 시작한 뒤라면 다른 모델이 처음부터 같은 요청을 다시 처리할 때 문장이 중복되거나 업무가 두 번 실행될 수 있습니다. 그래서 기본 동작은 출력이 시작된 이후 무리하게 모델을 교체하지 않는 방향입니다.
즉, Fallback은 실패를 없애는 마법이 아닙니다. 아직 외부에 결과가 전달되지 않은 안전한 구간에서 다음 제공자로 넘기는 장치입니다.
4. STT 장애와 ‘환자가 조용한 상태’를 구분해야 한다
STT가 실패하면 AI는 환자의 말을 들을 수 없습니다. 하지만 아무 전사 결과가 없다는 사실만으로 STT 장애라고 단정할 수는 없습니다.
다음 상황은 겉으로 모두 “입력이 없다”처럼 보입니다.
- 환자가 생각하느라 잠시 말하지 않음
- 통화 음질이 나빠 발화가 인식되지 않음
- 환자의 짧은 맞장구가 필터링됨
- STT 스트림 연결이 끊김
- 환자가 이미 전화를 끊음
따라서 시스템은 세 가지 신호를 함께 봐야 합니다.
- 전화 참여자가 여전히 연결되어 있는가?
- VAD가 음성 활동을 감지했는가?
- STT가 정상 상태인데 전사만 비어 있는가, 아니면 오류 이벤트가 발생했는가?
환자가 잠시 조용한 경우에는 다시 말씀해 달라고 안내할 수 있습니다. 현재 서비스도 일정 시간 응답이 없으면 입력 방식에 맞춰 음성 또는 키패드로 다시 응답해 달라고 안내하고, 제한된 횟수 동안 기다린 뒤 통화를 정리합니다.
반면 STT 스트림 자체가 복구 불가능한 상태라면 같은 안내를 반복해도 환자의 말은 들어오지 않습니다. LiveKit은 STT를 포함한 파이프라인 오류를 AgentSession의 오류 이벤트로 전달하며, 복구 가능 여부를 구분합니다. STT는 세션 동안 스트림이 유지되므로 복구 불가능한 오류 뒤에는 스트림을 다시 시작하거나 보조 STT로 전환하는 설계가 필요합니다. LiveKit Events and Error Handling 공식 문서에서도 구성 요소와 복구 가능 여부를 기준으로 대응할 것을 안내합니다.
현재 서비스는 병원별 설정에 따라 STT 제공자를 선택하는 구조입니다. 향후 두 제공자를 Fallback Adapter로 묶으면 기본 STT 장애 시 보조 STT로 전환하는 범위까지 확장할 수 있습니다.
5. TTS가 실패하면 텍스트 안내만으로는 복구할 수 없다
LLM이 정상적으로 답을 만들었더라도 TTS가 실패하면 전화기 너머의 환자에게는 아무것도 들리지 않습니다.
이때 “현재 음성 합성에 문제가 있습니다”라는 문장을 다시 TTS로 생성하려 해도 같은 장애 경로를 사용하기 때문에 소용이 없습니다.
TTS 장애에는 다음과 같은 단계적 대응이 필요합니다.
- 아직 음성이 재생되지 않았다면 보조 TTS 제공자로 전환합니다.
- 이미 문장 일부가 재생되었다면 중간에 목소리가 바뀌거나 문장이 처음부터 반복되지 않도록 주의합니다.
- 모든 TTS가 실패하면 미리 준비한 고정 음성으로 장애 안내를 재생합니다.
- 이후 통화를 계속할 수 없다면 환자가 상황을 이해한 상태에서 종료합니다.
특히 “잠시 연결이 원활하지 않습니다”, “나중에 다시 전화해 주세요”처럼 장애 시 반드시 전달해야 하는 문장은 사전 녹음 음성으로 준비할 수 있습니다. 사전 녹음 파일은 TTS를 통하지 않으므로 음성 합성 서비스가 모두 실패해도 재생할 수 있습니다.
LiveKit도 TTS 실패 시 텍스트만 다시 전달하지 말고, 오디오 프레임을 직접 재생하는 사전 녹음 Fallback을 권장합니다. 관련 예시는 LiveKit Events and Error Handling 공식 문서에 포함되어 있습니다.
현재 서비스는 스트리밍 TTS를 사용하고 있으며, 보조 TTS와 사전 녹음 장애 안내는 추가로 확장할 수 있는 복구 계층입니다.
6. 병원 API의 ‘결과 없음’과 ‘조회 실패’는 전혀 다르다
예약 가능한 시간이 한 건도 없는 것과 예약 시스템에 접속하지 못한 것은 환자에게 완전히 다른 정보입니다.
| API 결과 | 의미 | 환자 안내 |
|---|---|---|
| 정상 응답, 결과 0건 | 해당 조건에 가능한 일정이 없음 | 다른 날짜나 조건을 제안 |
| Timeout | 일정 확인을 완료하지 못함 | 조회 지연을 알리고 대체 경로 제안 |
| HTTP 오류 | 업무 시스템이 요청을 처리하지 못함 | 현재 확인이 어렵다고 안내 |
| 형식 오류 | 응답을 안전하게 해석할 수 없음 | 결과를 추측하지 않고 실패로 처리 |
| 성공 응답 | 확인된 일정이 있음 | 반환된 일정만 안내 |
이 구분이 없으면 AI가 API 장애를 “예약 가능한 시간이 없습니다”라고 잘못 안내할 수 있습니다. 환자는 실제로 자리가 있는데도 예약을 포기하게 됩니다.
현재 예약 흐름에서는 정상적인 빈 결과와 status=error를 분리합니다. 일정 조회가 실패하면 없다고 단정하지 않고, 확인하지 못했다는 사실을 정직하게 안내하도록 Grounding 규칙을 적용합니다.
조회 요청은 제한적으로 재시도할 수 있지만, 예약 생성·변경·취소처럼 상태를 바꾸는 요청은 더 조심해야 합니다. 응답이 Timeout으로 끝났더라도 서버에서는 이미 처리가 완료되었을 수 있기 때문입니다.
상태 변경 요청을 무작정 다시 보내면 중복 예약이나 이중 취소가 생길 수 있습니다. 이런 업무에는 다음과 같은 보호 장치가 필요합니다.
- 요청마다 중복 여부를 식별할 수 있는 키
- 재시도 전 현재 예약 상태 재조회
- 환자의 최종 동의를 기록하는 확인 단계
- 처리 결과가 불명확하면 성공으로 단정하지 않는 정책
7. FAQ 장애는 예약 통화까지 막지 않는다
병원 FAQ는 진료 시간, 주차, 준비물 같은 정보를 안내하는 데 사용됩니다. 하지만 FAQ API에 잠시 연결할 수 없다는 이유로 주소 확인이나 예약 업무까지 중단할 필요는 없습니다.
현재 인바운드 에이전트는 통화 시작 시 병원별 FAQ를 가져옵니다. 조회에 실패하거나 등록된 FAQ가 없다면 빈 목록을 사용하고, no-FAQ 지침으로 통화를 계속합니다.
제한 모드에서는 다음 원칙을 지킵니다.
- 통화 Context에 있는 기본 정보는 계속 안내합니다.
- 예약 API가 정상이라면 예약 업무도 계속 진행합니다.
- 제공받지 못한 병원 운영 정보는 추측하지 않습니다.
- 필요한 경우 사람 상담원 연결이나 메시지 접수를 안내합니다.
이것이 Graceful Degradation입니다. 장애가 발생한 기능만 내려놓고, 나머지 서비스는 유지합니다.
같은 원칙으로 통화 녹음 시작이 실패하더라도 실시간 환자 상담은 계속할 수 있습니다. 녹음 실패는 운영팀이 추적해야 할 중요한 문제지만, 환자가 지금 필요한 예약과 안내를 막아야 하는 문제는 아닙니다.
8. 상담원 연결 실패에는 ‘다음 선택지’가 있어야 한다
사람 상담원 연결은 AI의 대표적인 안전망입니다. 하지만 전환 시스템 역시 전화 회선, SIP, 상담원 상태, Redis Queue와 외부 네트워크에 의존합니다.
상담원 연결이 실패했을 때 아무 설명 없이 통화를 종료하면 안전망이 오히려 새로운 실패 지점이 됩니다.
현재 서비스의 전환 흐름은 실패 원인에 따라 다음과 같이 대응합니다.
- 일시적으로 재시도할 수 있는 SIP 오류는 제한된 횟수만 다시 시도합니다.
- 상담원이 통화 중이거나 응답하지 않으면 대기·재시도 정책을 적용합니다.
- Warm Transfer 대기 인프라를 사용할 수 없으면 Queue 진입을 포기합니다.
- 전환에 최종 실패하면 환자에게 실패 사실을 안내합니다.
- AI 음성 경로를 복원하고 메시지 남기기 흐름으로 이동합니다.
- 환자가 이미 전화를 끊었다면 추가 발화나 전환 작업을 시작하지 않습니다.
여기서 메시지 남기기는 단순한 부가 기능이 아닙니다. 실시간 연결이 불가능할 때도 환자의 연락 목적과 필요한 내용을 병원에 전달하는 비동기 Fallback입니다.
9. 연결이 끊긴 뒤에는 복구를 시도하지 않는다
복구 로직이 많아질수록 반드시 함께 확인해야 하는 상태가 있습니다.
환자가 아직 통화에 연결되어 있는가?
음성 재생을 기다리는 동안 환자가 전화를 끊었는데, 코드가 이를 모른 채 상담원 연결이나 예약 Task를 새로 시작할 수 있습니다. 이미 닫히는 세션에서 새로운 작업을 시작하면 종료가 지연되고, 녹음 정리나 통화 후 분석 전송까지 실행되지 못할 수 있습니다.
현재 전환 흐름에서는 안내 음성 재생이 끝난 뒤에도 SIP 참여자가 Room에 남아 있는지 다시 확인합니다. 환자가 이미 나갔다면 전환 Task를 시작하지 않고 즉시 반환합니다.
이 경험에서 얻은 교훈은 명확합니다.
- 음성 재생 완료는 상대방이 끝까지 들었다는 뜻이 아닙니다.
- 네트워크 작업이 예외 없이 끝났다고 참여자가 연결되어 있다고 가정할 수 없습니다.
- 긴 복구 작업에 들어가기 전에는 현재 세션 상태를 다시 확인해야 합니다.
- 종료 중인 세션에서는 새 업무를 만들지 말고 정리 작업이 끝날 수 있게 해야 합니다.
장애 복구는 실패한 작업을 다시 시작하는 기술인 동시에, 이미 의미가 없어진 작업을 시작하지 않는 기술입니다.
10. 환자에게는 기술 오류가 아니라 다음 행동을 알려준다
환자에게 “LLM Provider Timeout”이나 “SIP 403 오류”를 설명할 필요는 없습니다. 그렇다고 아무 일도 없었던 것처럼 말해서도 안 됩니다.
좋은 장애 안내에는 세 가지가 들어갑니다.
- 지금 무엇을 확인하거나 처리하지 못했는지
- 이미 처리된 것으로 오해하면 안 되는지
- 환자가 다음으로 선택할 수 있는 방법이 무엇인지
예를 들어 예약 조회가 실패했다면 다음과 같이 안내할 수 있습니다.
“현재 예약 가능한 시간을 확인하는 데 시간이 걸리고 있습니다. 예약이 완료된 것은 아니며, 상담원 연결이나 메시지 접수를 도와드릴 수 있습니다.”
반대로 피해야 할 표현은 다음과 같습니다.
- “예약 가능한 시간이 없습니다.” — 조회 자체가 실패했다면 사실이 아닙니다.
- “예약이 완료되었습니다.” — 확정 응답을 받지 못했다면 위험합니다.
- “잠시만 기다려 주세요.” — 언제까지 기다릴지, 실패하면 어떻게 할지 없습니다.
- “시스템 오류입니다.” — 환자가 취할 수 있는 다음 행동이 없습니다.
기술적인 실패를 환자의 언어로 번역하는 것도 Voice AI 복구 설계의 일부입니다.
11. 장애가 복구되었는지 운영팀도 알아야 한다
Fallback이 성공하면 환자는 장애를 거의 느끼지 못할 수 있습니다. 사용자 경험 측면에서는 좋은 일이지만, 운영 지표에도 아무 흔적이 남지 않으면 기본 제공자의 문제가 반복되어도 알기 어렵습니다.
따라서 오류와 복구를 구조화된 이벤트로 기록해야 합니다.
| 기록할 정보 | 목적 |
|---|---|
| 실패한 구성 요소 | STT·LLM·TTS·API·전환 중 원인 구분 |
| 복구 가능 여부 | 자동 복구와 통화 종료 위험 분리 |
| 시도 횟수와 대기 시간 | 과도한 재시도와 환자 침묵 시간 확인 |
| 사용한 Fallback | 어떤 대체 경로가 실제로 작동했는지 확인 |
| 최종 환자 안내 | 실패를 성공처럼 말하지 않았는지 검증 |
| 업무 최종 상태 | 성공·실패·불명확·환자 이탈 구분 |
현재 서비스는 FAQ 조회, 예약 API 결과, 상담원 전환 상태, 환자 연결 해제와 통화 종료 사유를 이벤트로 남기고 통화 후 분석에 전달합니다. 이를 통해 단순히 “통화가 끝났다”가 아니라 어느 단계에서 실패했고 누가 다음 행동을 선택했는지 분석할 수 있습니다.
특히 다음 지표는 구분해서 보는 것이 좋습니다.
- 기본 제공자 성공률과 Fallback 사용률
- API Timeout과 정상적인 빈 결과 비율
- 상담원 전환 실패 후 메시지 접수 전환율
- 복구 과정에서 발생한 추가 대기 시간
- 장애 안내 후 환자 이탈률
- 통화 종료 후 분석 데이터 전송 실패율
Fallback 사용률이 높아졌는데 전체 성공률이 유지된다고 안심해서는 안 됩니다. 그것은 보조 경로가 잘 작동한다는 뜻인 동시에 기본 경로가 불안정해졌다는 신호일 수 있습니다.
12. 안전한 Voice AI를 위한 장애 대응 체크리스트
STT·LLM·TTS
- 구성 요소별 Timeout과 재시도 한도가 있는가?
- 기본 모델 실패 시 사용할 보조 제공자가 있는가?
- 이미 출력이나 Tool 실행이 시작된 뒤 중복 실행을 막는가?
- STT 스트림 장애와 환자의 침묵을 구분하는가?
- TTS 전체 장애 시 재생할 사전 녹음 안내가 있는가?
병원 업무 API
- 빈 결과와 조회 실패를 다르게 처리하는가?
- Timeout을 성공이나 결과 없음으로 해석하지 않는가?
- 상태 변경 요청을 무조건 재시도하지 않는가?
- 처리 결과가 불명확하면 환자에게 완료되었다고 말하지 않는가?
- 사용할 수 없는 기능을 제외하고 다른 업무는 계속할 수 있는가?
상담원 연결
- 일시적 오류와 최종 실패를 구분하는가?
- 재시도 횟수와 대기 시간에 상한이 있는가?
- 전환 실패 후 AI 음성을 복원하는가?
- 메시지 남기기 같은 다음 경로가 있는가?
- 환자가 끊은 뒤 새로운 전환 작업을 시작하지 않는가?
종료와 운영
- 중요한 정리 작업이 통화 종료를 무한히 지연시키지 않는가?
- 녹음·분석 실패가 실시간 통화를 불필요하게 막지 않는가?
- 오류, Fallback, 최종 결과가 구조화된 이벤트로 남는가?
- 실제 장애 사례를 재현하는 테스트가 있는가?
- 복구 성공률뿐 아니라 환자가 기다린 시간도 측정하는가?
마치며
병원 Voice AI는 여러 외부 시스템이 연결된 실시간 서비스입니다. 모든 구성 요소가 항상 정상일 수는 없습니다.
중요한 것은 하나의 장애가 통화 전체를 무너뜨리지 않도록 경계를 만드는 것입니다.
- 짧은 일시적 오류는 제한적으로 재시도합니다.
- 핵심 AI 모델 장애는 다른 제공자로 전환합니다.
- FAQ나 녹음 장애는 해당 기능만 제한하고 통화를 계속합니다.
- 예약 API 실패는 일정 없음과 구분해 정직하게 안내합니다.
- 상담원 연결 실패에는 메시지 접수라는 다음 경로를 제공합니다.
- 더 진행하면 위험할 때는 환자가 이해할 수 있는 안내 후 안전하게 종료합니다.
좋은 장애 대응은 모든 실패를 성공으로 바꾸는 것이 아니라, 실패한 순간에도 환자가 다음 행동을 선택할 수 있게 만드는 것이다.
결국 Voice AI의 신뢰성은 정상적인 순간의 유창함보다, 예상하지 못한 문제가 생겼을 때 얼마나 침착하고 정직하게 통화를 이어가는지에서 드러납니다.