1. 배경: 빈 응답이 곧 이탈이 되는 구간
휴트리온에서 KT의 유선상품 가입 에이전트를 개발할 때의 이야기입니다. 사용자가 "인터넷이랑 TV 같이 쓸 만한 거 있어요?"처럼 자연어로 조건을 말하면, 에이전트가 조건에 맞는 상품을 찾아 안내하고 최종 가입까지 대화로 완결하는 상용 서비스였습니다.
문제는 못 찾았을 때였습니다.
검색 결과가 없으면 시스템은 아무것도 반환하지 않았습니다. 사용자 입장에서는 질문을 던졌는데 응답이 비어 있거나, "찾을 수 없습니다"라는 한 문장만 돌아옵니다. 해당 지점에서 대화가 종료됩니다.
상용 서비스에서 이것은 단순한 UX 결함이 아닙니다. 가입 여정이 중단되는 지점이고, 그대로 이탈로 이어집니다.
2. 문제 정의: 데드엔드가 발생하는 세 가지 경로
로그를 분석해보니 대화가 데드엔드에 도달하는 경로가 세 가지였습니다.
첫째, 조건에 정확히 맞는 상품이 없는 경우입니다. 사용자가 여러 조건을 동시에 걸면 교집합이 공집합이 됩니다. 조건 하나만 완화하면 대안이 있는데도 "없습니다"로 응답이 종료됐습니다.
둘째, 상품 질의가 아닌 경우입니다. 요금 정책이나 약관처럼 상품 검색으로는 답할 수 없는 질문이 섞여 들어왔습니다. 상품 검색 파이프라인은 해당 유형의 발화를 처리할 경로가 없었습니다.
셋째, 의도 자체가 불명확한 경우입니다. 발화가 짧거나 모호하면 라우터가 어느 경로로도 확신하지 못했고, 결국 임의의 경로도 타지 못했습니다.
세 경우 모두 시스템이 "모른다"는 상태에 도달했을 때 무엇을 할지가 정의되어 있지 않다는 공통 원인을 갖고 있었습니다.
3. 기술적 난점
단순히 "없으면 상담원 연결"로 처리하는 방안을 검토했으나 적절하지 않았습니다.
모든 실패를 상담 연결로 보내면 상담 인입이 급증합니다. 무인 채널을 도입한 목적 자체가 훼손됩니다. 실제로 초기 구조에서는 조건이 조금만 까다로워도 상담으로 넘어가는 비율이 높았습니다.
반대로 무리하게 답을 만들어내면 환각이 발생합니다. 검색 결과가 없는데 LLM이 그럴듯한 상품명을 지어내면, 존재하지 않는 상품을 안내하는 사고가 됩니다. 상용 환경에서 허용할 수 없는 오류입니다.
"임의로 답하기"와 "포기하기" 사이의 중간 단계가 필요했습니다.
4. 대안 검토
1안. 검색 조건을 자동으로 완화한다
결과가 없으면 조건을 하나씩 빼면서 재검색합니다.
- 장점: 구현이 단순하고 결과가 나올 확률이 올라갑니다.
- 단점: 어떤 조건을 뺄지 판단할 근거가 없습니다. 사용자가 가장 중요하게 여긴 조건을 빼버리면 엉뚱한 결과를 확신에 차서 안내하게 됩니다.
2안. LLM에게 대안을 생성하게 한다
검색이 실패하면 LLM이 알아서 대안을 제시합니다.
- 장점: 자연스러운 문장이 나옵니다.
- 단점: 존재하지 않는 상품을 만들어냅니다. 검색이 실패했다는 것은 참조할 데이터가 없다는 뜻인데, 그 상태에서 생성을 맡기면 환각의 전형적인 조건이 됩니다.
3안. 단계적으로 내려가는 폴백 체인을 설계한다
실패 시 다음 단계로 넘기되, 각 단계가 서로 다른 방식으로 답을 찾습니다.
- 장점: 각 단계가 명확한 근거를 갖고 동작하며, 최후 단계까지 가도 후속 행동이 남습니다.
- 단점: 단계 정의와 전이 조건을 직접 설계해야 합니다.
5. 설계 결정 및 근거
3안을 채택했습니다. 핵심 판단은 "모른다"에도 여러 종류가 있다는 것이었습니다. 정확히 일치하는 게 없는 것과, 질문 자체가 다른 영역인 것과, 의도를 파악하지 못한 것은 각각 다른 대응이 필요합니다.
5.1 4단계 폴백 체인
① 단품·부가 검색 정확히 일치하는 상품 탐색
↓ (결과 없음)
② 속성 기반 추천 조건을 속성으로 분해해 유사 상품 제시
↓ (여전히 없음)
③ 상담 연결 사람이 판단해야 하는 영역으로 이관
↓ (상품 질의가 아님)
④ 지식 에이전트 이관 RAG 기반 지식 응답으로 전환각 단계는 이전 단계가 실패했을 때만 동작합니다. 상위 단계에서 결과가 나오면 즉시 반환하고 아래로 내려가지 않습니다.
여기서 중요한 설계는 ②와 ④입니다.
② 속성 기반 추천은 "정확히 일치"가 아니라 "속성이 비슷한" 상품을 찾습니다. 사용자가 건 조건을 개별 속성으로 분해한 뒤, 그중 핵심 속성을 만족하는 대안을 제시합니다. 조건을 임의로 빼는 1안과 달리, 어떤 속성이 충족되고 어떤 것이 아닌지를 명시하면서 안내합니다.
④ 지식 에이전트 이관은 상품 검색으로 풀 수 없는 질의를 다른 전문 경로로 넘깁니다. 요금 정책이나 약관 같은 질문은 애초에 상품 DB가 아니라 문서 지식에서 답해야 합니다.
이 구조 덕분에 ③ 상담 연결이 최후 수단이 아니라 하나의 선택지가 됐습니다. 상품 관련 질의는 ①②에서, 지식 질의는 ④에서 흡수되므로 상담으로 넘어가는 비율이 줄었습니다.
5.2 매칭 정확도에 따른 3분기 안내
폴백만으로는 부족했습니다. "찾았다"와 "못 찾았다"의 이분법이 실제 상황을 표현하지 못했기 때문입니다.
이에 따라 상품 매칭 결과를 세 가지로 구분했습니다.
| 매칭 상태 | 상황 | 응답 방식 |
|---|---|---|
| 정확 일치 | 요청 조건을 모두 만족 | 해당 상품을 바로 안내 |
| 부분 일치 | 일부 조건만 만족 | 어떤 조건이 다른지 명시하고 대안으로 제시 |
| 미존재 | 만족하는 상품 없음 | 폴백 체인 다음 단계로 전이 |
부분 일치를 별도 상태로 정의한 것이 핵심이었습니다. 이전에는 부분 일치가 "찾았다"로 처리되어 조건이 다른 상품을 정확한 답인 것처럼 안내하거나, "못 찾았다"로 처리되어 유효한 대안이 버려졌습니다. 상태를 분리하고 나서야 "요청하신 조건 중 이것은 다르지만 이런 상품이 있습니다"라는 정직한 안내가 가능해졌습니다.
5.3 동적 UI 응답 빌더
폴백 체인을 만들고 나니 다른 문보였습니다. 단계마다 필요한 화면이 달랐습니다.
상품을 찾았으면 상품 카드가 필요하고, 조건을 더 물어야 하면 입력 폼이 필요하며, 상담으로 넘어가면 예약 바텀시트가 필요합니다. 이를 전부 텍스트로만 응답하면 사용자가 직접 타이핑해야 합니다.
이에 따라 응답 빌더(Response Builder) 를 두어, LLM 응답 상태에 맞는 프론트엔드 UI 컴포넌트를 함께 반환하도록 했습니다.
- 상품 카드: 검색·추천 결과가 있을 때
- 바텀시트: 선택지를 제시해야 할 때
- 진단 폼: 추가 정보를 받아야 할 때
여기서 지킨 원칙은 UI 종류를 LLM이 결정하지 않는다는 것입니다. LLM은 의도와 상태를 판정하고, 어떤 컴포넌트를 렌더링할지는 응답 빌더가 상태값을 보고 결정합니다. LLM에게 UI 스키마까지 생성시키면 형식이 흔들려 파싱 실패가 발생하기 때문입니다.
실제로 응답을 고정 템플릿 기반으로 전환하면서 평균 응답 토큰이 19.1% 줄었고, UI 컴포넌트 파싱 실패율도 함께 감소했습니다.
6. 실험 결과
| 항목 | 개선 전 | 개선 후 |
|---|---|---|
| 미식별 발화 처리 | 빈 응답 또는 대화 종료 | 4단계 폴백으로 후속 행동 제시 |
| 매칭 상태 구분 | 성공 / 실패 2분기 | 정확 · 부분 · 미존재 3분기 |
| 응답 형식 | 자유 생성 | 고정 템플릿 + 동적 UI 컴포넌트 |
| 평균 응답 토큰 | 기준 | 19.1% 절감 |
| 답변 성공률 | 78% (단일턴) | 98%+ (단일·멀티턴 평균) |
상용 오픈 1개월 시점에 주문 전환율 26%를 기록했고, 이는 전화상담 채널 대비 13배 수준이었습니다. 주말·야간 등 상담이 불가능한 시간대의 주문이 전체의 30%를 차지해, 무인 채널이 단독으로 신규 가입을 창출할 수 있음을 확인했습니다.
7. 결론 및 시사점
"못 찾았다"는 응답이 아니라 상태입니다. 검색 실패를 종착점으로 두면 대화가 끊기지만, 하나의 상태로 정의하고 그 다음 전이를 설계하면 대화가 이어집니다. 폴백 체인은 결국 실패 상태에 이름을 붙이고 각각의 다음 행동을 정의하는 작업이었습니다.
이분법이 문제를 감춥니다. 성공과 실패로만 나누던 매칭 결과를 세 단계로 늘리자, 이전에는 잘못 안내되거나 버려지던 케이스가 드러났습니다. 상태 정의가 거칠면 그 안에서 벌어지는 오류가 보이지 않습니다.
생성을 제한하면 폴백이 필요해집니다. 환각을 막기 위해 LLM이 참조할 수 있는 데이터를 제한하면, 필연적으로 "줄 수 있는 답이 없는" 상황이 늘어납니다. 환각 제어와 데드엔드 방지는 함께 설계해야 하는 한 쌍이며, 한쪽만 하면 안전하지만 쓸모없거나 유용하지만 위험한 시스템이 됩니다.
