🏷️ 멀티 레이블 카테고리 분류 + 라우팅
단일 레이블 → JSON 배열 다중 카테고리 · HAZMAT/COLD/EXPRESS 결합 라우팅 · 1월 분류 오류 해소 · 김지훈 수석연구원
1월 RT-O1의 분류 모델은 STD / EXPRESS / COLD를 mutually-exclusive 단일 레이블로 다뤘다. 그러나 실제 주문에는 "냉장(COLD_CHAIN) + 당일(EXPRESS)" 같은 복합 조건이 존재하며, 이를 단일 레이블로 강제할 경우 모델은 한 쪽만 선택해 라우팅 실패를 일으킨다. 1월 분류 오류 27건 중 21건이 이 충돌 케이스였다.
RT-O3는 카테고리를 EXPRESS / COLD_CHAIN / FRAGILE / OVERSIZED / HAZMAT 5종의 non-exclusive 레이블 집합으로 재정의하고, LLM에는 JSON mode로 배열 응답을 강제한다. 응답은 Pydantic 2.x strict schema로 검증되어 enum을 벗어나거나 빈 배열일 경우 즉시 escalate 분기로 빠진다. 라우팅 단계에서는 가장 제약이 강한 카테고리를 우선하는 룰셋(HAZMAT > COLD+EXPRESS > …)을 적용해, 위험물·콜드체인 거점이 누락되지 않도록 보장한다.
주문 메타(SKU·weight·temp_req·flammable·dim)를 파싱해 분류기 입력 벡터로 정규화.
LLM(JSON mode) 또는 transformer multi-label 분류기 호출 → categories: string[] 응답.
Pydantic 2.x로 enum·길이·중복 검증. 누락/위반 시 escalate 분기.
HAZMAT > COLD+EXPRESS > … 우선순위 매핑으로 특수 거점 선택.
우선순위에 걸리지 않는 일반 케이스는 dom_score_engine로 fallback 라우팅 (RT-O1 모델 재사용).
# category 필드를 단일 값에서 배열로 확장 # 기존: {"category": "EXPRESS"} # 변경: {"categories": ["EXPRESS", "COLD_CHAIN"]} classification_prompt = """ 주문을 분석하여 해당하는 모든 카테고리를 JSON 배열로 반환하세요. 가능한 카테고리: EXPRESS, COLD_CHAIN, FRAGILE, OVERSIZED, HAZMAT 형식: {"categories": ["카테고리1", "카테고리2"]} """ class CategoryEnum(str, Enum): EXPRESS = "EXPRESS" COLD_CHAIN = "COLD_CHAIN" FRAGILE = "FRAGILE" OVERSIZED = "OVERSIZED" HAZMAT = "HAZMAT" class ClassificationOut(BaseModel): categories: List[CategoryEnum] = Field(min_length=0, max_length=5)
def route_order(order, categories): # 가장 제약이 강한 카테고리 우선 적용 if "HAZMAT" in categories: return route_to_hazmat_certified_node(order) if "COLD_CHAIN" in categories and "EXPRESS" in categories: return route_to_cold_express_node(order) # 특수 거점 # 일반 DOM 라우팅 return dom_score_engine.route(order, categories)
단일 레이블 시절 사용하던 accuracy는 다중 레이블에서 희석되므로(샘플당 0/1 평가가 부적절), per-class F1의 macro 평균과 composite_match를 KPI로 사용한다. composite_match는 2개 이상 레이블이 동시에 붙은 케이스에서 모든 레이블을 정확히 맞춘 비율이다.
| EXP | COLD | FRA | OVR | HAZ | |
|---|---|---|---|---|---|
| EXP | 100 | 22 | 18 | 9 | 2 |
| COLD | 22 | 100 | 14 | 4 | 1 |
| FRA | 18 | 14 | 100 | 11 | 1 |
| OVR | 9 | 4 | 11 | 100 | 0 |
| HAZ | 2 | 1 | 1 | 0 | 100 |
EXPRESS×COLD_CHAIN(22)이 가장 빈번한 복합 조건이며, 이는 1월에 오류를 일으킨 바로 그 케이스다. RT-O3의 route_to_cold_express_node()분기는 이 조합 전용 거점(현재 NODE-D 1개) 으로 라우팅한다. HAZMAT은 타 카테고리와 거의 결합되지 않아 단독 처리 비중이 높다.
[1] 김지훈, "멀티 레이블 카테고리 분류 + 우선순위 라우팅", IntraLogis 사내 보고서, 2026.02
[2] Tsoumakas, G., Katakis, I. "Multi-Label Classification: An Overview", IJDWM, 2007
[3] Read, J., Pfahringer, B., Holmes, G., Frank, E. "Classifier Chains for Multi-label Classification", ECML-PKDD, 2009
[4] OpenAI, JSON Mode Documentation, 2024
[5] Pydantic, Pydantic 2.x Strict Schema Validation Docs, 2025
[6] 한국산업표준, KS C IEC 60079 위험물 분류 표준