From 4818ea13e3bed3aa4f174541ce49d3bd01f3030b Mon Sep 17 00:00:00 2001 From: happybell80 Date: Thu, 4 Dec 2025 22:12:19 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20plan=20=EB=AC=B8=EC=84=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EA=B0=84=EA=B2=B0=ED=99=94=20(584=EC=A4=84=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../250807_서비스_재구조화_계획.md | 304 ++++-------------- ...earch_콜드메일_tdd_테스트_계획.md | 249 ++++---------- ...1117_short_followup_context_3phase_plan.md | 164 +++------- 3 files changed, 173 insertions(+), 544 deletions(-) diff --git a/journey/plans/250807_서비스_재구조화_계획.md b/journey/plans/250807_서비스_재구조화_계획.md index f1194c2..380b68e 100644 --- a/journey/plans/250807_서비스_재구조화_계획.md +++ b/journey/plans/250807_서비스_재구조화_계획.md @@ -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: 메모리 캐시 확인
없으면 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` diff --git a/journey/plans/251110_gemini_file_search_콜드메일_tdd_테스트_계획.md b/journey/plans/251110_gemini_file_search_콜드메일_tdd_테스트_계획.md index c139912..50152f8 100644 --- a/journey/plans/251110_gemini_file_search_콜드메일_tdd_테스트_계획.md +++ b/journey/plans/251110_gemini_file_search_콜드메일_tdd_테스트_계획.md @@ -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` diff --git a/journey/plans/251117_short_followup_context_3phase_plan.md b/journey/plans/251117_short_followup_context_3phase_plan.md index 610c371..99548f6 100644 --- a/journey/plans/251117_short_followup_context_3phase_plan.md +++ b/journey/plans/251117_short_followup_context_3phase_plan.md @@ -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`