분류 자동화 — 문의·티켓·콘텐츠를 스키마로 나누기
결정모델이 가장 자주 하는 일은 분류입니다. Choice·Score·Noul 세 스키마로 고객문의·티켓·콘텐츠를 나누는 실전을 다룹니다. 라벨 개수와 문구, none 처리, 순서형 점수와 이진 판정을 설계하는 법, state와 questions로 요청을 짜는 법, 응답의 확률과 신뢰도를 읽는 법까지 정리합니다. 이 장을 마치면 작은 분류 작업 하나를 직접 스키마로 옮길 수 있습니다.
분류는 결정모델이 가장 자주 하는 일입니다
2장에서 LLM과 결정모델을 가르는 기준(출력의 모양, 처리량과 지연, 신뢰도 요구)을 봤습니다. 그 기준을 실제 작업에 처음 대 보면 대부분 같은 자리에 도착합니다. 바로 분류입니다.
서비스 코드가 AI에 시키는 판단의 상당수는 "이 입력이 알려진 카테고리 중 어디에 속하는가"입니다. 들어온 문의를 어느 팀으로 보낼지, 이 리뷰가 긍정인지 부정인지, 이 메시지가 위험한지. 답이 정해진 집합 안에 떨어지므로 결정모델의 정확한 사용처입니다.
분류의 정의부터 좁히면 설계가 쉬워집니다
TypeSafe 문서는 작업 유형을 트리거 조건으로 구분합니다. 분류(Classification)의 조건은 "알려진 카테고리 중 하나가 확정되어야 함"입니다. 여기에 "특정 속성이 있는지"를 묻는 탐지(Detection), "순서 있는 척도 위 어디인지"를 묻는 스코어링(Scoring)이 이웃해 있습니다. 세 조건이 그대로 뒤에 나올 세 스키마에 대응합니다.
문의·티켓·콘텐츠가 대표 대상입니다
가장 흔한 세 대상은 고객문의, 지원 티켓, 사용자 콘텐츠입니다. 셋 다 비정형 텍스트가 끊임없이 들어오고, 그때마다 같은 형태의 판단을 반복해야 합니다. 대량·반복·저지연이라는 조건이 겹치니 결정모델이 앞단을 지키기에 알맞습니다. 분류 결과를 n8n 같은 워크플로 자동화로 넘겨 후속 처리를 잇는 구조도 자연스럽습니다.
세 가지 스키마로 나눕니다
분류 스키마는 1장에서 소개한 세 기본형(Choice·Score·Noul)으로 짭니다. 각 질문은 type과 instructions(무엇을 묻는지)를 공통으로 갖고, 형태에 따라 criteria의 모양이 달라집니다.
| 스키마 | criteria 형태 | 돌려주는 값 | 쓰는 자리 |
|---|---|---|---|
| Choice | 옵션명 → 설명 맵 | choice · probabilities · confidence | 라벨 하나 확정 |
| Score | 낮음→높음 순서 배열 | score · legend · probabilities · confidence | 순서형 평가 |
| Noul | 선택적 true/false 설명 | noul(0~1 확률) | 예/아니오 판정 |
Choice — 여러 라벨 중 하나를 고릅니다
Choice는 criteria에 "옵션명 → 그 옵션의 설명"을 맵으로 적습니다. 문서 권고는 분명합니다. 전체 카테고리 목록을 넣으라는 것, 축약 리스트가 아니라는 것입니다. 옵션은 최대 255개까지 허용됩니다. 응답은 고른 choice, 옵션별 probabilities(합이 1.0), 그리고 confidence(0~1)로 옵니다.
Score — 순서가 있는 척도로 평가합니다
Score의 criteria는 숫자 min/max가 아니라 낮음에서 높음으로 정렬한 레벨 설명의 배열입니다. 레벨은 2~10개를 둘 수 있습니다. 돌아오는 score는 레벨 인덱스의 확률가중평균이라 레벨 사이의 연속값도 나옵니다. 3레벨이면 0~2 사이 실수가 답이 되는 식입니다. 응답에는 인덱스가 무엇을 뜻하는지 알려주는 legend가 함께 옵니다.
Noul — 예/아니오를 하나의 확률로 답합니다
Noul은 "no"와 "null"을 합친 이름으로, 이진 질문을 맡습니다. criteria로 참/거짓의 기준을 선택적으로 덧붙일 수 있고, 응답은 {"type":"noul","noul":0.95}처럼 단일 확률 하나입니다. Choice·Score와 달리 별도의 confidence 필드가 없습니다. 확률값 자체가 답이자 확신도이기 때문입니다.
질문 스키마 설계가 결과 품질을 좌우합니다
여기가 실전에서 제일 자주 막히는 지점입니다. 모델을 바꾸는 것보다 질문을 어떻게 적었는지가 정확도를 더 크게 흔듭니다.
라벨은 빠짐없이, 문구는 헷갈리지 않게
Choice의 카테고리는 서로 겹치지 않게, 그리고 입력이 실제로 떨어질 곳을 모두 담아야 합니다. 각 옵션의 설명(criteria)이 애매하면 확률이 여러 라벨로 분산되고 신뢰도가 떨어집니다. "environment/technical"처럼 경계가 흐린 라벨을 나란히 두기보다, 어느 쪽에 넣을지 판정 기준을 설명 문구에 못 박아 두는 편이 안전합니다.
none·other 처리와 멀티라벨
목록이 모든 입력을 커버하지 못할 수 있다면 other나 none of the above를 옵션으로 추가하라고 문서가 권합니다. 이 안전판이 없으면 분류 불가한 입력이 엉뚱한 라벨로 강제 배정됩니다.
한 입력에 라벨을 여러 개 붙이는 멀티라벨은 주의가 필요합니다. Choice는 기본적으로 하나를 고르고 전체 확률분포를 돌려주는 단일 선택입니다. 여러 라벨을 동시에 달아야 한다면 각 라벨을 독립된 Noul 질문으로 쪼개는 방식이 자연스럽지만, Choice 전용 멀티라벨 패턴이 문서에 명시돼 있는지는 확인이 더 필요합니다. 단정하지 않고 이렇게 열어 둡니다.
질문은 하나의 좁은 것만 묻게 쪼갭니다
TypeSafe 문서의 설계 원칙은 "각 질문이 하나의 구체적이고 잘 범위화된 것을 물을 때 가장 잘 작동한다"입니다. 확장된 추론이 필요하거나 여러 독립 요인을 저울질해야 하는 질문이라면, 잘게 분해해 각각을 물은 뒤 결과를 코드 로직으로 조합하라고 안내합니다. "이 티켓 어떻게 처리할까"를 통째로 묻지 말고, 부서·긴급성·짜증도를 따로 물어 코드가 합치는 식입니다.
실전 — state와 questions로 요청을 짭니다
요청은 판단 대상인 state와 묻고 싶은 질문 묶음 questions로 구성됩니다. 같은 state에 대한 질문들은 한 요청 안에서 병렬로 평가됩니다.
고객문의 분류: Choice + Score + Noul을 한 번에
지원 티켓 분류가 세 스키마를 섞어 쓰는 대표 예시입니다. 부서는 Choice(billing/technical/sales), 고객의 짜증도는 Score(0~2), 긴급성은 Noul로 한 호출에 함께 묻습니다. 아래는 요청 형태를 개념적으로 보여주는 예시(illustrative)입니다.
POST https://api.typesafe.ai/v1/systemone
{
"state": "결제가 3일째 실패합니다. 급합니다.",
"questions": {
"team": { "type": "choice", "criteria": { "billing": "...", "technical": "...", "sales": "..." } },
"anger": { "type": "score", "criteria": ["차분함", "불편함", "화남"] },
"urgent": { "type": "noul", "instructions": "긴급성이 드러나는가" }
}
}
문서의 예시 응답은 team이 technical 85%, 짜증도 1.0, 긴급성 1.0으로 나옵니다. 세 판단이 각각 확률·신뢰도를 달고 돌아오니 코드가 곧바로 라우팅에 쓸 수 있습니다.
콘텐츠 모더레이션: Noul 가드레일과 severity Score
콘텐츠 검열은 Noul을 여러 개 묶는 패턴이 잘 맞습니다. 공식 가드레일 예시는 jailbreak(탈옥 시도), harmful_request, medical_advice, self_harm을 각각 Noul로 두고, 위해 수준은 4단계 Score로 함께 평가합니다. 그 결과를 정책 임계값에 통과시켜 pass·review·block·support로 가릅니다.
가드레일 정책(strict) 예시: review 임계값 0.35 · action 임계값 0.70 · severity 차단 2.0
임계값을 바꾸면 같은 모델로도 보수적/관대한 정책을 만들 수 있습니다. 이 임계값 표가 곧 팀의 검열 기준이 됩니다.
확률과 신뢰도를 읽는 법
응답을 어떻게 해석하느냐가 자동화의 안전성을 결정합니다.
probabilities·confidence, 그리고 '보정'의 뜻
Choice·Score의 응답에는 옵션별 probabilities와 별도의 confidence가 붙습니다. Score의 경우 confidence가 1.0이라는 건 모든 확률이 한 레벨에 몰렸다는 뜻입니다. 여기서 자주 오해하는 지점이 신뢰도의 "보정(calibrated)"입니다.
보정: 0.2로 예측된 사건 묶음은 실제로 약 20% 발생해야 한다는 의미. 보정은 예측 '그룹' 단위로 측정되며, 개별 답 하나의 정답을 보장하지 않습니다.
즉 신뢰도가 90%라고 그 한 건이 반드시 맞는다는 뜻은 아닙니다. 같은 90% 밴드의 답들을 모아 보면 그중 약 90%가 맞도록 맞춰졌다는 통계적 약속입니다. 1장에서 본 "타입 오류가 구조적으로 불가능"과 같은 결의 이야기입니다. 스키마 밖 값을 못 내놓는다는 구조적 보장이지, 판단이 늘 옳다는 뜻은 아닙니다.
신뢰도로 자동·보류·사람을 가릅니다
보정된 신뢰도가 있으면 분류 결과를 신뢰도 밴드로 나눠 자동화 수위를 조절할 수 있습니다. 문서가 권하는 뼈대는 3단계입니다.
| 신뢰도 밴드 | 처리 |
|---|---|
| 높음(예: >0.9) | 자동 실행 |
| 중간 | 확인 요청·검토 플래그 |
| 낮음(예: <0.5) | 사람에게 라우팅·폴백 |
정확한 경계값은 도메인과 모델 성능에 따라 다르므로, 문서는 "보수적으로 시작해 조정하라"고 안내합니다. 파괴적이거나 되돌릴 수 없는 작업일수록 임계값을 더 높게 잡는 것이 실무 감각입니다. 이런 결정모델의 도구 상세는 Jev (TypeSafe AI) 페이지에서 확인할 수 있습니다.
정리
분류는 결정모델을 처음 붙이기 가장 좋은 작업이고, 그 품질은 모델이 아니라 질문 스키마 설계에서 갈립니다. Choice·Score·Noul을 입력 모양에 맞게 고르고, 라벨과 임계값을 명확히 적고, 응답의 확률·신뢰도를 밴드로 읽어 자동/보류/사람을 나누면 됩니다.
다음 장에서는 이 분류를 응용한 라우팅을 다룹니다. 요청 복잡도를 Score로 채점해 저비용·고성능 모델로 분기하는 모델 라우팅, 의도를 Choice로 나누는 프롬프트 라우팅, 도구 실행 전 Noul로 위험을 판정하는 게이팅까지 세 가지 라우팅 패턴을 살펴보겠습니다.
