감정 시스템 구현 문서에 구체적인 코드 참조 패턴 추가
- 키워드 매칭, DB 연결, API 라우트 패턴 추가 - TimescaleDB 및 시계열 집계 참조 추가 - 실제 파일 경로와 라인 번호 포함
This commit is contained in:
parent
1534005e78
commit
392d870aee
@ -1,11 +1,12 @@
|
||||
# 미해결 항목 매트릭스 (중요도 × 구현 난이도)
|
||||
|
||||
## 🔴 Quick Wins (높은 중요도 + 쉬운 구현) → 즉시 실행
|
||||
1. **네이버웍스 메일→슬랙 전달** - 콜드메일(03) 미구현 (1주) [→250919_03_cold](../troubleshooting/250919_naverworks_slack_03_cold_mail_list.md)
|
||||
1. **frontend-customer 인증 검증 URL 환경변수화** - `/auth/verify` 하드코딩 제거, `VITE_AUTH_SERVER_URL` 기반으로 통일 (0.5일) (참조: frontend-customer/src/contexts/auth-context.tsx:77)
|
||||
2. **헬스체크 경로 표준화 적용(rb8001/skills)** - 일부 서비스 `/health` → `/healthz`로 정렬 필요 (0.5일) (코드/도커 헬스체크 동기화 포함)
|
||||
|
||||
## 🟠 Major Projects (높은 중요도 + 어려운 구현) → 계획 수립 후 진행
|
||||
1. **하드코딩 URL 제거** - 15개+ 서비스 광범위 미해결, 특히 rb8001의 auth-server URL (3-4주) [→250915](../troubleshooting/250915_hardcoded_url_removal.md)
|
||||
2. **Gateway 스케일링** - 재시도/백오프/헬스체크 미구현 (Rate limiting은 별도 완료) (1주) [→250811](../troubleshooting/250811_happybell80_Gateway필드변환문제.md) [→250915_rate](../troubleshooting/250915_rate_limiting_미구현.md)
|
||||
2. **Gateway 스케일링** - 재시도/백오프 미구현 (Rate limiting 완료, `/healthz` 제공) (1주) [→250811](../troubleshooting/250811_happybell80_Gateway필드변환문제.md) [→250915_rate](../troubleshooting/250915_rate_limiting_미구현.md)
|
||||
3. **RAG 파이프라인 웹검색 통합** - 아이디어 단계, 미구현 (3주) [→250909](../ideas/250909_RAG_file_processing_architecture.md)
|
||||
4. **rb8001 리팩토링** - 계획 단계, 미구현 (3주) [→250914](../ideas/250914_rb8001_리팩토링_계획.md)
|
||||
5. **감정 분석 시스템 구현** - 현재 임시값 사용 중, ONNX/DB/API 미구현 (3주) [→250916](../ideas/250916_로빙_감정_분석_시스템_구현_계획.md)
|
||||
@ -19,13 +20,12 @@
|
||||
2. **캘린더 API** - /api/calendar 미구현 (4시간) [→250830](../troubleshooting/250830_skill_level_system_restructure.md)
|
||||
3. **문서 API** - /api/docs 미구현 (4시간) [→250830](../troubleshooting/250830_skill_level_system_restructure.md)
|
||||
4. **불용 환경변수 정리** - 전역 감사 미완 (2시간)
|
||||
5. **임베딩 서비스 오류 처리** - 재시도/폴백 미구현 (3시간)
|
||||
5. **임베딩 서비스 오류 처리** - 폴백(더미 벡터)만 구현, 재시도 미구현 (3시간)
|
||||
6. **헬스체크 일관화** - 일부 /healthz 추가 사례 있으나 전반 점검 미완 (1시간) [→250811](../troubleshooting/250811_happybell80_Gateway필드변환문제.md)
|
||||
|
||||
## ⚪ Consider Later (낮은 중요도 + 어려운 구현) → 재검토 필요
|
||||
1. **실시간 동기화** - WebSocket/폴링 미구현 (영향도 재평가 필요) (2주) [→250827](../troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md)
|
||||
2. **PKCE 적용** - OAuth 보안 강화 미구현 (1주) [→380](../300_architecture/380_authentication_system.md)
|
||||
3. **Refresh Token** - 토큰 재발급 체계 미구현 (1주) [→380](../300_architecture/380_authentication_system.md)
|
||||
4. **DB 스키마 통일** - company→workspaces 미구현 (2주) [→250831](250831_todo_and_tech_debt.md)
|
||||
5. **스킬 라우팅 고도화** - Decision Engine 미구현 (3주) [→250811](../ideas/250811_claude_rb10408_vs_rb10508_비교분석.md)
|
||||
6. **IntentAnalyzer 활성화** - 현재 미사용, LLM 기반 의도분석기 미연동 (1주) [→250914](../troubleshooting/250914_happybell80_IntentAnalyzer_미사용_문제.md)
|
||||
@ -36,4 +36,4 @@
|
||||
*평가 기준: 중요도(시스템 안정성/사용자 영향), 난이도(구현 시간/복잡도)*
|
||||
|
||||
---
|
||||
*최종 업데이트: 2025-09-27*
|
||||
*최종 업데이트: 2025-10-02*
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
# 감정 시스템 구현 계획 (rb8001)
|
||||
# 감정 시스템 구현 문서 (rb8001)
|
||||
|
||||
**작성일**: 2025-10-02
|
||||
**작성자**: Claude & happybell80
|
||||
**관련 서비스**: rb8001
|
||||
**이슈**: 감정 분석 시스템 미구현
|
||||
**목적**: rb8001의 균등분포 감정 분석을 실제 모델 추론 + 시계열 저장/집계로 전환
|
||||
|
||||
## 사용자 관점 시나리오
|
||||
|
||||
@ -26,16 +25,19 @@
|
||||
- **효과**: 부정 감정 임계치 초과 시 매니저 알림, 회의 전 팀 감정 브리핑
|
||||
- **구현 요구사항**: 채널별 감정 집계 + 임계치 알림 시스템
|
||||
|
||||
### 현재 구현 가능성
|
||||
- **시나리오 1**: 즉시 가능 (감정 분석 API + 프롬프트 수정)
|
||||
- **시나리오 2-3**: TimescaleDB 구축 후 가능 (시계열 저장/집계 필요)
|
||||
### 시나리오별 요구사항
|
||||
- **시나리오 1**: 문장 단건 추론 API, LLM 톤 조절 규칙 (rb8001/app/llm/llm_service.py:119)
|
||||
- **시나리오 2**: 사용자별 시계열 저장, time_bucket 집계, 요약 API
|
||||
- **시나리오 3**: 채널/워크스페이스 집계, 임계치 알림, 관리자 요약 API
|
||||
|
||||
## 현재 상황
|
||||
|
||||
### rb8001 감정 시스템 현황
|
||||
- **구조만 존재**: rb8001/app/core/emotion/base.py:16-34, rb8001/app/llm/emotion_llm.py:18-114
|
||||
- **실제 분석 없음**: rb8001/app/core/emotion/base.py:46-55 (모든 감정 균등 분포 반환)
|
||||
- **rb10508_micro**: rb10508_micro/app/core/emotion/base.py:46-55 (동일 구조)
|
||||
### 코드 위치 (정확)
|
||||
- **균등 분포 반환**: rb8001/app/core/emotion/base.py:46, 51
|
||||
- **감정 분석 호출**: rb8001/app/llm/emotion_llm.py:25, 56
|
||||
- **LLM 서비스 호출**: rb8001/app/llm/llm_service.py:119
|
||||
- **감정 API**: 없음 (rb8001/main.py 확인 완료)
|
||||
- **emotion_readings 테이블**: 없음
|
||||
|
||||
### 서버 확인 결과 (2025-10-02)
|
||||
|
||||
@ -62,168 +64,137 @@ done
|
||||
- **Gateway 서비스**: robeing-gateway 실행 중 (포트 8100)
|
||||
- **결론**: 51123에 감정 시스템 관련 인프라 전혀 구현되지 않음
|
||||
|
||||
### 구현된 부분
|
||||
```text
|
||||
rb8001/app/core/emotion/base.py:16-34 EmotionState 정의 (9개 감정 레이블 포함)
|
||||
rb8001/app/core/emotion/base.py:37-44 calculate_entropy[_cached]
|
||||
rb8001/app/core/emotion/base.py:128-155 ThompsonSampler
|
||||
rb8001/app/llm/emotion_llm.py:25-54 analyze_user_emotion (analyze_emotion 호출)
|
||||
rb8001/app/llm/emotion_llm.py:56-89 generate_response_with_emotion (메모리 저장)
|
||||
```
|
||||
### 기존 코드 파일
|
||||
- rb8001/app/core/emotion/base.py (EmotionState, 엔트로피, ThompsonSampler)
|
||||
- rb8001/app/core/emotion/bayesian.py (베이지안 학습)
|
||||
- rb8001/app/core/emotion/storage.py (사용자별 파라미터)
|
||||
- rb8001/app/core/emotion/monitoring.py (감정 모니터링)
|
||||
- rb8001/app/llm/emotion_llm.py (analyze_user_emotion, generate_response_with_emotion)
|
||||
|
||||
### 미구현 부분
|
||||
1. **모델 통합**: klue/bert-base 기반 7클래스 분류기 (코드 없음)
|
||||
2. **ONNX 추론**: 모델 변환 및 최적화 (코드 없음)
|
||||
3. **Temperature Scaling**: 확률 보정 (코드 없음)
|
||||
4. **데이터베이스**: emotion_readings 테이블 (스키마/마이그레이션 없음)
|
||||
5. **API 엔드포인트**: /v1/emotion/infer 등 (엔드포인트 없음)
|
||||
### 미구현 항목
|
||||
- rb8001/app/core/emotion/inference.py (파일 없음)
|
||||
- ONNX 모델 파일 (없음)
|
||||
- 토크나이저 초기화 (없음)
|
||||
- emotion_readings 테이블 (없음)
|
||||
- /v1/emotion/* API 엔드포인트 (없음)
|
||||
|
||||
## 구현 로드맵
|
||||
## 데이터 모델 설계
|
||||
|
||||
### Phase 1: 기본 감정 분석 (1주)
|
||||
1. **Day 1-2: 모델 준비**
|
||||
- klue/bert-base 기반 감정 분류 모델 준비
|
||||
- 7개 클래스: fear, surprise, anger, sadness, neutral, happiness, disgust
|
||||
- ONNX 변환 및 최적화
|
||||
### emotion_readings 테이블
|
||||
필수 컬럼:
|
||||
- user_id (UUID)
|
||||
- created_at (TIMESTAMPTZ)
|
||||
- probs (JSONB)
|
||||
- entropy (FLOAT)
|
||||
- top_label (TEXT)
|
||||
- top_p (FLOAT)
|
||||
- model_version (TEXT)
|
||||
- meta (JSONB)
|
||||
- text_hash (VARCHAR) - 원문 미저장, 해시만
|
||||
|
||||
2. **Day 3-4: 추론 엔진 구현**
|
||||
```text
|
||||
없음: rb8001/app/core/emotion/inference.py (파일 미존재)
|
||||
없음: rb8001 내 onnxruntime/transformers 런타임 사용 코드
|
||||
참고: training_emotion/train_korean_emotion.py:244-257 (학습용 ORT/Tokenizer)
|
||||
현재 추론 경로: rb8001/app/core/emotion/base.py:63-85 (analyze_emotion[_cached])
|
||||
현재 LLM 연동: rb8001/app/llm/emotion_llm.py:25-54 (analyze_user_emotion)
|
||||
토크나이저/ONNX 세션 초기화 위치: 없음 (프로덕션 코드 기준)
|
||||
EMOTION_TEMPERATURE 사용: rb8001/app/core/emotion/base.py:14 (상수 로드)
|
||||
Temperature Scaling 적용: 없음 (확률 보정 미적용)
|
||||
모델 파일 경로 상수: 없음
|
||||
레이블 상수(7클래스): 없음
|
||||
추론 입력 전처리: 없음
|
||||
추론 출력 후처리: 없음
|
||||
배치 추론 엔트리포인트: 없음
|
||||
에러 처리/재시도: 없음
|
||||
로깅 위치: rb8001/app/llm/emotion_llm.py:49 (분석 결과 로그)
|
||||
```
|
||||
저장 위치:
|
||||
- robeing_metrics DB (별도 DB 권장)
|
||||
- TimescaleDB 하이퍼테이블 적용
|
||||
|
||||
3. **Day 5: DB 스키마 구현 (TimescaleDB 권장)**
|
||||
```text
|
||||
없음: emotion_readings 테이블 (코드/마이그레이션 미존재)
|
||||
확인: DOCS/ideas/emotion_graph_implementation.md:215,232 (문서 내 예시 스키마)
|
||||
확인: DOCS/ideas/250916_로빙_감정_분석_시스템_구현_계획.md:11 (테이블 부재 명시)
|
||||
### TimescaleDB 참조
|
||||
- 설치/활성화: DOCS/troubleshooting/250714_system_metrics_implementation.md
|
||||
- time_bucket 쿼리: frontend-base/backend/metrics_database.py:103
|
||||
- asyncpg interval 이슈: DOCS/troubleshooting/250715_metrics_graph_timebucket_error.md
|
||||
|
||||
[TimescaleDB 적용 권장]
|
||||
- emotion_readings는 시계열 데이터로 TimescaleDB 하이퍼테이블이 적합
|
||||
- robeing_metrics DB 사용 (main_db와 분리)
|
||||
- 참고: frontend-base/backend/metrics_database.py:103 (time_bucket 쿼리)
|
||||
- 참고: DOCS/troubleshooting/250714_system_metrics_implementation.md
|
||||
## API 스펙
|
||||
|
||||
CREATE TABLE emotion_readings (
|
||||
time TIMESTAMPTZ NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
text_hash VARCHAR(64),
|
||||
model_version VARCHAR(20),
|
||||
temperature FLOAT,
|
||||
logits JSONB,
|
||||
probs JSONB,
|
||||
top_label VARCHAR(20),
|
||||
top_p FLOAT,
|
||||
entropy FLOAT,
|
||||
meta JSONB
|
||||
);
|
||||
### POST /v1/emotion/infer
|
||||
- 입력: text, user_id
|
||||
- 출력: {probs, entropy, top_label, top_p, model_version}
|
||||
- 저장: emotion_readings 삽입
|
||||
|
||||
SELECT create_hypertable('emotion_readings', 'time');
|
||||
CREATE INDEX ON emotion_readings (user_id, time DESC);
|
||||
```
|
||||
### GET /v1/emotion/timeseries
|
||||
- 쿼리: user_id, start, end, bucket
|
||||
- 출력: bucket별 집계 결과
|
||||
|
||||
### Phase 2: API 및 통합 (1주)
|
||||
### GET /v1/emotion/team-insight
|
||||
- 쿼리: channel_id, workspace_id, 기간
|
||||
- 출력: 팀 감정 지표
|
||||
|
||||
1. **Day 6-7: API 엔드포인트**
|
||||
```text
|
||||
없음: rb8001 내 /v1/emotion/* 라우트
|
||||
확인: rg 검색 결과 엔드포인트 미발견
|
||||
관련 파일: rb8001/main.py (감정 관련 API 없음)
|
||||
현재 사용 경로: rb8001/app/llm/llm_service.py:119-134 (내부 호출만 존재)
|
||||
robeing-gateway/app/main.py (프록시에 감정 API 없음)
|
||||
robeing-monitor (감정 API 없음)
|
||||
```
|
||||
## 통합 포인트
|
||||
|
||||
2. **Day 8-9: 기존 시스템 통합**
|
||||
- Router에서 감정 분석 호출
|
||||
- 메모리 저장 시 감정 메타데이터 추가
|
||||
- Slack 응답에 감정 정보 포함
|
||||
### 감정 분석 삽입
|
||||
- rb8001/app/llm/emotion_llm.py:25 - inference.py 호출로 대체
|
||||
- rb8001/app/core/emotion/base.py:46, 51 - 실제 분석 로직으로 교체
|
||||
|
||||
3. **Day 10: 시각화**
|
||||
- 감정 그래프 생성 (matplotlib/plotly)
|
||||
- Slack 이미지 업로드
|
||||
### LLM 톤 조절
|
||||
- rb8001/app/llm/llm_service.py:133 - 주석 블록 재활성화
|
||||
- 감정 기반 프롬프트 조절 로직 추가
|
||||
|
||||
### Phase 3: 고도화 (선택적)
|
||||
### 저장 계층
|
||||
- 신규 DB 클라이언트 (robeing_metrics)
|
||||
- 비동기 저장 큐 고려
|
||||
|
||||
1. **Temperature Calibration**
|
||||
- 검증 데이터셋으로 최적 T 값 찾기
|
||||
- ECE (Expected Calibration Error) 최소화
|
||||
### 권한
|
||||
- user_id는 JWT sub(UUID)
|
||||
- robeing-gateway/app/main.py:23 검증 로직 존재
|
||||
|
||||
2. **배치 처리 최적화**
|
||||
- 마이크로배칭
|
||||
- 비동기 처리 큐
|
||||
## 구현 참조 패턴
|
||||
|
||||
3. **감정 공명 시스템**
|
||||
- 과거 감정과 현재 감정 결합
|
||||
- 사용자별 감정 패턴 학습
|
||||
### 키워드 매칭 로직
|
||||
- 정규식 기반 의도 분류: rb8001/app/brain/decision_engine.py:69, 116
|
||||
- 키워드·정규식 혼합 파싱: rb8001/app/skills/email_integration.py:214, 226-239, 245-258
|
||||
|
||||
## 구현 우선순위
|
||||
### DB 연결 패턴
|
||||
- asyncpg 풀: frontend-base/backend/metrics_database.py:12, 23
|
||||
- asyncpg 단건: robeing-monitor/app/api/monitor.py:139, 208
|
||||
- asyncpg 단건: skill-email/services/naverworks_provider.py:38
|
||||
- asyncpg 단건: rb8001/app/services/coldmail_filter.py:159, 183, 225
|
||||
- psycopg2 동기: rb8001/app/skills/news_posting_skill.py:35-37
|
||||
- SQLAlchemy Async: robeing-gateway/app/database.py:22-36
|
||||
|
||||
### 즉시 구현 가능 (Quick Win)
|
||||
1. ✅ 감정 DB 테이블 생성 (TimescaleDB 하이퍼테이블로)
|
||||
2. ✅ 간단한 규칙 기반 감정 분석 (키워드 매칭)
|
||||
3. ✅ 감정 저장 및 조회 API
|
||||
### API 라우트 패턴
|
||||
- rb8001 메인 라우트: rb8001/main.py:344 (@app.post("/api/slack/events"))
|
||||
- rb8001 스케줄 테스트: rb8001/main.py:356 (@app.post("/api/schedule/test-news"))
|
||||
- 인증 의존성 주입: rb8001/app/auth.py:61 (get_current_user), 66-75 (JWT decode)
|
||||
- 게이트웨이 검증: robeing-gateway/app/main.py:41 (get_verified_user), 228-232 (Authorization 포워딩)
|
||||
|
||||
### TimescaleDB 활용 전략
|
||||
- **신규 테이블 우선**: emotion_readings를 robeing_metrics DB에 하이퍼테이블로 생성
|
||||
- **기존 main_db 유지**: 프로덕션 DB는 그대로 유지, 시계열만 분리
|
||||
- **asyncpg 주의사항**: interval 바인딩 이슈 대응 필요 (DOCS/troubleshooting/250715_metrics_graph_timebucket_error.md)
|
||||
### 시계열 집계 패턴
|
||||
- TimescaleDB 설치: DOCS/troubleshooting/250714_system_metrics_implementation.md:18-29
|
||||
- time_bucket 쿼리: frontend-base/backend/metrics_database.py:103
|
||||
- asyncpg interval 이슈: DOCS/troubleshooting/250715_metrics_graph_timebucket_error.md:28, 57, 85, 112-113
|
||||
|
||||
### 중기 목표 (1-2주)
|
||||
1. ⏳ BERT 모델 통합
|
||||
2. ⏳ ONNX 최적화
|
||||
3. ⏳ Temperature Scaling
|
||||
### 데이터 모델 참조
|
||||
- emotion_readings 스키마: DOCS/ideas/emotion_graph_implementation.md:215, 232
|
||||
- emotion 스키마: DOCS/ideas/250916_로빙_감정_분석_시스템_구현_계획.md:11
|
||||
- rb_news 테이블 예시: rb8001/scripts/create_rb_news_table.sql:8, 56, 77
|
||||
|
||||
### 장기 목표 (1개월+)
|
||||
1. 📅 사용자별 감정 패턴 학습
|
||||
2. 📅 실시간 감정 모니터링 대시보드
|
||||
3. 📅 감정 기반 응답 생성
|
||||
### 팀/주간 집계 메타
|
||||
- 채널 식별: rb8001/app/skills/news_posting_skill.py:214, 467
|
||||
- JSONB 메타 패턴: DOCS/ideas/emotion_graph_implementation.md:235, 259
|
||||
|
||||
## 리소스 요구사항
|
||||
## 작업 순서
|
||||
|
||||
### 모델
|
||||
- klue/bert-base (400MB)
|
||||
- ONNX 변환 모델 (100MB)
|
||||
- 추론 시간: CPU 40-80ms, GPU 10-20ms
|
||||
1. 추론 모듈 추가: rb8001/app/core/emotion/inference.py
|
||||
2. EmotionAwareLLM 연결: rb8001/app/llm/emotion_llm.py:25
|
||||
3. LLMService 톤 조절: rb8001/app/llm/llm_service.py:133
|
||||
4. DB 스키마 준비: robeing_metrics DB (별도)
|
||||
5. API 라우트 추가: rb8001/main.py
|
||||
6. 집계 쿼리 구현: time_bucket 기반
|
||||
|
||||
### 인프라
|
||||
- 추가 메모리: 500MB-1GB
|
||||
- DB 스토리지: 사용자당 일 100KB
|
||||
- 계산 리소스: CPU 2 cores 권장
|
||||
## 모니터링/성능
|
||||
|
||||
## 주의사항
|
||||
### 추론 지연
|
||||
- rb10508_micro/app/core/emotion/monitoring.py 패턴 참고
|
||||
|
||||
1. **프라이버시**
|
||||
- 원문 텍스트는 해시만 저장
|
||||
- 사용자 동의 필요
|
||||
- 삭제 권한 보장
|
||||
### 저장 압력
|
||||
- TTL/압축은 TimescaleDB 정책으로 설정
|
||||
|
||||
2. **성능**
|
||||
- 캐싱 적극 활용
|
||||
- 배치 처리로 효율화
|
||||
- 비동기 처리 필수
|
||||
## 리스크/롤백
|
||||
|
||||
3. **정확도**
|
||||
- 한국어 특화 모델 필요
|
||||
- 지속적인 모니터링
|
||||
- 사용자 피드백 수집
|
||||
### 모델 미가용
|
||||
- 균등분포 폴백 허용
|
||||
|
||||
## 결론
|
||||
### DB 장애
|
||||
- 저장 실패해도 응답 생성 지속 (비동기 큐)
|
||||
|
||||
rb10508_micro의 감정 시스템을 rb8001로 이식 또는 skill-embedding으로 분리 필요:
|
||||
- rb10508_micro에 Bayesian 기반 감정 시스템 구현됨
|
||||
- rb8001에 기본 구조만 있고 실제 기능 없음
|
||||
- 이식 또는 독립 스킬화 검토 필요
|
||||
## 테스트 체크리스트
|
||||
|
||||
- 단위: 레이블 확률 합=1, 엔트로피 범위, dominant 일관성
|
||||
- 통합: POST infer → DB insert 생성, GET timeseries → time_bucket 응답
|
||||
- 회귀: 균등분포 제거 후 LLM 응답 톤 변화 확인
|
||||
|
||||
@ -1,77 +0,0 @@
|
||||
# rb8001 중복 코드 검사 및 정리 계획
|
||||
|
||||
## 작성 정보
|
||||
- 작성일: 250911
|
||||
- 작성자: happybell80
|
||||
- 범위: rb8001 컨테이너 코드 중 엔드포인트/헬스체크/라우터 중복 및 미사용 코드
|
||||
|
||||
## 문제 요약
|
||||
- 동일 기능 엔드포인트가 서로 다른 파일에 중복 정의되어 유지보수 비용 증가.
|
||||
- 라우터로 분리된 파일 일부가 main에 include 되지 않아 사실상 죽은 코드가 존재.
|
||||
- 헬스체크 엔드포인트가 여러 위치에 흩어져 동작 기준이 불명확.
|
||||
|
||||
## 영향도
|
||||
- 라우팅 충돌/오동작 위험, 문서/헬스체크 불일치로 배포 검증 혼선.
|
||||
- 테스트/리팩토링 난이도 증가, 장애 시 원인 분석 지연.
|
||||
|
||||
## 발견 항목 (파일/엔드포인트)
|
||||
1) LLM 완료 엔드포인트 중복
|
||||
- main.py: `POST /complete`
|
||||
- app/router/llm_endpoint.py: `POST /api/llm/complete`
|
||||
|
||||
2) DM 전송 엔드포인트 중복
|
||||
- main.py: `POST /api/dm/send`, `/api/dm/send-to-user`, `/api/dm/send-email-summary`, `/api/dm/send-daily-summary`
|
||||
- app/router/dm_endpoint.py: `POST /send`, `/send-to-user` (라우터 미포함)
|
||||
|
||||
3) Slack 엔드포인트 중복/미포함
|
||||
- main.py: `POST /slack/events`, `/slack/interactive`
|
||||
- app/router/slack_endpoint.py: `POST /events`, `/slash` (라우터 미포함)
|
||||
|
||||
4) 헬스체크 중복
|
||||
- main.py: `GET /health`
|
||||
- app/router/llm_endpoint.py: `GET /api/llm/health`
|
||||
- app/router/slack_endpoint.py, app/router/test_endpoint.py: `GET /health` (미포함)
|
||||
- app/llm/llm_service.py, app/brain/brain_service.py, app/state/state_service.py: 각자 독립 FastAPI 앱의 `/health` (컨테이너에서 미사용)
|
||||
|
||||
5) 사실상 미사용(죽은 코드)
|
||||
- app/router/dm_endpoint.py, app/router/slack_endpoint.py, app/router/test_endpoint.py: main에 include 되지 않음.
|
||||
- app/llm/llm_service.py, app/brain/brain_service.py, app/state/state_service.py: 독립 앱 구조이나 rb8001에서 기동되지 않음.
|
||||
|
||||
## 원인 분석
|
||||
- 기능 추가/실험 과정에서 임시 라우터/독립 앱이 누적되었으나 정리 미흡.
|
||||
- 라우터 include 정책 일관성 부재, 경로 네이밍 규칙 미정립.
|
||||
|
||||
## 정리 원칙
|
||||
1) 단일 책임 라우팅: rb8001 컨테이너의 공식 엔드포인트는 main.py로 집약.
|
||||
2) 서브 기능은 Router로 모듈화하되, main에 명시적으로 include하고 경로 접두사 통일.
|
||||
3) 헬스체크 표준화: 컨테이너 헬스는 `GET /health` 하나만 진실원천(SOT)으로 유지.
|
||||
4) 미사용/실험 코드는 `experiments/`로 이동하거나 삭제.
|
||||
|
||||
## 변경 제안 (우선순위)
|
||||
1) `/complete` 제거 → `/api/llm/complete`만 유지 (app/router/llm_endpoint.py 기준).
|
||||
2) DM 엔드포인트는 `/api/dm/*`만 유지. dm_endpoint.py는 삭제 또는 main에 통합 후 중복 제거.
|
||||
3) Slack 엔드포인트는 main.py만 유지. slack_endpoint.py는 삭제 또는 `/api/slack/*`로 통합 시 중복 제거.
|
||||
4) 헬스체크: main.py의 `/health`만 남기고 나머지는 개발용으로 주석/이동.
|
||||
5) 독립 FastAPI 앱(LLM/Brain/State) 파일은 rb8001 컨테이너에서 제외. 별도 서비스로 운용 시 전용 레포/이미지로 분리.
|
||||
|
||||
## 구현 체크리스트
|
||||
- [ ] main.py의 `/complete` 제거
|
||||
- [ ] app/router/llm_endpoint.py 유지, prefix `/api/llm` 확인
|
||||
- [ ] DM 엔드포인트 중복 제거(파일 정리)
|
||||
- [ ] Slack 라우터 중복 제거(파일 정리)
|
||||
- [ ] `/health` 단일화 및 Dockerfile/compose/workflow 헬스체크 동기화
|
||||
- [ ] 불용 파일 삭제 또는 `experiments/` 이동
|
||||
|
||||
## 검증 항목
|
||||
- 빌드/기동 후 라우트 목록 점검: 중복/누락 없는지 확인
|
||||
- 헬스체크: `/health` 200, compose healthcheck 통과
|
||||
- DM/LLM/Slack 주요 플로우 수동 테스트(200/응답 구조)
|
||||
|
||||
## 교훈
|
||||
- 기능 추가 시 라우팅 정책(접두사/포함 범위)을 문서로 표준화하고 PR 단계에서 중복 검증.
|
||||
- 헬스체크는 서비스당 단일 엔드포인트로 유지하여 배포 검증 경로를 일관화.
|
||||
|
||||
## 후속 작업 제안
|
||||
- 게이트웨이 기준으로 `X-User-Id`(UUID) 신뢰, rb8001 내부의 Slack ID 변환 제거(책임 분리).
|
||||
- RB/스킬 간 통신은 HTTP API만 사용(직접 import 금지) 원칙 점검 및 위반 제거.
|
||||
|
||||
@ -1,177 +0,0 @@
|
||||
# 감정 시스템 구현 계획 (rb8001)
|
||||
|
||||
**작성일**: 2025-09-20
|
||||
**작성자**: Claude
|
||||
**관련 서비스**: rb8001
|
||||
**이슈**: 감정 분석 시스템 미구현
|
||||
|
||||
## 현재 상황
|
||||
|
||||
### rb8001 감정 시스템 현황
|
||||
- **구조만 존재**: base.py, emotion_llm.py 등 파일은 있으나 임시 구현
|
||||
- **실제 분석 없음**: 모든 감정에 균등 분포 (1/9) 반환
|
||||
- **rb10508 부재**: 이식하려던 rb10508 디렉토리 자체가 없음
|
||||
|
||||
### 구현된 부분
|
||||
```python
|
||||
# /app/core/emotion/base.py
|
||||
- EmotionState 클래스 정의
|
||||
- 9개 감정: joy, sadness, anger, fear, disgust + anxiety, envy, embarrassment, ennui
|
||||
- calculate_entropy() 함수
|
||||
- Thompson Sampling 구조
|
||||
```
|
||||
|
||||
### 미구현 부분
|
||||
1. **모델 통합**: klue/bert-base 기반 7클래스 분류기
|
||||
2. **ONNX 추론**: 모델 변환 및 최적화
|
||||
3. **Temperature Scaling**: 확률 보정
|
||||
4. **데이터베이스**: emotion_readings 테이블
|
||||
5. **API 엔드포인트**: /v1/emotion/infer 등
|
||||
|
||||
## 구현 로드맵
|
||||
|
||||
### Phase 1: 기본 감정 분석 (1주)
|
||||
1. **Day 1-2: 모델 준비**
|
||||
- klue/bert-base 기반 감정 분류 모델 준비
|
||||
- 7개 클래스: fear, surprise, anger, sadness, neutral, happiness, disgust
|
||||
- ONNX 변환 및 최적화
|
||||
|
||||
2. **Day 3-4: 추론 엔진 구현**
|
||||
```python
|
||||
# /app/core/emotion/inference.py
|
||||
class EmotionInference:
|
||||
def __init__(self, model_path: str):
|
||||
self.session = onnxruntime.InferenceSession(model_path)
|
||||
self.tokenizer = AutoTokenizer.from_pretrained("klue/bert-base")
|
||||
self.temperature = 1.0
|
||||
|
||||
def predict(self, text: str) -> Dict[str, float]:
|
||||
# 토크나이징
|
||||
inputs = self.tokenizer(text, max_length=128, truncation=True)
|
||||
# ONNX 추론
|
||||
logits = self.session.run(None, inputs)[0]
|
||||
# Temperature Scaling
|
||||
probs = softmax(logits / self.temperature)
|
||||
return dict(zip(EMOTION_LABELS, probs))
|
||||
```
|
||||
|
||||
3. **Day 5: DB 스키마 구현**
|
||||
```sql
|
||||
CREATE TABLE emotion_readings (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID REFERENCES "user"(id),
|
||||
text_hash VARCHAR(64),
|
||||
model_version VARCHAR(20),
|
||||
temperature FLOAT,
|
||||
logits JSONB,
|
||||
probs JSONB,
|
||||
top_label VARCHAR(20),
|
||||
top_p FLOAT,
|
||||
entropy FLOAT,
|
||||
meta JSONB,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_emotion_user_time ON emotion_readings(user_id, created_at);
|
||||
```
|
||||
|
||||
### Phase 2: API 및 통합 (1주)
|
||||
|
||||
1. **Day 6-7: API 엔드포인트**
|
||||
```python
|
||||
# /app/api/emotion.py
|
||||
@router.post("/v1/emotion/infer")
|
||||
async def infer_emotion(text: str, user_id: str):
|
||||
# 감정 분석
|
||||
result = emotion_inference.predict(text)
|
||||
# DB 저장
|
||||
await save_emotion_reading(user_id, text, result)
|
||||
return result
|
||||
|
||||
@router.get("/v1/emotion/timeseries")
|
||||
async def get_emotion_timeseries(user_id: str, start: datetime, end: datetime):
|
||||
# 시계열 데이터 조회
|
||||
readings = await get_readings(user_id, start, end)
|
||||
return aggregate_emotions(readings)
|
||||
```
|
||||
|
||||
2. **Day 8-9: 기존 시스템 통합**
|
||||
- Router에서 감정 분석 호출
|
||||
- 메모리 저장 시 감정 메타데이터 추가
|
||||
- Slack 응답에 감정 정보 포함
|
||||
|
||||
3. **Day 10: 시각화**
|
||||
- 감정 그래프 생성 (matplotlib/plotly)
|
||||
- Slack 이미지 업로드
|
||||
|
||||
### Phase 3: 고도화 (선택적)
|
||||
|
||||
1. **Temperature Calibration**
|
||||
- 검증 데이터셋으로 최적 T 값 찾기
|
||||
- ECE (Expected Calibration Error) 최소화
|
||||
|
||||
2. **배치 처리 최적화**
|
||||
- 마이크로배칭
|
||||
- 비동기 처리 큐
|
||||
|
||||
3. **감정 공명 시스템**
|
||||
- 과거 감정과 현재 감정 결합
|
||||
- 사용자별 감정 패턴 학습
|
||||
|
||||
## 구현 우선순위
|
||||
|
||||
### 즉시 구현 가능 (Quick Win)
|
||||
1. ✅ 감정 DB 테이블 생성
|
||||
2. ✅ 간단한 규칙 기반 감정 분석 (키워드 매칭)
|
||||
3. ✅ 감정 저장 및 조회 API
|
||||
|
||||
### 중기 목표 (1-2주)
|
||||
1. ⏳ BERT 모델 통합
|
||||
2. ⏳ ONNX 최적화
|
||||
3. ⏳ Temperature Scaling
|
||||
|
||||
### 장기 목표 (1개월+)
|
||||
1. 📅 사용자별 감정 패턴 학습
|
||||
2. 📅 실시간 감정 모니터링 대시보드
|
||||
3. 📅 감정 기반 응답 생성
|
||||
|
||||
## 리소스 요구사항
|
||||
|
||||
### 모델
|
||||
- klue/bert-base (400MB)
|
||||
- ONNX 변환 모델 (100MB)
|
||||
- 추론 시간: CPU 40-80ms, GPU 10-20ms
|
||||
|
||||
### 인프라
|
||||
- 추가 메모리: 500MB-1GB
|
||||
- DB 스토리지: 사용자당 일 100KB
|
||||
- 계산 리소스: CPU 2 cores 권장
|
||||
|
||||
## 주의사항
|
||||
|
||||
1. **프라이버시**
|
||||
- 원문 텍스트는 해시만 저장
|
||||
- 사용자 동의 필요
|
||||
- 삭제 권한 보장
|
||||
|
||||
2. **성능**
|
||||
- 캐싱 적극 활용
|
||||
- 배치 처리로 효율화
|
||||
- 비동기 처리 필수
|
||||
|
||||
3. **정확도**
|
||||
- 한국어 특화 모델 필요
|
||||
- 지속적인 모니터링
|
||||
- 사용자 피드백 수집
|
||||
|
||||
## 결론
|
||||
|
||||
"감정시스템 이식"이라는 작업은 실제로는 **새로운 구현**이 필요합니다:
|
||||
- rb10508에 구현된 감정 시스템이 없음
|
||||
- rb8001에 기본 구조만 있고 실제 기능 없음
|
||||
- 처음부터 구현 필요
|
||||
|
||||
**권장 사항**:
|
||||
1. 단계적 구현 (간단한 키워드 기반 → BERT 모델)
|
||||
2. 우선순위: DB 스키마 → API → 모델 통합
|
||||
3. 예상 소요 시간: 2-3주 (전체 구현)
|
||||
Loading…
x
Reference in New Issue
Block a user