Models & Algorithms••EN

어떤 문의를 사람에게 넘겨야 할까: 분류기, 판단 모델, 사람 순서로 넘기는 시스템 실측

확실하면 분류기가 답하고, 애매하면 판단 모델이, 그래도 애매하면 사람이 받는 시스템을 만들어 쟀습니다. BANKING77에서는 판단 모델이 사람 몫을 줄이지 못했고, CLINC150에서는 모르는 질문이 기준값을 무너뜨렸습니다.

어떤 문의를 사람에게 넘겨야 할까: 분류기, 판단 모델, 사람 순서로 넘기는 시스템 실측

어떤 문의를 사람에게 넘겨야 할까: 분류기, 판단 모델, 사람 순서로 넘기는 시스템 실측

텍스트 분류 안내의 마지막 단계는 확률을 믿고 처리하는 일이었습니다. 확신이 높은 문의는 자동으로 답하고, 나머지는 사람에게 넘기는 것입니다. 이번에는 그 시스템을 직접 만들어 처음부터 끝까지 재 봤습니다. 구조는 세 단계입니다.

  1. 작은 분류기(MiniLM 임베딩과 로지스틱 회귀, CPU, 이전 기준선과 같은 구성)가 먼저 봅니다. 확률이 기준값 이상이면 그대로 답합니다.
  2. 기준에 못 미치면 분류기가 고른 후보 5개를 판단 모델에 넘깁니다. 판단 모델도 자기 확률이 두 번째 기준값 이상일 때만 답합니다. 판단 모델로는 Ollama 0.35에서 로컬로 돌린 Nimble 9B와 Tev1 4B(단독 실측), 그리고 API로 부른 Jev 1.13을 썼습니다. Jev는 후보를 줄이지 않고 선택지 전체를 주는 방식도 함께 쟀습니다.
  3. 그래도 기준에 못 미치면 사람에게 넘깁니다. 사람에게 넘긴 문의는 정답으로 세지 않습니다.

알고 싶었던 것은 두 번째 단계의 몫입니다. 같은 정확도를 지키면서 사람에게 가는 문의를 얼마나 덜어 주는지입니다.

기준값은 이렇게 정했습니다

모든 설정은 검증 세트에서 고르고, 고를 때 한 번도 보지 않은 테스트 세트에서 한 번만 채점했습니다.

  • BANKING77(은행 고객 문의, 의도 77개)은 학습 데이터 10,003건 중 의도마다 10%씩, 모두 1,003건을 떼어 검증에 쓰고 테스트 3,080건 전체로 채점했습니다.
  • CLINC150(가상 비서에게 하는 말, 의도 150개)은 공식 분할을 그대로 썼습니다. 검증 3,100건, 테스트 5,500건이고, 둘 다 어느 의도에도 맞지 않는 질문(범위 밖 질문)이 섞여 있습니다.

기준값은 검증 세트에서 자동 처리한 답의 정확도를 95%(또는 98%) 이상으로 지키면서 가장 많이 자동 처리하는 값으로 골랐습니다. 테스트 결과는 목표에 못 미쳐도 나온 그대로 적었습니다.

요약

  • BANKING77에서는 어떤 판단 모델도 사람 몫을 줄이지 못했습니다. 분류기가 자신 없어 한 문의는 Nimble, Tev1, Jev에게도 똑같이 어려웠습니다. 95% 목표에서 분류기 혼자 테스트 문의의 93.2%를 자동 처리했고 그중 96.2%가 맞았는데, 판단 모델을 붙인 구성은 모두 이 숫자와 같거나 더 낫지 않았습니다.
  • CLINC150에서는 Jev와 Nimble이 분류기가 넘긴 문의를 더 잘 맞혔습니다. 98% 목표에서 넘긴 문의에 대해 분류기의 1순위는 61.6%, Jev는 78.8%가 맞았습니다(p < 0.001). Tev1은 분류기보다 확실히 낫지 않았습니다.
  • 문제는 모르는 질문이었습니다. CLINC150은 검증 세트의 3%만 범위 밖 질문인데 테스트 세트는 18%입니다. 95%를 맞추도록 고른 기준값이 테스트에서는 84.8%에 그쳤고, 범위 밖 질문 1,000건 중 592건에 아는 질문인 것처럼 답했습니다. 판단 모델을 붙이면 더 많이 새어 나갔습니다.
  • 검증 세트에 모르는 질문을 넣자 새는 양이 절반 아래로 줄었습니다. 범위 밖 질문 250건을 검증 세트에 더하니 새는 양이 592건에서 271건으로 줄었고, 이때는 Jev를 두 번째 단계로 붙이자 오답을 늘리지 않고 사람 몫을 1.9%p 덜었습니다. 그래도 테스트에서는 95% 목표에 못 미쳤습니다.
기울기 그래프. CLINC150 테스트에서 범위 밖 질문 1,000건 중 자동으로 답해 버린 수, 95% 정확도 목표로 고른 기준값. 공식 검증 세트(범위 밖 3%)에서 범위 밖 250건을 더한 검증 세트(10.4%)로 바꾸면 분류기 단독 592에서 271, 분류기 다음 Jev(선택지 150개 전체) 749에서 269, 분류기 다음 Nimble 766에서 284, 분류기 다음 Tev1 757에서 274.

BANKING77: 두 번째 단계가 더할 것이 없었습니다

분류기 혼자도 이미 강했습니다. 테스트 문의의 92.9%를 맞혔고, 정답이 분류기 후보 5개 안에 들어 있는 경우가 99.3%였습니다. 95% 목표에서는 3,080건 중 2,871건을 자동 처리해 96.2%를 맞혔고(95% 신뢰구간 95.4-96.8%), 209건을 사람에게 넘겼습니다. 98% 목표에서는 82.9%를 자동 처리해 98.0%(97.4-98.5%)를 맞혔고 17.1%를 넘겼습니다.

두 번째 단계는 분류기가 넘긴 문의만 받습니다. 그래서 같은 문의를 두고 분류기의 1순위와 각 판단 모델의 선택을 비교하는 것이 공정합니다.

BANKING77 테스트, 분류기가 넘긴 문의95% 목표 (209건)98% 목표 (526건)
분류기 1순위47.4%67.9%
Nimble 9B, 후보 5개52.2% (p = 0.31)60.3% (p = 0.003)
Tev1 4B, 후보 5개51.2% (p = 0.46)54.9% (p < 0.001)
Jev 1.13, 후보 5개51.2% (p = 0.43)57.0% (p < 0.001)
Jev 1.13, 선택지 77개 전체47.8% (p = 1.0)55.5% (p < 0.001)

95% 목표에서는 판단 모델들이 분류기가 혼자 고른 답보다 낫지 않았고, 98% 목표에서는 오히려 뒤졌습니다. 확률도 맞는 답과 틀린 답을 충분히 가르지 못했습니다. 분류기가 넘긴 검증 문의에서 Nimble이 0.99 이상을 붙인 답도 설정에 따라 58-82%만 맞았습니다. 그런 답 자체가 10-30건뿐이었습니다. 그래서 검증 세트에서 기준값을 찾자 거의 모든 구성에서 "두 번째 단계의 답은 하나도 받지 않는다"가 골라졌습니다. 예외는 선택지 77개 전체를 준 Jev 하나로, 확률이 정확히 1.00인 답만 받았습니다. 테스트에서는 35건이 더 자동 처리됐는데, 자동 처리 비율 차이가 +0.3%p(-0.2에서 +0.7)라 없는 것과 구분되지 않습니다.

이 표에는 단서가 둘 있습니다. 하나는 Tev1입니다. Tev1은 학습 데이터에 BANKING77 3,000건이 들어 있다고 밝히고 있는데, 그런데도 여기서 분류기를 이기지 못했습니다. 다른 하나는 표본 크기입니다. "받지 않는다"는 판단은 95% 목표에서 검증 문의 83건, 98% 목표에서 195건으로 내린 것이라 작은 표본에 기댄 결정입니다.

CLINC150: 넘긴 문의에서는 두 번째 단계가 도움이 됐습니다

같은 비교를 CLINC150에서 하자 결과가 반대로 나왔습니다.

CLINC150 테스트, 분류기가 넘긴 범위 안 문의95% 목표 (48건)98% 목표 (349건)
분류기 1순위39.6%61.6%
Nimble 9B, 후보 5개66.7% (p = 0.011)69.6% (p = 0.018)
Tev1 4B, 후보 5개58.3% (p = 0.049)64.5% (p = 0.45)
Jev 1.13, 후보 5개68.8% (p = 0.007)78.8% (p < 0.001)

"분류기가 자신 없어 한 문의는 누구에게나 어렵다"는 말은 BANKING77에서는 맞았고 CLINC150에서는 틀렸습니다. 왜 갈렸는지는 이번 실행으로 알 수 없습니다. 먼저 떠오르는 설명은 BANKING77에 비슷한 의도가 많아서라는 것인데, 숫자로는 두 데이터셋이 갈리지 않았습니다. 넘긴 문의에서 분류기가 틀렸을 때 정답이 분류기의 2순위였던 비율이 BANKING77은 57-60%, CLINC150은 98% 목표에서 63%로 비슷했습니다. 자주 헷갈린 쌍도 비슷한 모양입니다. BANKING77에서는 verify_my_identity와 why_verify_identity, CLINC150에서는 user_name과 what_is_your_name이었습니다. 확실히 말할 수 있는 것은 결과가 데이터에 따라 달라진다는 것, 그러니 내 데이터에서 재 봐야 한다는 것입니다.

모르는 질문이 모든 기준값을 무너뜨렸습니다

CLINC150에는 어느 의도에도 해당하지 않는 질문도 들어 있습니다. 비서가 맡지 않는 일을 묻는 경우입니다. "해당 없음"이라는 선택지가 없는 시스템은 이런 질문을 사람에게 넘겨야 하는데, 기댈 수 있는 신호는 낮은 확률 하나뿐입니다.

CLINC150 테스트, 95% 목표로 고른 기준값자동 처리자동 처리 중 정답범위 밖 질문에 답함 (1,000건 중)사람에게
분류기 단독91.7%84.8%5928.3%
분류기 다음 Jev(후보 5개)96.8%81.7%8443.2%
분류기 다음 Jev(선택지 150개 전체)95.2%82.9%7494.8%
분류기 다음 Nimble(후보 5개)95.1%82.4%7664.9%

95%를 목표로 고른 설정이 테스트에서는 모두 82-85% 언저리였습니다. 범위 안 질문만 보면 분류기의 자동 답은 96.1%가 맞았습니다. 모자란 몫은 전부 모르는 질문에 아는 척 답한 데서 나왔습니다. 원인은 검증 세트입니다. 검증 세트는 3,100건 중 100건(3%)만 범위 밖인데, 테스트 세트는 5,500건 중 1,000건(18%)입니다. 모르는 질문이 드문 데이터로 맞춘 기준값은 그런 질문이 많이 올 것을 예상하지 못합니다. 판단 모델을 붙이면 더 나빠집니다. 판단 모델은 어떤 문의든 가장 가까운 의도를 잘 찾아내는데, 맞는 의도가 없는 질문에도 똑같이 찾아내기 때문입니다. 98% 목표에서도 같은 양상이 조금 작게 나왔습니다. 분류기 단독은 207건이 샜고, 두 번째 단계를 붙이면 190-243건이었습니다.

검증 세트에 모르는 질문을 넣으면

CLINC150의 학습 분할에는 분류기가 학습하지 않은 범위 밖 질문 250건이 따로 있습니다. 이 250건을 검증 세트에만 넣어, 모르는 질문이 섞여 있다는 것을 알고 기준값을 고르게 했습니다(검증 세트의 10.4%). 학습, 테스트, 분류기는 그대로입니다. 위 결과를 본 뒤에 추가한 조건이라 원래 결과를 대신하지 않고 옆에 나란히 둡니다.

CLINC150 테스트, 분류기 단독공식 검증 세트 (모르는 질문 3%)250건 추가 (10.4%)
95% 목표: 자동 처리 중 정답84.8%92.0%
95% 목표: 범위 밖 질문에 답함 (1,000건 중)592271
95% 목표: 사람에게8.3%18.2%
98% 목표: 자동 처리 중 정답93.6%97.3%
98% 목표: 범위 밖 질문에 답함20780
98% 목표: 사람에게20.8%30.3%

새는 양이 절반 아래로 줄었고, 사람에게 가는 몫은 10%p쯤 늘었습니다. 시스템이 모르는 질문을 사람에게 넘기기 시작한 것이니, 원래 이 시스템이 해야 할 일입니다. 다만 여전히 목표에는 못 미쳤습니다. 검증 세트의 모르는 질문 10.4%가 테스트의 18%보다 여전히 적기 때문입니다. 실제로 들어오는 문의에서 모르는 질문의 비율이 바뀌면 기준값도 다시 맞춰야 합니다.

이 조건에서는 95% 목표에서 Jev의 세 구성이 모두 사람 몫을 덜었고, 목록이 길수록 더 많이 덜었습니다. 선택지 150개 전체를 주면 1.9%p(사람 몫 18.2%에서 16.3%, 짝지은 부트스트랩 구간 1.2-2.6%p), 후보 10개면 1.2%p(0.8-1.7), 후보 5개면 0.8%p(0.2-1.4)였습니다. 세 구성 모두 오답 차이는 0과 구분되지 않았습니다(전체 목록 +0.05%p, -0.5에서 +0.6). 98% 목표에서는 선택지 전체를 준 Jev만 답을 받아 줬고, 사람 몫을 2.1%p(1.4-2.8) 덜면서 오답이 0.3%p(0.0-0.6) 늘었습니다. Nimble은 후보 10개로 0.8%p(0.04-1.5)를 덜었고, 후보 5개도 0.8%p였지만 구간이 0을 포함합니다(-0.02에서 1.6). Tev1은 덜지 못했습니다.

후보 목록과 전체 목록

여기서는 두 측정이 서로 다른 쪽을 가리켰습니다. 모든 문의를 판단 모델 혼자 분류하게 하면 짧은 목록이 조금 더 정확했습니다. BANKING77에서 Nimble은 분류기 후보 5개면 85.4%, 10개면 84.4%, 20개면 83.2%를 맞혔고, Jev는 후보 5개면 82.1%, 선택지 77개 전체면 79.9%였습니다(CLINC150에서는 92.8% 대 92.1%). 차이가 작고 검정은 하지 않았습니다. 그런데 시스템의 두 번째 단계로 놓고 보면 전체 목록이 나았습니다. 검증 세트에 모르는 질문을 넣은 조건에서 선택지 전체를 준 Jev가 사람 몫을 가장 많이 덜었고(1.9%p, 후보 10개는 1.2%p, 후보 5개는 0.8%p), 공식 검증 세트에서는 모르는 질문을 덜 통과시켰습니다(749건, 후보 5개는 844건).

속도

분류기는 CPU 스레드 4개로 한 건에 8ms가 걸렸습니다. 후보 5개를 준 두 번째 단계 호출은 로컬 모델이 중앙값 165-237ms였고(다른 작업과 함께 쓰던 A100), BANKING77에서 Nimble에 후보 10개, 20개를 주면 281ms, 385ms였습니다. 한국에서 부른 Jev는 후보 목록이든 전체 목록이든 216-221ms였습니다. 두 번째 단계는 분류기가 넘긴 문의만 받는데, 이번 설정들에서 그 비율은 전체의 7-34%였습니다. 그래서 대부분의 문의는 몇 밀리초 안에 답이 나갑니다.

이렇게 써 보세요

  • 분류기와 사람, 두 단계로 시작합니다. 분류기의 기준값은 따로 떼어 둔 데이터에서 정합니다. 두 데이터셋 모두 분류기 혼자 대부분을 처리했습니다.
  • 검증 세트에 모르는 질문을 넣습니다. 실제로 들어올 것으로 예상하는 만큼 넣습니다. 이게 없으면 안전해 보이는 기준값이 모르는 질문 대부분을 그대로 통과시킵니다.
  • 판단 모델은 분류기가 넘긴 문의에서 분류기를 이길 때만 붙입니다. 모든 문의에 돌리기 전에, 내 데이터에서 넘어간 문의를 같은 문항으로 비교해 봅니다. BANKING77이었다면 지연과 비용만 늘었을 것입니다.
  • 목록 길이는 판단 모델 혼자가 아니라 시스템 전체로 재 봅니다. 짧은 목록은 판단 모델의 개별 정답률을 조금 올렸지만, 사람 몫을 가장 많이 던 것도, 모르는 질문을 덜 통과시킨 것도 전체 목록이었습니다.

이번 결과로 말할 수 없는 것

영어 데이터셋 둘, 분류기 하나, 모델마다 한 버전만 쟀고, 라벨 이름만 주고 설명은 넣지 않았습니다. 두 번째 단계의 기준값은 0.05 간격으로 찾았는데, Jev 확률은 소수 둘째 자리로 반올림돼 나와서 기준값을 그보다 세밀하게 정할 수 없습니다. 일부 판단은 작은 표본에 기댔습니다. BANKING77 95% 목표에서 넘긴 검증 문의는 83건, CLINC150은 범위 안 문의 33건이었습니다. 로컬 모델의 속도는 다른 작업과 GPU를 나눠 쓰는 동안 잰 값입니다. 모르는 질문을 더한 검증 세트는 첫 결과를 본 뒤에 추가한 조건이고, 그래도 테스트 세트보다 모르는 질문이 적습니다. 문의 한 건의 비용과 사람의 시간이 얼마짜리인지는 재지 않았습니다.

책의 앞부분은 지금 읽을 수 있습니다: 2장 첫 기준선, 코드 포함.

이 시스템을 처음부터 끝까지 만드는 책을 쓰고 있습니다

BANKING77 예제 하나로 데이터 분할, 분류기, 판단 모델, 모르는 문의 넘기기, 운영까지 따라갑니다. 이메일을 남겨 주시면 책이 나올 때 한 번 알려 드립니다.

출시 알림 한 번 외에는 메일을 보내지 않습니다.

실험 설정: 분류기는 sentence-transformers/all-MiniLM-L6-v2와 scikit-learn 로지스틱 회귀(C = 10)이고, 검증 세트의 범위 안 문의로 음의 로그우도를 최소화해 온도를 맞췄습니다(BANKING77 T = 0.75, CLINC150 T = 0.63). BANKING77 분할은 학습 데이터 10,003건에서 의도마다 10%를 떼어 학습 9,000건, 검증 1,003건으로 나눴습니다(시드 20261001). 테스트는 3,080건입니다. CLINC150은 "plus" 구성의 범위 안 학습 15,000건, 공식 검증(3,000건 + 범위 밖 100건)과 테스트(4,500건 + 범위 밖 1,000건)를 썼고, 변형은 학습 분할의 범위 밖 250건을 검증에 더했습니다. 두 번째 단계는 /v1/systemone으로 불렀습니다. Nimble(nimble:latest)과 Tev1(tev1:4b)은 Ollama 0.35.0에서 OLLAMA_LLM_LIBRARY=cuda_v13로 A100 80GB 한 장에서 돌렸고, Jev는 jev-1.13.0을 api.typesafe.ai로 네 건씩 동시에 불렀습니다. 지시문은 이전 글과 같고, 선택지는 라벨 이름만 줬습니다. 두 번째 단계 호출은 모두 94,614건이었고 실패는 없었습니다. 분류기 기준값은 검증 세트의 분류기 확률 값에서, 두 번째 단계 기준값은 0에서 1까지 0.05 간격에서 찾았고, 검증 세트에서 자동 처리 정확도가 목표 이상인 설정 중 자동 처리 비율이 가장 큰 것을 골랐습니다. 정확도의 신뢰구간은 Wilson, 같은 문의를 두고 한 비교는 정확 McNemar 검정, 시스템 전체의 차이는 테스트 문의를 2,000번 다시 뽑은 짝지은 부트스트랩 구간입니다. 스크립트는 scripts/jev-bench/route_cascade.py, 결과는 `drafts/jev-bench/results/route-.json`입니다. 측정일 2026-10-02.*

이 글과 이어지는 강좌

SOTAAZ 강좌

강좌는 하나씩 살 수 있습니다. 13개 전체가 필요하면 $199 평생 번들도 있습니다.

더 많은 콘텐츠를 받아보세요

SNS에서 새로운 글과 튜토리얼 소식을 가장 먼저 받아보세요

이메일로 받아보기

관련 포스트

Jeff vs Jev, 같은 문항으로 재 보니: 종합 점수와 선택지 26개 한계(v1.1에서 해결)
Models & Algorithms

Jeff vs Jev, 같은 문항으로 재 보니: 종합 점수와 선택지 26개 한계(v1.1에서 해결)

Jeff 자체 벤치마크 4,599문항에서 Jev 85.7, Jeff-2B 83.0이었습니다. README의 83.1 대 83.0은 다른 표본끼리 비교한 값입니다. 제 측정에서 Jeff v1.0은 27번째 이후 선택지를 고르지 않았고, v1.1에서 고쳐졌습니다.

Kev vs Jev: Kev 0.8B~9B와 Jev의 정확도·확률 보정 비교
Models & Algorithms

Kev vs Jev: Kev 0.8B~9B와 Jev의 정확도·확률 보정 비교

같은 문장 1,629개(요청 2,329건)에 Kev(0.8B, 4B, 9B)와 Jev 1.13을 돌렸습니다. Kev가 학습한 데이터셋 세 개에서는 Kev-9B가 같거나 앞섰고(TREC 93.8% 대 89.0%), 처음 보는 세 개 중 두 개에서는 Jev가 앞섰습니다(CLINC150 68.5% 대 62.0%, MASSIVE 82.9% 대 76.0%). Jev 확률은 실제 정확도보다 높게 나오고 소수 둘째 자리로 반올림돼 있어서, BANKING77에서는 정확도 95%를 지키는 임계값이 없었습니다.

판단 모델은 라벨 몇 개의 값어치일까: Kev가 처음 보는 과제 세 개 실측
Models & Algorithms

판단 모델은 라벨 몇 개의 값어치일까: Kev가 처음 보는 과제 세 개 실측

Kev가 학습하지 않은 CLINC150, MASSIVE, 금융 뉴스 트윗에서 Kev-9B의 정확도는 클래스마다 라벨 2~20개로 학습한 작은 분류기와 비슷했습니다. 확률은 실제 정답률보다 10~17%p 낮게 나왔고(보정 오차 11~17%, 익숙한 데이터에서는 2~9%), 정확도 95% 기준으로 자동 통과시킬 수 있는 비율은 23~58%였습니다. 선택지에 없는 질문에는 낮은 확률을 붙여서 100개 중 5개만 그 기준을 넘었습니다. 0.8B 모델은 금융 트윗 200개 중 152개를 'Financials'로 답했습니다.