# 짧은 후속 질문 컨텍스트 유실 개선 3단계 계획

**날짜**: 2025-11-17  
**작성자**: Claude Code  
**관련 파일**:  
- rb8001/app/brain/decision_engine.py  
- rb8001/tests/test_intent_entity_skill_comprehensive.py  
- DOCS/journey/plans/251017_intent_analysis_improvement_plan.md  
- DOCS/journey/troubleshooting/251117_human_in_the_loop_intent_learning.md  

---

## 1. 문제 요약

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

---

## 2. 목표

1. "어디서?", "언제?", "누구랑?" 같은 **짧은 후속 질문**이 항상 직전 발화/대화 맥락과 연결되도록 한다.  
2. 비용 제약 없이, **정규식 FastPath → 임베딩 기반 의도 분류 → 멀티턴/슬롯필링**까지 단계적으로 설계한다.  
3. 기존 DecisionEngine/테스트 구조를 유지하면서, 점진적으로 확장 가능한 형태로 설계한다.  

---

## 3. 1단계: 짧은 후속 질문 전용 Intent 추가 (FastPath)

### 3.1 설계

- 새 IntentType 추가: `CONTEXT_FOLLOWUP` (이름은 구현 시 팀 합의)  
- intent_patterns에 짧은 후속 질문 패턴 추가 (예시):  
  - `r"^어디서[요]?$"`  
  - `r"^언제[요]?$"`  
  - `r"^누구(랑|하고)?[요]?$"`  
  - `r"^뭐[야|였어]?$"`  
- 규칙:  
  - 이 패턴이 매칭되면 **무조건 CONTEXT_FOLLOWUP** 으로 분류 (UNKNOWN으로 보내지 않음).  
  - 현재 발화만으로 판단하지 않고, **직전 1~3턴의 메시지**를 강제 참조하도록 DecisionEngine에 후속 처리 경로 추가.  

### 3.2 처리 흐름

1. DecisionEngine에서 CONTEXT_FOLLOWUP 감지.  
2. 대화 로그/메모리에서 **가장 최근의 "장소/시간/대상"이 포함된 발화**를 검색.  
3. LLM 프롬프트에 아래 정보를 함께 전달:  
   - 현재 질문: "어디서?"  
   - 직전 발화: "11월 18일 오전 6시 40분에 검진이 있습니다"  
   - 관련 메모리(예: 병원명, 의료기관 기록 등)  
4. LLM에게 **"후속 질문으로, 위 직전 발화를 기준으로 답하라"** 는 제약을 명시.  

### 3.3 테스트 전략

- `rb8001/tests/test_intent_entity_skill_comprehensive.py` 또는 별도 테스트 파일에 케이스 추가:  
  - 대화 시나리오: ["내일 아침에 건강검진 있어", "어디서?"] → 장소가 포함된 응답 기대.  
  - ["내일 오전 10시에 미팅 있어", "언제?"] → 시간 재응답.  
- 기대 행동:  
  - Intent: `CONTEXT_FOLLOWUP`  
  - UNKNOWN 비율 감소, understand 액션 호출 없이도 적절한 핸들링 가능.  

---

## 4. 2단계: 임베딩 기반 의도/맥락 분류 + LLM 폴백

### 4.1 설계

- 251017 문서에서 제안한 **정규식 FastPath + 임베딩 + LLM 3단계 구조**를, CONTEXT_FOLLOWUP에도 확장.  
- 핵심 아이디어:  
  - "어디서?" 자체만 보면 모호하지만,  
  - 직전/과거 발화와의 **임베딩 유사도**로 "장소 관련 후속 질문"임을 더 강하게 판단.  

### 4.2 처리 흐름 (의사 단계)

1. 정규식 FastPath에서 패턴 매칭 실패 또는 확신도 낮음.  
2. 임베딩 엔진으로 현재 발화 + 최근 N턴 발화를 임베딩.  
3. 후보 의도들(예: `calendar_query`, `context_followup`, `general_chat` 등)의 description 임베딩과 유사도 비교.  
4. 상위 3개 의도 + 유사도 스코어를 계산:  
   - 확신도 ≥ 0.8 → 해당 의도로 결정.  
   - 0.5 ≤ 확신도 < 0.8 → LLM에게 top-3 후보와 함께 전달, 최종 선택 요청.  
   - 확신도 < 0.5 → LLM general understand로 폴백.  

### 4.3 기대 효과

- 짧은 질문이라도, **직전 발화와의 관계**를 임베딩 수준에서 반영.  
- DecisionEngine의 UNKNOWN 경로 유입을 줄이고, LLM 호출도 불필요하게 늘리지 않도록 제어.  
- 향후 Human/LLM-in-the-loop 라벨링과 결합 시, 의도 prototype 업데이트로 정밀도 향상.  

---

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

### 5.1 설계

- Redis 등 외부 스토리지를 사용해 **세션 단위로 3~5턴 대화 상태를 유지**.  
- 각 세션에 대해 **슬롯 구조**를 정의:  
  - 예: `calendar_event` → {날짜, 시간, 장소, 대상, 목적}  
- 사용자의 후속 질문은, 이 슬롯 구조를 기반으로 해석:  
  - "어디서?" → `장소` 슬롯 재질문/확인  
  - "언제?" → `시간` 슬롯 재질문/확인  

### 5.2 처리 흐름

1. 사용자가 "검진 일정 잡아줘" → Phase 1/2의 의도 분석을 거쳐 `calendar_event`로 분류.  
2. 시스템이 슬롯 채우기 진행 (날짜, 시간, 장소 등).  
3. 후속 질문 발생 시, 현재 세션의 슬롯 상태를 조회:  
   - 이미 채워진 값이 있으면, 그 값을 기준으로 답변.  
   - 값이 없으면, LLM이 추가 질문 또는 기본값 제안.  

### 5.3 비용 및 운영 관점

- LLM 호출 횟수는 증가하지만, **세션/슬롯 상태 관리를 통해 재질문/중복 호출을 줄일 수 있음**.  
- Redis 세션 TTL, 슬롯 수 제한 등을 통해 메모리/비용 관리 가능.  
- 사람 개입(Human-in-the-loop) 또는 LLM-in-the-loop 리뷰 큐와 결합해, 자주 틀리는 패턴을 우선적으로 보완.  

---

## 6. 정리

1. 1단계: CONTEXT_FOLLOWUP Intent + 패턴 추가로, 짧은 후속 질문을 UNKNOWN에서 분리.  
2. 2단계: 임베딩 기반 의도/맥락 분류와 LLM 폴백으로, "어디서?" 같은 질문도 직전 발화와 안정적으로 연결.  
3. 3단계: 멀티턴/슬롯필링 구조를 도입해, 일정/검진/회의 등 복합 작업 흐름에서 자연스러운 후속 질문 처리를 지원.  

