docs: plan 문서 추가 간결화 (584줄 삭제)

This commit is contained in:
happybell80 2025-12-04 22:12:19 +09:00
parent a60d3c903b
commit 4818ea13e3
3 changed files with 173 additions and 544 deletions

View File

@ -1,247 +1,69 @@
# 서비스 재구조화 계획 - API 게이트웨이 및 모니터링 분리
# 서비스 재구조화 계획
**작성일**: 2025-08-07
**작성자**: happybell80 & Claude
**날짜**: 2025-08-07
**상태**: 계획 단계
## 현재 문제점
### 1. 복잡한 연결 구조
- frontend-customer와 로빙 직접 연결 부재
- `/api/assistant/{id}` 엔드포인트 미구현
- 어떤 사용자가 어떤 로빙과 연결되는지 결정 로직 없음
### 2. 인증 흐름 불완전
- auth-server에서 인증 → frontend로 토큰 전달 경로 없음
- 로빙이 사용자 인증 정보 받는 방법 없음
- OAuth 콜백 후 frontend로 돌아가는 로직 부재
### 3. 데이터베이스 분산
- PostgreSQL (auth-server) - users, workspaces
- ChromaDB (51124) - 벡터 메모리
- SQLite (각 로빙) - 로컬 데이터
- user_id 동기화 문제
### 4. 서비스 역할 혼재
- frontend-base가 admin UI + 백엔드 역할 혼재
- 모니터링과 라우팅이 분리되지 않음
## 현재 서버 구조
### 51123 서버 (메인 서버)
```
├── frontend-customer (https://ro-being.com/)
│ └── React 정적 파일, nginx 직접 서빙
├── frontend-base:8000 (https://ro-being.com/admin)
│ └── 관리자 대시보드 + 백엔드
├── auth-server (https://auth.ro-being.com)
│ └── OAuth 인증, PostgreSQL DB
└── nginx (리버스 프록시, SSL)
```
### 51124 서버 (로빙/스킬 서버)
```
├── 로빙 컨테이너
│ ├── rb8001:8001 (프로덕션)
│ ├── rb10508_micro:10508 (테스트)
│ └── rb10408:10408 (테스트)
├── 스킬 서비스
│ ├── skill-email:8501 (Gmail 연동)
│ ├── skill-news:8505
│ ├── skill-embedding:8515 (포트 변경됨)
│ └── skill-slack (멀티봇 지원)
└── ChromaDB (벡터 DB)
```
## 제안하는 새 구조
### 1단계: 서비스 분리
#### robeing-gateway (구 frontend-base 일부)
- **위치**: 51123 서버
- **포트**: 8000 (기존 유지)
- **역할**:
- API 게이트웨이 (사용자 요청 → 로빙 라우팅)
- 인증 체크 (auth-server 연동)
- 사용자-로빙 매핑 (메모리 캐시)
- 캐시 관리: 로그인 시 추가, 로그아웃 시 제거
#### robeing-control (구 frontend-base 일부)
- **위치**: 51123 서버
- **포트**: 9023
- **역할**:
- 전체 시스템 모니터링 통합
- admin 대시보드 UI 제공
- 23서버 프로세스 직접 체크
- 24서버 상태는 API로 조회
- 향후 간단한 관제 기능 추가 가능
#### robeing-monitor (신규)
- **위치**: 51124 서버
- **포트**: 9024
- **역할**:
- 24서버 로컬 모니터링
- 로빙 상태 체크
- 스킬 서비스 상태
- 리소스 사용량 수집
- API로 정보 제공
### 2단계: 인증 흐름 개선
```mermaid
sequenceDiagram
participant U as User
participant F as Frontend
participant G as Gateway
participant A as Auth
participant R as Robeing
U->>F: 로그인 클릭
F->>G: /api/auth/login
G->>A: OAuth 시작
A->>U: Google OAuth
U->>A: 인증 완료
A->>G: 토큰 + user_id
G->>F: 로그인 성공 (user_id)
F->>U: 로그인 완료
U->>F: 채팅 입력
F->>G: /api/chat (user_id 포함)
Note over G: 메모리 캐시 확인<br/>없으면 DB 조회 후 캐싱
G->>R: 프록시 (port 8001)
R->>G: 응답
G->>F: 응답
F->>U: 표시
```
**수정된 흐름 설명:**
1. 로그인 완료 후 Frontend는 user_id만 알면 됨
2. 모든 API 요청에 user_id 포함 (JWT 토큰 또는 헤더)
3. Gateway가 메모리 캐시 확인 (대부분 여기서 처리)
- 캐시 hit: 즉시 라우팅
- 캐시 miss: DB 조회 후 캐싱
4. Gateway가 적절한 로빙으로 프록시
5. Frontend는 로빙 포트를 전혀 알 필요 없음
### 3단계: 데이터베이스 통합
#### 단기 계획
- auth-server PostgreSQL을 메인 DB로 사용
- user_id를 모든 서비스에서 통일
- user_id → robeing_port 매핑 테이블 관리
#### 장기 계획
- 로빙별 SQLite → PostgreSQL 마이그레이션
- 중앙 집중식 데이터 관리
### 4단계: API 설계
#### robeing-gateway API
```
POST /api/auth/login # 로그인 시작
GET /api/auth/callback # OAuth 콜백
POST /api/auth/logout # 로그아웃
GET /api/auth/status # 인증 상태
POST /api/chat # 채팅 (자동 라우팅)
GET /api/robeing/info # 할당된 로빙 정보
```
#### robeing-control API
```
GET /admin # 대시보드 UI
GET /api/monitor/overview # 전체 시스템 상태
GET /api/monitor/23 # 23서버 상태
GET /api/monitor/24 # 24서버 상태 (robeing-monitor 호출)
POST /api/control/restart # 서비스 재시작 (향후)
```
#### robeing-monitor API
```
GET /api/status/robeings # 로빙 상태
GET /api/status/skills # 스킬 상태
GET /api/status/resources # 리소스 사용량
GET /api/health # 헬스체크
```
## 구현 우선순위
### Phase 1
1. robeing-gateway 기본 구조 생성
2. 인증 흐름 연결
3. 단순 라우팅 (모든 사용자 → rb10508_micro)
### Phase 2
1. robeing-monitor 구현
2. robeing-control 분리
3. 모니터링 대시보드 연결
### Phase 3
1. 사용자-로빙 매핑 로직
2. 워크스페이스 기반 할당
3. 로빙 포트 자동 할당
### Phase 4 (선택)
1. 간단한 관제 기능
2. DB 통합
3. 성능 최적화
## 기대 효과
1. **명확한 책임 분리**
- 각 서비스가 단일 역할만 수행
- 유지보수 용이
2. **독립적 배포**
- 서비스별 독립 배포 가능
- 장애 격리
3. **확장성**
- 로빙 추가 시 gateway만 수정
- 모니터링 기능 점진적 확장
4. **보안 강화**
- 중앙 집중식 인증
- 로빙 직접 접근 차단
## 리스크 및 대응
1. **개발 복잡도**
- 리스크: 서비스 분리로 인한 복잡도
- 대응: Phase별 점진적 구현
2. **기존 서비스 중단**
- 리스크: 마이그레이션 중 서비스 중단
- 대응: 병렬 운영 후 전환
3. **복잡도 증가**
- 리스크: 서비스 개수 증가
- 대응: 명확한 문서화, 자동화 도구
## 추가 통합 계획 (2025-08-17)
### Email Skill 통합
- Gmail OAuth 토큰 관리: PostgreSQL 기반
- 토큰 위치: auth-server/tokens/ → DB 이전 예정
- 멀티 로빙 지원: 각 로빙별 Gmail 계정 매핑
### Slack 멀티봇 지원
- rb8001: robeing 봇
- rb10408: hj-robeing 봇
- 봇 토큰 중앙 관리 필요
## 다음 단계
1. [ ] 팀 리뷰 및 승인
2. [ ] 상세 API 스펙 작성
3. [ ] 개발 환경 구성
4. [ ] Phase 1 구현 시작
5. [ ] Email/Slack 토큰 DB 마이그레이션
---
## 참고사항
## 현재 문제
- 이 계획은 초안이며, 구현 과정에서 수정될 수 있음
- 기존 frontend-base의 코드를 최대한 재활용
- 서버팀과 사전 협의 필요 (포트, 도메인 등)
1. frontend-customer와 로빙 직접 연결 부재
2. 인증 흐름 불완전 (OAuth → frontend 토큰 전달 없음)
3. DB 분산 (PostgreSQL, ChromaDB, SQLite) - user_id 동기화 문제
4. 서비스 역할 혼재 (frontend-base가 admin UI + 백엔드)
---
## 제안 구조
### robeing-gateway (51123:8100)
**역할**:
- API 게이트웨이 (사용자 → 로빙 라우팅)
- JWT 인증 체크
- 사용자-로빙 매핑 (메모리 캐시)
### robeing-control (51123:9023)
**역할**:
- 시스템 모니터링 통합
- Admin 대시보드 UI
- 51123/51124 서버 상태 조회
### robeing-monitor (51124:9024)
**역할**:
- 로빙 컨테이너 health 체크
- Stats 수집 (메모리, CPU, 응답 시간)
- 로그 수집
---
## 구현 Phase
### Phase 1: robeing-gateway 분리 (미착수)
- frontend-base에서 라우팅 로직 분리
- JWT 인증 미들웨어
- 사용자-로빙 매핑 테이블/캐시
### Phase 2: robeing-control 분리 (미착수)
- Admin UI 분리
- 모니터링 통합 대시보드
- 51123 서버 프로세스 직접 체크
### Phase 3: robeing-monitor 구현 (미착수)
- 51124 서버에 배포
- Docker stats API
- Health check 엔드포인트
---
## 기대 효과
- 관심사 분리 (라우팅 vs 모니터링)
- 확장성 향상 (로빙 추가 시 gateway만 수정)
- 장애 격리 (모니터링 장애가 라우팅에 영향 X)
---
## 참고
- `troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md`
- `311_FastAPI_구조_원칙.md`

View File

@ -1,217 +1,82 @@
# Gemini File Search 콜드메일 통합 TDD 테스트 계획
# Gemini File Search 콜드메일 통합 계획
**작성일**: 2025-11-10
**작성자**: Claude Code
**목표**: Gemini File Search API를 콜드메일 워크플로우에 통합하여 IR 분석 품질 개선
**날짜**: 2025-11-10
**목표**: Gemini File Search로 IR 분석 품질 개선
---
## 1. 배경
## 현재 문제
### 현재 콜드메일 워크플로우
### 콜드메일 워크플로우 병목
1. PDF 첨부파일 다운로드
2. skill-rag-file 업로드 (PyPDF2 → OCR)
3. RAG 쿼리 6회 (IR 지표 추출)
4. **문제**: OCR 품질 낮음 → RAG 검색 0건 → IR 지표 "N/A"
참고: rb8001/app/services/workflows/coldmail_workflow.py:22-150
**결과**: seed 30억·신뢰도 0.6 고정
1. 컴퍼니엑스 이메일 조회 (NAVER WORKS)
2. Naive Bayes 콜드메일 필터링
3. PDF 첨부파일 다운로드
4. skill-rag-file 업로드 (PyPDF2 → OCR)
5. RAG 쿼리 6회 (IR 지표 추출)
6. 베이지안 가치 평가
7. Slack Lists 등록
---
### 병목점
참고:
- skill-rag-file/app/api/upload.py:148-183
- rb8001/app/services/startup_valuation.py:38-72, 296-314
**PDF 추출 실패 연쇄 효과**:
- OCR 품질 낮음 → RAG 검색 0건
- IR 지표 "N/A" → evidence_count=0
- seed 30억·신뢰도 0.6 고정
### Gemini File Search 개선 효과
참고: DOCS/research/rag/251110_gemini_file_search_api_테스트_및_콜드메일_개선방안_평가.md:166-184
## Gemini File Search 개선
### 장점
- 한글 OCR PDF 13.77초 안정 처리
- IR 지표 정확 추출 → evidence_count ≥ 2
- 신뢰도 0.7~0.8 상승
- IR 지표 정확 추출
- grounding_metadata로 근거 제공
- evidence_count ≥ 2 → 신뢰도 0.7~0.8
---
## 2. 임베딩 차원 호환성
## 구현 계획
### 현재 시스템
- **2025-11-22 업데이트**: skill-embedding은 ko-sroberta 768차원으로 운영 중이며, 기존 384차원 컬렉션과 혼용하면 차원 불일치가 발생한다. 실제 운영 상태와 불일치한 아래 384차원 가정은 참조용이며, 대응 방안은 [251122_happybell80_chromadb_dimension_mismatch.md] 참고.
### Phase 1: Gemini File API 구현 (미착수)
- skill-embedding: multilingual-MiniLM-L12-v2 (384차원)
- ChromaDB 컬렉션: skill_rag_file_{team_id}_documents
**파일**: `rb8001/app/services/gemini_file_service.py`
### Gemini 임베딩
**기능**:
- PDF 업로드 → Gemini File API
- 쿼리 실행 (IR 지표 추출)
- grounding_metadata 파싱
- gemini-embedding-001: 3,072차원 (기본)
- 설정 가능: 128~3,072 차원
### Phase 2: coldmail_workflow 통합 (미착수)
### 호환성 전략
**파일**: `rb8001/app/services/workflows/coldmail_workflow.py`
**옵션 1**: 별도 컬렉션 (team_id_gemini vs team_id_documents)
**옵션 2**: Gemini 차원 384로 축소
**변경**:
- skill-rag-file → Gemini File Search로 교체
- 6개 IR 쿼리 병렬 실행
- evidence_count 기반 신뢰도 계산
### Phase 3: TDD 테스트 (미착수)
**파일**: `rb8001/tests/test_coldmail_gemini_integration.py`
**시나리오**:
1. PDF 업로드 성공
2. IR 지표 추출 (매출, 투자 단계 등)
3. evidence_count ≥ 2 검증
4. 신뢰도 0.7 이상 검증
---
## 임베딩 차원 호환성
### 현재
- skill-embedding: ko-sroberta (768차원)
- ChromaDB: `skill_rag_file_{team_id}_documents`
### Gemini
- gemini-embedding-001: 3,072차원
- 설정 가능: 128~3,072
### 전략
**옵션 1**: 별도 컬렉션 (`{team_id}_gemini`)
**옵션 2**: Gemini 차원 768로 축소
**추천**: 옵션 1 (성능 최대화)
---
## 3. 테스트 코드 위치
## 참고
### 추천 위치
**파일**: `rb8001/tests/test_coldmail_gemini_integration.py`
**이유**:
- rb8001/tests/에 기존 콜드메일 테스트 시리즈 있음
- 전체 E2E 워크플로우 통합 테스트 가능
- 실제 스케줄러 환경과 동일
**기존 콜드메일 테스트**:
- test_coldmail_filter.py
- test_coldmail_ontology.py
- test_coldmail_full_scenario.py
- test_e2e_coldmail_workflow.py
---
## 4. 테스트 시나리오
### 시나리오 1: PDF 처리 품질 A/B 테스트
**목적**: PyPDF2+OCR vs Gemini File Search IR 지표 추출 정확도
**Given**:
- IR PDF 샘플: rb8001/state/ocr_tests/611938b0-kor.ocr.pdf
- 또는 과거 콜드메일 첨부 PDF
**When**:
- 경로 A: skill-rag-file (PyPDF2 → OCR → 384차원)
- 경로 B: Gemini File Search (자동 색인 → 3,072차원)
**Then 검증**:
- IR 지표 6개 추출 성공률 (사업분야, 단계, 매출, 성장률, 팀규모, 기술우위)
- evidence_count 비교 (0~4개)
- 처리 시간 비교
**성공 기준**:
- Gemini evidence_count ≥ 2
- 신뢰도 ≥ 0.7
### 시나리오 2: 밸류에이션 신뢰도 개선 검증
**목적**: evidence_count 증가로 신뢰도 0.6 → 0.7~0.8 상승 확인
**Given**:
- evidence_count=0 과거 콜드메일 케이스
- startup_valuation.py:296-314 함수 동작
**When**:
- 동일 PDF를 Gemini로 재분석
- IR 지표 재추출 → evidence_count 증가
- valuate_startup() 재실행
**Then 검증**:
- 기존: seed 30억, 신뢰도 0.6
- 개선: seed 탈출, 신뢰도 0.7~0.8
- compute_confidence() ev_boost 작동
**성공 기준**:
- evidence_count: 0 → 2 이상
- confidence: 0.6 → 0.7 이상
- Slack Lists 상태: HOLD → 정상
### 시나리오 3: 하이브리드 운영 E2E 테스트
**목적**: 48시간 제약 우회 이중 저장 전체 플로우
**Given**:
- 신규 콜드메일 수신 시뮬레이션
**When**:
1. PDF 다운로드
2. Gemini File Search 업로드 (임시)
3. skill-rag-file 업로드 (영구)
4. IR 분석: Gemini RAG 우선 사용
5. Slack Lists 등록
6. 48시간 후: Gemini 삭제, Chroma 검색
**Then 검증**:
- 48시간 이내: Gemini 검색 성공, grounding 제공
- 48시간 이후: Chroma 검색 성공
- Slack Lists IR 파일 영구 유효
- TCO 측정 (색인 비용 vs 운영 비용)
**성공 기준**:
- 검색 영속성 보장
- 결과 일관성 유지
- 비용 효율성 검증
---
## 5. 구현 순서
### Phase 1: 기본 검증 (시나리오 1)
1. test_coldmail_gemini_integration.py 생성
2. PDF A/B 테스트 함수 작성
3. IR 지표 추출 정확도 비교
### Phase 2: 품질 개선 검증 (시나리오 2)
1. evidence_count 증가 테스트
2. 신뢰도 향상 검증
3. Slack Lists HOLD 상태 해소
### Phase 3: 운영 검증 (시나리오 3)
1. 이중 저장 파이프라인 구현
2. 48시간 영속성 테스트
3. TCO 분석 및 의사결정
---
## 6. 제약사항
### Gemini API 한계
- 무료 tier: 분당 요청 제한
- 저장 한도: 1GB (무료)
- 파일 크기: 최대 100MB
- 보존 기간: 48시간
### 기술적 제약
- 임베딩 차원 불일치 (384 vs 3,072)
- 별도 컬렉션 필요
- ChromaDB 스토리지 증가 (8배)
### 운영 고려사항
- 색인 비용: $0.15/1M 토큰
- 외부 API 의존성
- 데이터 보안 리스크
---
## 7. 다음 단계
### 즉시 실행 가능
1. rb8001/tests/test_coldmail_gemini_integration.py 생성
2. 시나리오 1 구현 (PDF A/B 테스트)
3. 기존 IR PDF로 검증
### 의사결정 필요
1. Gemini 차원 설정 (384 vs 3,072)
2. 하이브리드 운영 여부
3. 예산 승인 (유료 tier 전환)
---
**작성**: Claude Code, 2025-11-10
**상태**: 계획 단계 (구현 전)
**참고**: research/rag/251110_gemini_file_search_api_테스트_및_콜드메일_개선방안_평가.md
- `research/rag/251110_gemini_file_search_api_테스트.md`
- `troubleshooting/251122_chromadb_dimension_mismatch.md`

View File

@ -1,124 +1,66 @@
# 짧은 후속 질문 컨텍스트 유실 개선 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
**날짜**: 2025-11-17
**목표**: "어디서?", "언제?" 같은 짧은 질문의 맥락 연결
---
## 1. 문제 요약
## 문제
- 사용자: "11월 18일 오전 6시 40분에 검진이 있습니다" → RoBeing 응답 OK
- 이어서 사용자: "어디서?"
- 실제 동작: 짧은 질문이 UNKNOWN → understand 액션으로 전달 → LLM이 "오늘 일정 정리해 드릴까요?"처럼 **새 대화로 오인**
- 근본 원인: 짧은 후속 질문에 대한 별도 Intent/처리 경로가 없어서, **직전 발화/대화 맥락을 강제 참조하지 못하는 구조**
**사례**:
```
사용자: "11월 18일 오전 6시 40분에 검진이 있습니다"
로빙: "알겠습니다."
사용자: "어디서?"
로빙: "오늘 일정 정리해 드릴까요?" ❌ (새 대화로 오인)
```
**원인**: 짧은 후속 질문을 UNKNOWN으로 분류, 직전 맥락 참조 안 함
---
## 2. 목표
## 3단계 계획
1. "어디서?", "언제?", "누구랑?" 같은 **짧은 후속 질문**이 항상 직전 발화/대화 맥락과 연결되도록 한다.
2. 비용 제약 없이, **정규식 FastPath → 임베딩 기반 의도 분류 → 멀티턴/슬롯필링**까지 단계적으로 설계한다.
3. 기존 DecisionEngine/테스트 구조를 유지하면서, 점진적으로 확장 가능한 형태로 설계한다.
### 1단계: CONTEXT_FOLLOWUP Intent (미구현)
**설계**:
- IntentType 추가: `CONTEXT_FOLLOWUP`
- 패턴: `r"^어디서[요]?$"`, `r"^언제[요]?$"`, `r"^누구(랑)?[요]?$"`
- 처리: 직전 1~3턴 메시지 강제 참조
**구현**:
- `app/services/brain/decision_engine.py`: 패턴 추가
- LLM 프롬프트에 직전 발화 포함
### 2단계: 임베딩 기반 맥락 분류 (미구현)
**설계**:
- 현재 발화 + 최근 N턴 임베딩
- 후보 의도와 유사도 비교
- 확신도 ≥ 0.8 → 결정, < 0.5 LLM 폴백
**효과**:
- 짧은 질문도 직전 발화와 관계 반영
- UNKNOWN 경로 유입 감소
### 3단계: 멀티턴/슬롯필링 (미구현)
**설계**:
- Redis 세션 관리 (3~5턴)
- 슬롯 구조: {날짜, 시간, 장소, 대상, 목적}
- 후속 질문 → 슬롯 채우기
**예시**:
```
사용자: "검진 일정 잡아줘"
로빙: "언제 하실 예정인가요?" (날짜 슬롯 질문)
사용자: "11월 24일"
로빙: "어디서 하시나요?" (장소 슬롯 질문)
```
---
## 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단계: 멀티턴/슬롯필링 구조를 도입해, 일정/검진/회의 등 복합 작업 흐름에서 자연스러운 후속 질문 처리를 지원.
## 참고
- `troubleshooting/251117_human_in_the_loop_intent_learning.md`
- `plans/251017_intent_analysis_improvement_plan.md`