# 짧은 후속 질문 컨텍스트 유지 3단계 구현 완료

**날짜**: 2025-11-17  
**작성자**: Claude Code  
**관련 파일**:  
- rb8001/app/brain/decision_engine.py:264-316 (CONTEXT_FOLLOWUP Intent 추가 및 패턴 매칭)  
- rb8001/app/brain/decision_engine.py:437-439 (CONTEXT_FOLLOWUP 스킬 시퀀스)  
- rb8001/app/router/router.py:218-263 (CONTEXT_FOLLOWUP 처리 및 세션 슬롯 관리)  
- rb8001/app/brain/session_manager.py (3단계: 멀티턴/슬롯필링 세션 관리)  
- rb8001/tests/test_intent_entity_skill_comprehensive.py:83-253 (3단계 테스트)  

---

## 문제 상황

- 사용자: "11월 18일 오전 6시 40분에 검진이 있습니다" → RoBeing 응답 OK  
- 이어서 사용자: "어디서?"  
- 실제 동작: 짧은 질문이 UNKNOWN → understand 액션으로 전달 → LLM이 "오늘 일정 정리해 드릴까요?"처럼 **새 대화로 오인**  
- 근본 원인: 짧은 후속 질문에 대한 별도 Intent/처리 경로가 없어서, **직전 발화/대화 맥락을 강제 참조하지 못하는 구조**  

---

## 해결 방안 (3단계 TDD 구현)

### 1단계: CONTEXT_FOLLOWUP Intent 추가 (FastPath)

**구현 내용**:
- `IntentType.CONTEXT_FOLLOWUP` 추가 (decision_engine.py:67-68)
- 정규식 패턴 매칭: "어디서?", "언제?", "누구랑?", "뭐야?" 등 (decision_engine.py:271-277)
- 컨텍스트가 있을 때만 CONTEXT_FOLLOWUP으로 분류 (decision_engine.py:266-291)
- router에서 CONTEXT_FOLLOWUP 감지 시 직전 발화를 LLM 프롬프트에 포함 (router.py:218-240)

**테스트**: test_context_followup_intent_detection, test_context_followup_without_context_falls_back, test_context_followup_retrieves_previous_message

### 2단계: 임베딩 기반 의도/맥락 분류

**구현 내용**:
- 정규식 패턴 매칭 실패 시 임베딩 기반 분류 시도 (decision_engine.py:293-316)
- 직전 발화와 현재 메시지를 결합하여 임베딩 유사도 계산
- 확신도 ≥0.5이면 CONTEXT_FOLLOWUP으로 분류
- SemanticIntentClassifier 활용 (기존 인프라 재사용)

**테스트**: test_embedding_based_context_followup_detection, test_embedding_fallback_when_pattern_mismatch

### 3단계: 멀티턴/슬롯필링 기반 대화 관리

**구현 내용**:
- `SessionManager` 클래스 추가 (session_manager.py)
- 사용자별 세션 상태 유지 (3~5턴, 10분 TTL)
- 슬롯 구조: 날짜, 시간, 장소 등 (calendar_event Intent 기준)
- router에서 calendar_event Intent 감지 시 슬롯 자동 추출 (router.py:242-263)
- CONTEXT_FOLLOWUP 처리 시 슬롯 정보도 LLM에 전달 (router.py:226-234)

**테스트**: test_slot_filling_for_calendar_event, test_multi_turn_conversation_state_persistence (TODO: Redis 마이그레이션 후 완전 구현)

---

## 구현 완료 (커밋 해시)

- feat: add CONTEXT_FOLLOWUP Intent for short followup questions (1단계)
- feat: add embedding-based context followup detection (2단계)
- feat: add session manager for multi-turn slot filling (3단계)

---

## 교훈

### 1. TDD 원칙 준수
- 테스트 먼저 작성 (Red) → 구현 (Green) → 리팩터 순서로 진행
- 각 단계별로 독립적인 테스트 작성으로 점진적 확장 가능

### 2. 기존 인프라 재사용
- SemanticIntentClassifier를 2단계에서 재사용하여 추가 의존성 없이 구현
- 기존 router 구조를 최소한으로 수정하여 안정성 유지

### 3. 점진적 확장 설계
- 1단계: 정규식 FastPath (즉시 적용 가능)
- 2단계: 임베딩 폴백 (패턴 매칭 실패 시)
- 3단계: 세션/슬롯 관리 (향후 Redis 마이그레이션 가능하도록 설계)

### 4. 컨텍스트 강제 참조
- CONTEXT_FOLLOWUP Intent는 컨텍스트가 필수이므로, 컨텍스트 없이는 다른 Intent로 폴백
- router에서 직전 발화를 LLM 프롬프트에 명시적으로 포함하여 "새 대화로 오인" 방지

---

## 후속 작업 (제안)

1. **Redis 마이그레이션**: 메모리 기반 SessionManager를 Redis로 전환하여 서버 재시작 시에도 세션 유지
2. **슬롯 추출 개선**: 현재는 간단한 정규식 휴리스틱 사용, LLM 기반 엔티티 추출로 정확도 향상
3. **프론트엔드 통합 테스트**: happybell80 (UUID: 53529291-5050-4daa-89fb-008b546feb63) 사용자로 실제 시나리오 테스트
4. **Human-in-the-loop 연동**: CONTEXT_FOLLOWUP Intent도 리뷰 큐에 포함하여 자주 틀리는 패턴 보완

---

**작성일**: 2025-11-17  
**상태**: ✅ 3단계 구현 완료, 프론트엔드 테스트 대기 중

