docs: 제로샷 의도 분류 방식으로 전환 (3.4.3)

- Snips 학습 기반 → 제로샷 의도 설명 기반 전환
- Hong et al.(SIGDIAL 2024) 연구 반영
- 다국어 임베딩(mpnet) + 후보 축소 방식 적용
- 의도 설명만 수정하면 즉시 반영되는 유연한 구조
- LLM 호출 90% 절감 예상

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
happybell80 2025-09-09 20:58:51 +09:00
parent 651004edfc
commit 743481cce5

View File

@ -270,29 +270,73 @@ if pattern_matches(NEGATIVE_FEEDBACK_PATTERNS):
return apologize_and_clarify()
```
### 3.4.3 Snips + Self-Attentive Gate 통합
### 3.4.3 제로샷 의도 분류 통합 (Hong et al., 2024 기반)
최신 SIGDIAL 2024 연구에 따르면, 고품질 의도 설명 1개와 임베딩 기반 후보 축소가 핵심입니다.
```python
class TimeAwareIntentClassifier:
class ZeroShotTimeAwareClassifier:
def __init__(self):
self.snips = SnipsNLU() # 경량 의도 분류
# 제로샷: 학습 없이 의도 설명만으로 분류
self.intent_descriptions = {
"attendance": "출근, 퇴근, 재택근무 같은 근태를 기록하려는 요청",
"time_query": "현재 시각, 날짜, 요일을 묻는 질문",
"context_retrieval": "아까, 어제, 방금 전 같은 과거 대화를 참조하는 요청",
"email": "이메일 확인, 전송, 검색과 관련된 요청",
"schedule": "일정 조회, 등록, 수정에 대한 요청"
}
# 다국어 임베딩 (한국어 지원, Snips 대체)
self.embedder = SentenceTransformer('paraphrase-multilingual-mpnet-base-v2')
self.gate = SelfAttentiveGate() # 시간 게이트
async def classify_with_time(self, text, user_id):
# Step 1: Snips로 빠른 의도 분류 (50ms)
intent = self.snips.classify(text)
# Step 1: 임베딩 기반 후보 축소 (20ms)
text_emb = self.embedder.encode(text)
intent_scores = {}
# Step 2: Gate로 시간 필요 여부 결정 (10ms)
needs_time = self.gate.needs_temporal_context(intent)
for intent, description in self.intent_descriptions.items():
desc_emb = self.embedder.encode(description)
score = cosine_similarity(text_emb, desc_emb)
intent_scores[intent] = score
# Step 3: 선택적 시간 컨텍스트 추가
if needs_time:
context = await self.enrich_temporal_context(text, user_id)
else:
context = {}
# 상위 3개 후보만 선택 (Hong et al. 권장: 10-13개, 로빙은 3개면 충분)
top_candidates = sorted(intent_scores.items(),
key=lambda x: x[1],
reverse=True)[:3]
# Step 2: 확신도 체크 및 시간 게이트
best_intent = top_candidates[0][0]
confidence = top_candidates[0][1]
# Step 3: 시간 컨텍스트 선택적 추가
context = {}
if best_intent in ['time_query', 'attendance', 'context_retrieval']:
context['current_time'] = datetime.now(KST).strftime("%Y년 %m월 %d일 %H:%M")
context['needs_time'] = True
return {"intent": intent, "context": context}
# Step 4: 저확신 시 LLM 폴백
if confidence < 0.7:
# 의도 설명을 포함한 프롬프트로 LLM 호출
prompt = f"사용자: {text}\n후보 의도:\n"
for intent, score in top_candidates:
prompt += f"- {intent}: {self.intent_descriptions[intent]} (점수: {score:.2f})\n"
context['needs_llm'] = True
return {
"intent": best_intent,
"confidence": confidence,
"context": context,
"candidates": top_candidates
}
```
#### 제로샷 방식의 장점 (로빙 적용)
1. **학습 데이터 불필요**: Snips와 달리 의도 설명만 수정하면 즉시 반영
2. **비용 절감**: 임베딩 후보 축소로 LLM 호출 90% 감소
3. **한국어 최적화**: 다국어 임베딩 모델로 한국어 성능 우수
4. **유연한 확장**: 새 의도 추가 시 설명 한 줄만 추가
---
## 4. 데이터 구조