
AI가 실제 예약 요청을 접수하기까지: 병원 Voice AI의 조회·스테이징·확정 설계
환자가 병원에 전화해 말합니다.
“다음 주 수요일 오후에 스케일링 예약하고 싶어요. 선생님은 아무나 괜찮아요.”
AI가 자연스럽게 답하는 것만 놓고 보면 간단한 요청처럼 보입니다. 하지만 실제 예약 요청으로 만들려면 여러 질문에 먼저 답해야 합니다.
- “다음 주 수요일”은 정확히 몇 월 며칠인가?
- 해당 병원이 전화 예약으로 받는 진료 항목인가?
- 그 날짜 오후에 실제로 가능한 시간이 있는가?
- “아무나”라는 조건에서 어떤 의료진을 배정할 수 있는가?
- 환자가 마지막에 들은 진료 항목과 일시에 정말 동의했는가?
- AI가 접수한 것은 확정 예약인가, 병원이 확인할 예약 요청인가?
이 과정에서 LLM에게 모든 판단과 상태 변경을 맡기면 대화는 유연해지지만 예약의 안전성은 낮아집니다. 반대로 모든 대화를 고정된 단계로만 만들면 환자가 “그 시간 말고 30분 뒤요”라고 조건을 바꾸는 순간 흐름이 쉽게 꼬입니다.
와이즈에이아이 인바운드 에이전트는 이 문제를 대화는 LLM이 이어가고, 예약의 사실과 상태 변경은 코드가 통제하는 구조로 풀고 있습니다.
이 글에서는 환자의 한 문장이 어떻게 실시간 일정 조회, 정확한 후보 선택, 최종 확인을 거쳐 안전한 예약 요청이 되는지 살펴보겠습니다.
목차
- 1. 먼저 ‘예약 확정’과 ‘예약 요청 접수’를 구분한다
- 2. 전체 예약 흐름은 하나의 대화보다 길다
- 3. LLM은 ‘대화 상태’를, 코드는 ‘업무 상태’를 맡는다
- 4. 병원 기준 정보와 실시간 일정은 다른 사실이다
- 5. 일정 검색은 매번 완전한 조건으로 요청한다
- 6. ‘일정 없음’과 ‘조회 실패’를 구분한다
- 7. 스테이징은 ‘대화 속 후보’를 ‘확인 가능한 후보’로 바꾼다
- 8. 확인 질문은 LLM의 요약이 아니라 거래 경계다
- 9. 조건이 바뀌면 이전 동의 대상은 폐기한다
- 10. Commit은 병원 예약 확정이 아니라 완전한 요청 기록이다
- 11. 예약 흐름의 성공은 문장이 아니라 이벤트로 측정한다
- 12. 안전한 예약 요청을 위한 설계 원칙
- 마치며
1. 먼저 ‘예약 확정’과 ‘예약 요청 접수’를 구분한다
현재 서비스에서 AI가 통화 중 완료하는 일은 병원 EMR에 예약을 즉시 확정하는 것이 아닙니다.
AI는 환자와 함께 진료 항목·의료진·일시를 선택하고, 최종 동의를 받은 뒤 완전한 예약 요청 정보를 통화 세션에 기록합니다. 이 요청은 이후 병원 확인 절차를 거쳐 최종 확정됩니다.
따라서 마지막 안내도 두 상태를 분명히 구분합니다.
“예약 신청이 접수되었습니다. 다만 아직 병원에서 확정된 예약은 아니며, 병원 확인 후 최종 확정 안내를 드리겠습니다.”
이 차이는 단순한 말투 문제가 아닙니다.
| 상태 | 시스템이 알고 있는 사실 | 환자에게 말할 수 있는 표현 |
|---|---|---|
| 일정 조회 성공 | 조회 시점에 가능한 후보가 있었음 | “이 시간이 가능합니다” |
| 후보 스테이징 | 정확한 진료 항목·의료진·일시를 확인 질문으로 만들었음 | “이 조건으로 접수해 드릴까요?” |
| 예약 요청 기록 완료 | 환자가 동의한 요청 정보가 세션에 기록됨 | “예약 신청이 접수되었습니다” |
| 병원 최종 확인 | 병원 업무 시스템이 최종 상태를 확정함 | “예약이 최종 확정되었습니다” |
조회 결과가 있었다는 이유만으로 “예약되었습니다”라고 말해서는 안 됩니다. AI가 예약 요청을 기록했다는 사실과 병원이 예약을 확정했다는 사실도 같지 않습니다.
Voice AI가 성공을 안내할 수 있는 범위는 자신이 실제로 완료한 시스템 경계까지다.
2. 전체 예약 흐름은 하나의 대화보다 길다
예약 요청은 일정만 고르는 과정이 아닙니다. 현재 신규 예약 흐름은 크게 다음 단계로 구성됩니다.
환자의 생년월일이 아직 확인되지 않았다면 DTMF를 통해 정보를 수집하고 검증합니다. 병원 설정에 따라 보험 선택 단계가 추가될 수 있습니다. 그다음 병원별 진료 항목과 의료진 목록을 가져오고, 실제 가능한 일정과 연결합니다.
각 단계는 서로 다른 종류의 사실을 다룹니다.
- 환자 식별은 누구의 요청인가를 결정합니다.
- 병원 기준 정보는 무엇을 예약할 수 있는가를 결정합니다.
- 일정 조회는 언제, 누가 가능한가를 확인합니다.
- 최종 확인은 환자가 어떤 요청에 동의했는가를 고정합니다.
- 요청 기록은 어떤 내용을 병원에 전달할 것인가를 만듭니다.
이 경계를 섞으면 아직 확인되지 않은 선택이 예약 요청에 들어가거나, 이전에 선택한 시간이 환자가 바꾼 조건보다 늦게 반영될 수 있습니다.
3. LLM은 ‘대화 상태’를, 코드는 ‘업무 상태’를 맡는다
예약 대화에는 부드러운 상태와 단단한 상태가 함께 존재합니다.
환자가 “오후가 좋아요”, “가능하면 김 원장님이요”, “가장 빠른 날로요”라고 말하는 동안 조건은 계속 바뀔 수 있습니다. 이 단계의 정보는 아직 예약 후보가 아니라 대화를 좁히기 위한 선호입니다.
반면 정확한 진료 항목, 의료진, 날짜와 시간이 실제 일정 조회 결과로 확인되면 예약의 후보가 됩니다. 이때부터는 코드가 소유해야 하는 업무 상태입니다.
| 구분 | 예시 | 주된 소유자 |
|---|---|---|
| 대화 속 선호 | 오후, 가장 빠른 날, 아무 의료진 | LLM 대화 Context |
| 병원 기준 정보 | 진료 항목 ID, 의료진 ID, 예약 설정 | API와 코드 |
| 조회 결과 | 실제 가능한 날짜와 시간 | 예약 API |
| 스테이징된 후보 | 진료 항목·의료진·정확한 일시 | 코드 상태 |
| 최종 요청 | 환자가 동의한 완전한 예약 요청 | 통화 세션 데이터 |
LLM은 환자의 자유로운 표현을 구조화된 조회 조건으로 바꾸는 데 강합니다. 하지만 존재하지 않는 시간이나 의료진 ID를 만들어서는 안 됩니다. 실제 후보와 최종 기록은 반드시 API 결과와 코드 검증을 통과해야 합니다.
4. 병원 기준 정보와 실시간 일정은 다른 사실이다
예약 흐름을 시작하면 에이전트는 병원별 진료 항목, 의료진, 예약 설정을 불러옵니다. 이 데이터는 통화 안에서 기준 정보로 사용하고 재호출 시 재사용할 수 있도록 캐싱합니다.
하지만 기준 목록에 의료진이 있다는 사실은 특정 날짜에 그 의료진이 가능하다는 뜻이 아닙니다.
| 정보원 | 증명하는 것 | 증명하지 못하는 것 |
|---|---|---|
| 진료 항목 목록 | 전화 예약에서 선택 가능한 항목 | 특정 날짜의 예약 가능 여부 |
| 의료진 목록 | 병원 소속 의료진과 담당 항목 | 특정 시간의 근무·예약 가능 여부 |
| 일정 조회 API | 조회 조건에서 가능한 날짜·시간·의료진 | 병원이 나중에도 반드시 확정한다는 보장 |
예를 들어 의료진 목록에 김 원장님이 있고 스케일링을 담당한다고 해도, 수요일 오후에 예약 가능한지는 일정 API가 확인해야 합니다. 반대로 일정 응답에 의료진 ID가 있더라도 병원의 진료 항목 기준과 연결되지 않으면 어떤 진료로 예약할 수 있는지 안전하게 말할 수 없습니다.
예약 후보는 이 두 종류의 사실이 교차하는 지점에서만 만들어집니다.
5. 일정 검색은 매번 완전한 조건으로 요청한다
대화형 AI는 이전 대화 내용을 기억합니다. 하지만 예약 API까지 LLM의 기억에 의존하면 검색 조건이 일부 빠질 수 있습니다.
현재 일정 검색 Tool은 호출할 때마다 이해한 조건을 완전한 형태로 전달하도록 설계되어 있습니다.
- 조회 시작일과 종료일
- 진료 항목 ID
- 의료진 ID
- 오전·오후 같은 시간 범위
- 정확한 희망 시각
- 이전 후보보다 뒤의 시간을 찾는 조건
예를 들어 환자가 다음과 같이 조건을 바꿀 수 있습니다.
“수요일 오후로 찾아주세요.”
“그럼 김 원장님 가능한 시간만요.”
“첫 번째 말고 그다음 시간은요?”
각 검색은 “이전 검색에서 의료진만 바꾼다” 같은 숨은 상태를 보내지 않습니다. 현재까지 이해한 날짜·시간·진료 항목·의료진 조건을 한 번에 다시 전달합니다.
이 방식은 요청이 조금 길어지는 대신 검색 호출 하나만 읽어도 어떤 조건을 조회했는지 알 수 있습니다. 이전 대화 상태와 API 요청이 어긋나는 문제도 줄일 수 있습니다.
6. ‘일정 없음’과 ‘조회 실패’를 구분한다
예약 API가 정상적으로 응답했고 결과가 비어 있다면 해당 조건에 가능한 일정이 없다고 안내할 수 있습니다.
하지만 API가 Timeout이나 오류로 실패했다면 일정이 없는지 확인하지 못한 것입니다. 이때 “가능한 시간이 없습니다”라고 말하면 조회 실패를 병원 운영 정보처럼 전달하게 됩니다.
현재 예약 Tool도 정상적인 빈 결과와 status=error를 분리합니다. 이는 단순한 오류 처리보다 Grounding에 가깝습니다. AI가 환자에게 말할 수 있는 사실의 범위를 API 응답 상태가 결정하기 때문입니다.
7. 스테이징은 ‘대화 속 후보’를 ‘확인 가능한 후보’로 바꾼다
검색 결과에서 시간이 하나 보였다고 바로 예약 요청으로 기록하지 않습니다.
환자가 특정 시간을 선택하면 stage_booking 단계가 정확한 후보를 다시 검증합니다.
- 진료 항목 ID가 병원 기준 목록에 있는지 확인합니다.
- 의료진 ID가 실제 목록에 있는지 확인합니다.
- 날짜와 시간이 허용된 조회 범위 안인지 검사합니다.
- 해당 날짜의 일정을 조회해 그 시각과 의료진 조합이 가능한지 확인합니다.
- 정확한 진료 항목·의료진·일시를 하나의 후보로 저장합니다.
- 코드가 최종 확인 질문을 만들어 반환합니다.
스테이징이 성공해야만 다음과 같은 확인 질문을 말할 수 있습니다.
“스케일링, 8월 12일 수요일 오후 2시에 예약해 드릴까요?”
병원 설정상 환자가 의료진을 직접 선택해야 하는데 같은 시간에 여러 의료진이 가능하다면, 임의로 한 명을 확정하지 않고 선택지를 다시 묻습니다. 반대로 의료진 선택을 묻지 않는 병원이라면 코드가 가능한 의료진 중 한 명을 배정하되, 환자에게 제공하지 않는 선택지를 불필요하게 노출하지 않습니다.
스테이징은 실제 EMR 예약의 임시 저장이 아닙니다. 통화 안에서 “지금 어떤 정확한 요청에 대해 동의를 받고 있는가”를 고정하는 안전장치입니다.
8. 확인 질문은 LLM의 요약이 아니라 거래 경계다
확인 질문은 친절을 위해 한 번 더 묻는 문장이 아닙니다. 환자가 동의하는 대상을 하나로 고정하는 거래 경계입니다.
따라서 확인 질문에는 다음 정보가 들어가야 합니다.
- 진료 항목
- 병원 설정상 필요한 경우 의료진
- 정확한 날짜와 시간
- 지금 수행하는 행동이 예약 요청 접수라는 사실
확인 질문 이후의 환자 답변도 구분해야 합니다.
| 환자 답변 | 의미 | 다음 행동 |
|---|---|---|
| “네, 그렇게 해주세요” | 명시적 동의 | 요청 기록 진행 |
| “네?” | 질문을 못 들음 | 같은 확인 질문 재안내 |
| “아니요” | 현재 후보 거절 | 다른 조건 확인 |
| “3시로 바꿔주세요” | 조건 변경 | 새 후보 재검색·스테이징 |
| “잠시만요” | 동의 아님 | 기다린 뒤 새 확인 필요 |
| “그냥 예약 안 할게요” | 흐름 취소 | 요청 없이 종료 |
현재 구현에서 코드는 스테이징된 후보가 존재하는지, 동의받았다고 전달된 일시가 스테이징 일시와 같은지, 상태 변경이 직렬화되는지를 검사합니다. 명시적 동의와 되묻기, 조건 변경의 의미 판단은 LLM 지침과 평가 테스트가 함께 보호합니다.
여기에는 아직 남은 기술적 경계도 있습니다. 확인 질문이 실제로 끝까지 재생되었는지, 그 직후의 사용자 발화가 해당 질문에 대한 직접 동의인지까지 코드가 증거로 묶으면 더 강한 확인 게이트를 만들 수 있습니다.
즉, 프롬프트에 “반드시 확인하라”고 쓰는 것과 코드가 확인 증거 없이는 요청 기록을 거부하는 것은 서로 다른 안전 수준입니다.
9. 조건이 바뀌면 이전 동의 대상은 폐기한다
환자가 확인 질문을 들은 뒤 조건을 바꿀 수 있습니다.
AI: “오후 2시에 예약해 드릴까요?”
환자: “네, 그런데 3시로 바꿔주세요.”
이 답변에서 “네”만 떼어내 동의로 처리하면 오후 2시 요청이 기록될 수 있습니다. 전체 의미는 오후 3시로 변경해 달라는 요청입니다.
안전한 흐름은 다음과 같습니다.
현재 스테이징은 새 후보가 들어오면 이전 후보를 덮어씁니다. commit_booking은 환자가 동의했다고 전달된 일시와 현재 스테이징된 일시가 다르면 기록을 차단하고, 새 후보를 다시 스테이징하도록 요구합니다.
이 검사는 오래된 확인 질문에 대한 늦은 응답이나, LLM이 이전 시간을 기억해 잘못 제출하는 상황을 막는 최소한의 트랜잭션 가드입니다.
10. Commit은 병원 예약 확정이 아니라 완전한 요청 기록이다
환자가 정확한 후보에 동의하면 예약 흐름은 다음 정보를 하나의 요청으로 만듭니다.
- 요청 유형
- 진료 항목 ID
- 의료진 ID
- 예약 희망 일시
- 환자 식별에 필요한 정보
- 병원 설정에 따라 선택한 보험 정보
이 값은 부분적으로 기록되지 않습니다. 정확한 후보가 스테이징되고 동의 조건을 통과한 뒤 완전한 reservation_info로 만들어집니다.
현재 commit_booking은 이 시점에 일정 API를 다시 조회하지 않습니다. 스테이징 단계에서 같은 조건을 검증했고, 통화 중 Commit은 외부 예약 쓰기 API가 아니라 로컬 예약 요청 기록이기 때문입니다.
이 선택에는 분명한 트레이드오프가 있습니다.
- 장점: 확인 직후 API 장애로 접수 흐름이 다시 실패하지 않습니다.
- 장점: 외부 쓰기 재시도로 인한 중복 예약 위험이 없습니다.
- 한계: 스테이징 이후 병원 확인 전까지 일정이 바뀔 가능성을 완전히 제거하지 못합니다.
- 결과: AI는 최종 확정이 아니라 예약 요청 접수까지만 안내합니다.
향후 AI가 병원 EMR에 직접 예약을 확정하는 구조로 확장된다면 이 경계도 달라져야 합니다. 정확한 후보의 최종 가용성 확인과 예약 쓰기가 하나의 원자적 업무로 처리되어야 하고, Timeout 뒤 중복 실행을 막을 Idempotency Key와 결과 조회·조정 절차가 필요합니다.
11. 예약 흐름의 성공은 문장이 아니라 이벤트로 측정한다
환자가 마지막 안내를 들었다는 사실만으로 예약 요청 성공을 판단하면 안 됩니다. 실제로 어떤 상태까지 도달했는지 구조화된 이벤트가 필요합니다.
현재 예약 흐름은 주요 경계를 통화 기록에 남깁니다.
| 이벤트 상태 | 의미 |
|---|---|
STARTED | 신규 예약 흐름 진입 |
IDENTITY_VERIFY: SUCCESS | 환자 식별 완료 |
SLOTS_SEARCHED | 실제 일정 조회 수행 |
STAGED | 정확한 진료 항목·의료진·일시 후보 생성 |
SUCCESS | 완전한 예약 요청 정보 기록 완료 |
EXITED | 환자가 다른 요청으로 이동하거나 예약 흐름 중단 |
ERROR | 기준 정보·정규화·업무 처리 실패 |
이벤트가 있으면 다음 질문에 답할 수 있습니다.
- 환자 식별에서 많이 이탈하는가?
- 일정 조회 결과가 없어서 중단되는가?
- 후보는 만들었지만 최종 요청까지 가지 못하는가?
- 어떤 병원 설정에서 의료진 선택이 반복되는가?
- 조회 실패를 일정 없음으로 잘못 안내하지 않았는가?
- 확인 없이 Commit된 의심 경로가 있는가?
예약 전환율 하나만 보면 정상적인 환자 취소와 AI의 잘못된 판단, 병원 일정 부족, API 장애가 모두 같은 미완료로 보입니다. 단계별 이벤트는 실패 원인을 실제 소유자에게 돌려주는 관측성의 기반입니다.
12. 안전한 예약 요청을 위한 설계 원칙
정보와 가용성
- 병원 기준 목록과 특정 일시 가용성을 구분합니다.
- 일정은 반드시 실시간 API 결과에서만 안내합니다.
- 빈 결과와 API 실패를 다르게 처리합니다.
- 날짜 범위와 시간대 조건을 매 검색에 완전하게 전달합니다.
후보와 상태
- 넓은 날짜 범위나 “오후” 같은 선호를 예약 후보로 저장하지 않습니다.
- 정확한 진료 항목·의료진·일시만 스테이징합니다.
- 새 후보가 만들어지면 이전 후보의 동의 권한을 폐기합니다.
- 상태 변경은 Lock이나 단일 상태 전이로 직렬화합니다.
확인과 접수
- 최종 확인 질문은 API로 검증된 후보에서 코드가 만듭니다.
- 되묻기, 침묵, 조건 변경을 동의로 해석하지 않습니다.
- 동의받은 일시와 스테이징된 일시가 다르면 Commit을 차단합니다.
- 요청 정보가 완전히 기록된 뒤에만 접수 성공을 안내합니다.
환자 안내
- 예약 신청 접수와 병원 최종 확정을 구분합니다.
- 처리하지 못한 요청을 성공했다고 말하지 않습니다.
- 일정이 바뀔 수 있는 경계를 환자에게 숨기지 않습니다.
- 예약 흐름을 중단해도 다른 문의나 상담원 연결로 돌아갈 수 있게 합니다.
마치며
병원 Voice AI의 예약 기능은 LLM이 날짜와 시간을 잘 알아듣는 문제로 끝나지 않습니다.
안전한 예약 요청을 만들려면 대화 속 선호와 실제 업무 상태를 분리하고, 병원 기준 정보와 실시간 일정의 교차점에서 정확한 후보를 만들어야 합니다. 그 후보를 환자에게 완전하게 읽어주고, 동의받은 내용과 같은 요청만 기록해야 합니다.
그리고 시스템이 완료한 것이 예약 요청 접수라면, 환자에게도 최종 예약이 아니라 접수라고 말해야 합니다.
예약 Voice AI의 핵심은 빨리 Commit하는 것이 아니라, 환자가 동의한 정확한 요청만 Commit하는 것이다.
결국 좋은 예약 경험은 자연스러운 대화와 엄격한 거래 경계가 함께 있을 때 만들어집니다. LLM은 환자의 표현을 이해하고, 코드는 무엇이 실제 사실이며 언제 상태를 바꿀 수 있는지를 결정합니다.