docs: plan 문서 추가 간결화 (584줄 삭제)
This commit is contained in:
parent
a60d3c903b
commit
4818ea13e3
@ -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`
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user