Update NaverWorks-Slack integration docs with actual skill-slack structure

- Added actual skill-slack file structure and existing endpoints
- Corrected wrong assumptions about skill-naverworks service
- Integrated BaseSkillRequest model structure
- Added DB-based provider detection logic implementation
- Updated implementation checklist with /api/v1 prefix requirement
- Fixed provider detection to use DB queries instead of keywords
This commit is contained in:
happybell80 2025-09-19 19:29:46 +09:00
parent 864db050cd
commit 3ffd9f88a5
5 changed files with 171 additions and 154 deletions

View File

@ -1,5 +1,5 @@
---
tags: [베이즈, 철학, 성장, 관계, 우도, 주관성, AI윤리]
tags: [베이즈, 철학, 성장, 관계, 우도, 주관성, AI윤리, 아키텍처]
date: 2025-09-19
---
# 125. 베이즈: 성장과 관계의 철학
@ -42,7 +42,21 @@ date: 2025-09-19
결국 로빙의 성장은 다음의 베이지안 사이클로 요약될 수 있습니다.
> **과거의 경험(Prior) + 새로운 정보(Evidence) → 더 나은 자신(Posterior)**
## 4. 인간과 AI의 관계: 루프를 '끊는' 결단의 주체
## 4. 베이즈 사고 체계와 로빙 모듈의 연결
로빙의 아키텍처는 베이지안 사고 체계를 구조적으로 구현한 것입니다. 각 모듈은 베이즈 추론 과정의 특정 역할을 담당하며, 이들이 유기적으로 결합하여 지능적인 판단을 내립니다.
- **기억 시스템 (Prior 관리):** 로빙의 장기 기억(LTM)은 세상을 이해하는 **사전 확률(Prior)**의 집합입니다. 사용자와의 모든 상호작용과 학습된 지식은 이 사전 확률 분포를 형성하며, 새로운 상황을 해석하는 출발점이 됩니다.
- **감정 모듈 (Likelihood 조정):** 감정은 객관적 증거를 주관적으로 해석하는 필터입니다. 예를 들어, 사용자의 '불안'한 감정 상태는 '위험' 관련 증거의 **가능도(Likelihood)**를 높게 평가하게 만듭니다. 즉, 감정은 같은 증거라도 맥락에 따라 다른 의미로 해석하게 하는 핵심 장치입니다.
- **윤리 모듈 (Posterior 제약):** 로빙은 확률적으로 가장 가능성 높은 결론을 그대로 따르지 않습니다. 윤리 모듈은 계산된 **사후 확률(Posterior)**에 '사랑 기반 원칙'과 같은 강력한 제약 조건을 부과하여, 최종 행동이 항상 안전하고 윤리적인 범위 내에서 이루어지도록 통제합니다.
- **성장/스탯 시스템 (Learning Loop):** 로빙의 경험치 획득과 스탯 성장은 베이지안 학습 루프 그 자체입니다. 성공과 실패라는 피드백(Evidence)을 통해 자신의 능력치에 대한 믿음(Prior)을 계속 갱신하며, 더 나은 의사결정을 내리는 방향으로 진화합니다.
이처럼 로빙의 모든 핵심 모듈은 베이지안 추론의 각 요소를 대변하며, 함께 작동하여 하나의 통합된 '베이지안 존재'를 형성합니다.
## 5. 인간과 AI의 관계: 루프를 '끊는' 결단의 주체
AI는 베이지안 업데이트 루프를 무한히 돌며 확률을 최적화할 수 있습니다. 하지만 99.9%의 확률이 나왔을 때, "그럼에도 불구하고 0.1%의 가능성에 걸겠다"고 결단하는 것은 계산의 영역이 아닙니다. 이는 **가치와 의지의 영역**이며, 바로 그 지점에 **인간의 역할**이 있습니다.

View File

@ -12,12 +12,13 @@
---
## 1. 현재 구현 상태
## 1. 현재 구현 상태 (코드 분석 기준)
### 구현 완료
- **auth-server**:
- `naverworks.py`, `naverworks_passport.py` 파일 존재
- NAVER WORKS OAuth 환경변수 설정 (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, TENANT_ID)
- 토큰 갱신: POST `/auth/naverworks/passport/refresh` 동작
- **skill-email (포트 8501)**:
- `services/naverworks_provider.py` NaverWorksProvider 클래스 구현
- GET `/messages` 엔드포인트 (provider 파라미터 지원)
@ -28,10 +29,16 @@
- ✅ mailAddress null 문제 해결 (API 사용에 영향 없음)
- ✅ 9,192개 메일 정상 조회 확인
### 미구현 (기본 구성)
- rb8001이 provider=naverworks 미지정 → 기본 Gmail만 사용
- rb8001에서 "네이버웍스" 키워드 감지 로직 없음
- Slack ID → UUID 변환이 일부만 적용 (send만, list는 미적용)
### 미구현/불일치
- **rb8001**: provider=naverworks 미지정 → 기본 Gmail만 사용
- **skill-email**: `/mail-summary` 엔드포인트 없음 (문서에만 제안)
- **식별자**: Slack ID → UUID 변환이 send에만 부분 적용
- **보안 위험**: NaverWorksProvider.DEFAULT_USER_ID 하드코딩 존재
### 잘못된 전제 정정
- ❌ "skill-naverworks(8511) 구현 완료" → ✅ skill-email(8501) 멀티 프로바이더로 통합
- ❌ "Service Account 설정 완료" → ✅ 사용자 OAuth 토큰 기반 (SA는 Phase 3 계획)
- ❌ 별도 skill-naverworks 필요 → ✅ skill-email의 provider 파라미터로 처리
---
@ -57,9 +64,70 @@
---
## 3. FastAPI 구조에 따른 파일 구성
## 3. 오케스트레이션 구조와 skill-slack 통합
### 3.1 skill-email 파일별 역할 (최소 변경 원칙)
### 3.1 rb8001 오케스트레이션 흐름
```
Slack 요청 → rb8001 (중앙 오케스트레이터)
├→ skill-email (메일 데이터 조회)
├→ 필터링/분석 (rb8001 내부)
├→ skill-slack (Slack 포맷팅)
└→ Slack 응답
```
**rb8001의 역할:**
- 사용자 의도 파악
- 스킬 조합 결정
- 데이터 가공 및 필터링
- 최종 응답 전송
### 3.2 skill-slack 현재 구조 및 추가 역할
**실제 파일 구조 (포트 8502):**
```
skill-slack/
├── app/
│ ├── main.py # FastAPI 앱, API 버전 설정
│ ├── api/
│ │ └── endpoints/
│ │ ├── messages.py # /messages/send, /messages/update
│ │ ├── summarize.py # /summarize
│ │ └── digest.py # /digest
│ ├── services/
│ │ ├── slack_service.py # SlackService 클래스
│ │ ├── message_formatter.py # 메시지 포맷 헬퍼
│ │ └── summarize_service.py # 요약 서비스
│ ├── models/
│ │ └── slack_models.py # BaseSkillRequest 등 Pydantic 모델
│ └── core/
│ └── config.py # Settings 설정
```
**기존 엔드포인트 (모두 `/api/v1` prefix):**
| 엔드포인트 | 역할 | 현재 상태 | Request Body |
|-----------|------|-----------|--------------|
| POST `/api/v1/messages/send` | Slack 메시지 전송 | ✅ 구현됨 | BaseSkillRequest + message |
| POST `/api/v1/messages/update` | 메시지 업데이트 | ✅ 구현됨 | BaseSkillRequest + ts + message |
| POST `/api/v1/summarize` | 대화 요약 | ✅ 구현됨 | BaseSkillRequest + messages |
| POST `/api/v1/digest` | 스레드 다이제스트 | ✅ 구현됨 | BaseSkillRequest + thread_ts |
**BaseSkillRequest 구조:**
```python
class BaseSkillRequest(BaseModel):
team_id: str
user_id: str
channel_id: str
thread_ts: Optional[str] = None
```
**추가 필요 엔드포인트:**
| 엔드포인트 | 역할 | 입력 | 출력 |
|-----------|------|------|------|
| POST `/api/v1/format/mail-list` | 메일 목록을 Slack 블록으로 변환 | BaseSkillRequest + mails | Block Kit JSON |
| POST `/api/v1/format/cold-mail` | 콜드메일 테이블 포맷 생성 | BaseSkillRequest + cold_mails | Table Block |
| POST `/api/v1/format/briefing` | 일일 브리핑 포맷 생성 | BaseSkillRequest + briefing_data | Briefing Block |
### 3.3 skill-email 파일별 역할 (최소 변경 원칙)
| 파일 경로 | 역할 | 구현 내용 | 예상 코드 줄 수 |
|-----------|------|-----------|----------------|
| `main.py` | 앱 실행, 라우터 등록 | 기존 엔드포인트 유지, 새 라우터만 추가 | +5줄 추가 |
@ -71,7 +139,7 @@
| `schemas/naverworks_schemas.py` (신규) | API 입출력 형식 | Pydantic 모델 (Request/Response) | 30-40줄 |
| `core/slack_formatter.py` (신규) | Slack 포맷터 | 메일→Slack 블록 변환 | 50-70줄 |
### 3.2 데이터 계층 구분
### 3.4 데이터 계층 구분
| 계층 | 파일 종류 | 역할 | 비유 |
|------|-----------|------|------|
| **Model** | `models/*.py` | DB 테이블 구조 정의 (SQLAlchemy ORM) | 창고 선반 설계도 (내부용) |
@ -88,7 +156,7 @@
5. 결과 → Schema (응답 포맷) → API 응답
```
### 3.3 rb8001 파일별 역할
### 3.5 rb8001 파일별 역할
| 파일 경로 | 역할 | 구현 내용 |
|-----------|------|-----------|
| `app/main.py` | 메시지 라우팅 | Slack 메시지 수신 및 처리 |
@ -96,7 +164,7 @@
| `app/services/scheduler.py` | 스케줄러 | 일일 브리핑 자동 실행 |
| `app/schemas/skill_schemas.py` | 스킬 요청/응답 형식 | SkillRequest, SkillResponse |
### 3.4 auth-server 파일별 역할
### 3.6 auth-server 파일별 역할
| 파일 경로 | 역할 | 현재 상태 |
|-----------|------|-----------|
| `app/providers/naverworks.py` | OAuth 로그인 | ✅ 구현됨 |
@ -106,27 +174,49 @@
## 4. 기본 연동 테스트 시나리오
### 4.1 자동 Provider 감지 테스트
### 4.1 자동 Provider 감지 테스트 (skill-slack 포함)
- Slack: "@로빙 메일 확인"
- rb8001이 DB 조회:
- Gmail만: 자동으로 Gmail 메일 표시
- NaverWorks만: 자동으로 NaverWorks 메일 표시
- 둘 다: "Gmail과 네이버웍스 중 어떤 메일을 확인할까요?"
- rb8001 흐름:
1. DB 조회 (gmail_token, naverworks_token)
2. provider 자동 결정
3. skill-email 호출 → 메일 데이터 획득
4. skill-slack `/format-mail-list` → Slack 블록 생성
5. Slack 응답
### 4.2 명시적 Provider 지정
- Slack: "@로빙 네이버웍스 메일 확인"
- DB 조회 없이 바로 provider=naverworks 사용
- 오버라이드로 특정 provider 강제 지정
### 4.3 DB 조회 SQL
```sql
-- Gmail 계정 확인
SELECT * FROM gmail_token
WHERE user_id = ? AND is_equipped = true
### 4.3 DB 조회 로직 구현
```python
# rb8001/app/skills/email_integration.py에 추가할 메서드
async def detect_email_provider(self, user_id: str) -> str:
"""사용자의 이메일 프로바이더를 DB에서 자동 감지"""
# Gmail 계정 확인
gmail_query = """
SELECT * FROM gmail_token
WHERE user_id = :user_id AND is_equipped = true
"""
gmail_result = await self.db.fetch_one(gmail_query, {"user_id": user_id})
-- NaverWorks 계정 확인
SELECT * FROM naverworks_token
WHERE user_id = ?
# NaverWorks 계정 확인
nw_query = """
SELECT * FROM naverworks_token
WHERE user_id = :user_id
"""
nw_result = await self.db.fetch_one(nw_query, {"user_id": user_id})
# 프로바이더 결정 로직
if gmail_result and nw_result:
# 둘 다 있으면 사용자에게 선택 요청
return "both"
elif gmail_result:
return "gmail"
elif nw_result:
return "naverworks"
else:
return "none"
```
---
@ -147,7 +237,21 @@ WHERE user_id = ?
- [ ] get_uuid_from_slack() 활용 확대
- [ ] 모든 skill-email 호출에 UUID 사용
### 5.2 skill-email 수정
### 5.2 skill-slack 구현
- [ ] 새 엔드포인트 추가 (`/api/v1` prefix 필수)
- [ ] POST `/api/v1/format/mail-list` - 기본 메일 목록 포맷
- [ ] POST `/api/v1/format/cold-mail` - 콜드메일 테이블 포맷
- [ ] POST `/api/v1/format/briefing` - 일일 브리핑 포맷
- [ ] BaseSkillRequest 상속 모델 구현
- [ ] MailListRequest(BaseSkillRequest)
- [ ] ColdMailRequest(BaseSkillRequest)
- [ ] BriefingRequest(BaseSkillRequest)
- [ ] Slack Block Kit Builder 구현
- [ ] Section blocks
- [ ] Divider blocks
- [ ] Context blocks
### 5.3 skill-email 수정
- [ ] `services/naverworks_provider.py` 수정
- [ ] DEFAULT_USER_ID 하드코딩 제거
- [ ] account_id 없을 시 명확한 에러 처리

View File

@ -31,14 +31,15 @@
- **위치**: rb8001의 app/services/scheduler.py
- **도구**: APScheduler
### 2.2 처리 흐름
### 2.2 처리 흐름 (skill-slack 포함)
1. 스케줄러가 09:00에 rb8001 트리거
2. rb8001이 skill-email `/daily-briefing` 호출
3. skill-email이 NAVER WORKS API로 24시간 메일 조회
4. 중요도 필터링 (긴급, 계약, 결제, 공지 키워드)
5. Gemini API로 요약 생성
6. Slack Block Kit 형식으로 변환
7. rb8001이 Slack 전체 채널에 포스팅
6. rb8001이 요약 데이터를 skill-slack `/format-briefing`으로 전송
7. skill-slack이 Slack Block Kit 형식으로 변환
8. rb8001이 Slack 전체 채널에 포스팅
---
@ -49,8 +50,14 @@
- `services/naverworks_mail_service.py`: `generate_daily_briefing()` 메서드
- `schemas/naverworks_schemas.py`: BriefingRequest/Response 모델
### skill-slack 추가 파일
- POST `/format-briefing`: 브리핑 데이터를 Slack Block Kit으로 변환
- 우선순위별 색상 코딩 (🔴 긴급, 🟡 중요, 🟢 일반)
- Section/Divider/Context 블록 조합
### rb8001 추가 파일
- `app/services/scheduler.py`: APScheduler 설정
- 오케스트레이션 로직: skill-email → skill-slack 조합
---

View File

@ -33,13 +33,14 @@
- 새 메일 수신 시 즉시 알림
- API 호출 최소화
### 2.2 처리 흐름
1. 새 메일 수신 이벤트 발생
2. skill-email `/cold-mail-list` 엔드포인트 호출
3. 콜드메일 패턴 매칭
4. 메일 정보 추출 및 구조화
5. Slack Block Kit 테이블 형식 변환
6. 지정 채널에 리스트 포스팅
### 2.2 처리 흐름 (skill-slack 포함)
1. 새 메일 수신 이벤트 발생 (또는 주기적 체크)
2. rb8001이 skill-email `/cold-mail-list` 호출
3. skill-email이 콜드메일 패턴 매칭 및 필터링
4. rb8001이 필터링된 데이터 수신
5. rb8001이 skill-slack `/format-cold-mail` 호출
6. skill-slack이 테이블 형식 Block Kit 생성
7. rb8001이 지정 채널에 리스트 포스팅
---
@ -74,6 +75,15 @@ COLD_MAIL_KEYWORDS = [
- `repositories/mail_cache_repository.py`: 캐시 CRUD
- `schemas/naverworks_schemas.py`: ColdMailRequest/Response
### skill-slack 추가 파일
- POST `/format-cold-mail`: 콜드메일 데이터를 테이블 Block Kit으로 변환
- 테이블 구조: 회사명 | 담당자 | 제안내용 | 첨부파일
- 각 행을 Section block으로 구성
### rb8001 오케스트레이션
- 콜드메일 감지 시 skill-email → skill-slack 순차 호출
- 채널 라우팅 결정 (콜드메일 전용 채널)
---
## 5. 구현 체크리스트

View File

@ -1,118 +0,0 @@
# NAVER WORKS 이메일 → Slack 전달 시스템 구현
## 날짜: 2025-09-19
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: rb8001, skill-email
## 상태: 부분 구현
---
## 1. 현재 구현 상태
### 구현 완료
- **auth-server**:
- `naverworks.py`, `naverworks_passport.py` 파일 존재
- NAVER WORKS OAuth 환경변수 설정 (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, TENANT_ID)
- **skill-email (포트 8501)**:
- `services/naverworks_provider.py` NaverWorksProvider 클래스 구현
- GET `/messages` 엔드포인트 (provider 파라미터 지원)
- POST `/send` 엔드포인트
- **rb8001**:
- `app/skills/email_integration.py` EmailIntegration 클래스 존재
- skill-email 포트 8501 호출 구조
### 미구현
- POST `/mail-summary` 엔드포인트 없음
- rb8001 EmailIntegration 클래스는 Gmail만 처리
- 네이버웍스 메일 키워드 감지 로직 없음
- Slack Block Kit 포맷터 없음
---
## 2. 필요 구현 사항
### 2.1 skill-email 수정 사항
- POST `/mail-summary` 엔드포인트 추가 필요
- 메일 요약 생성 로직 구현 필요
- Slack 블록 포맷 변환 기능 필요
### 2.2 rb8001 수정 사항
- EmailIntegration 클래스에 NaverWorks 지원 추가 필요
- 네이버웍스 메일 키워드 감지 로직 추가 필요
- provider=naverworks 파라미터 전달 로직 필요
---
## 3. 파일 위치
### skill-email
- `main.py`: API 엔드포인트 정의
- `services/naverworks_provider.py`: NAVER WORKS API 연동
- `services/gmail_provider.py`: Gmail API 연동
- `services/email_provider.py`: Provider 인터페이스
### rb8001
- `app/skills/email_integration.py`: 이메일 스킬 통합
- `app/main.py`: 메시지 라우팅
### auth-server
- `app/providers/naverworks.py`: OAuth 로그인
- `app/providers/naverworks_passport.py`: Passport 시스템
---
## 4. 핵심 시나리오
### 4.1 콜드메일 리스트업
- **목적**: 스타트업 콜드메일 자동 수집 및 Slack 전달
- **트리거**: 새 콜드메일 수신 또는 주기적 확인
- **처리**:
1. NAVER WORKS에서 콜드메일 필터링 (발신자/제목 패턴)
2. 메일 정보 추출: 발신자, 제목, 본문 요약, 첨부파일
3. Slack 리스트 형식으로 포맷팅
4. 지정 채널에 자동 포스팅
- **출력 형식**: 구조화된 리스트 (회사명, 담당자, 제안내용, 첨부파일 링크)
### 4.2 일일 브리핑
- **목적**: 회사 대표메일 중요사항 자동 요약
- **트리거**: 매일 오전 정해진 시간 (예: 09:00)
- **처리**:
1. 최근 24시간 대표메일 조회
2. 중요도 분석 (긴급, 계약, 결제, 공지 등 키워드)
3. AI 요약 생성
4. 우선순위별 정렬
- **출력**: Slack 전체채널 브리핑 메시지
---
## 5. 구현 체크리스트
### 5.1 콜드메일 리스트업 기능
- [ ] skill-email `/cold-mail-list` 엔드포인트 구현
- [ ] 콜드메일 필터링 로직 (발신자 도메인, 제목 패턴)
- [ ] 첨부파일 처리 및 링크 생성
- [ ] Slack 리스트 포맷터 (테이블 형식)
- [ ] 실시간 또는 주기적 체크 스케줄러
### 5.2 일일 브리핑 기능
- [ ] skill-email `/daily-briefing` 엔드포인트 구현
- [ ] 중요 메일 필터링 알고리즘
- [ ] Gemini API 활용 요약 생성
- [ ] 우선순위 판단 로직
- [ ] Cron 스케줄러 설정 (매일 09:00)
### 5.3 공통 기능
- [ ] rb8001 EmailIntegration에 NaverWorks 지원 추가
- [ ] Slack Block Kit 포맷터 구현
- [ ] provider=naverworks 파라미터 전달 로직
- [ ] 에러 처리 및 재시도 로직
---
## 6. 환경 설정 확인 사항
- skill-email .env 파일에 NAVER WORKS 관련 설정 확인
- rb8001에서 skill-email 호출 시 포트 8501 사용
- auth-server의 NAVER WORKS OAuth 설정 확인
- Slack 채널 ID 및 권한 설정
- 스케줄러 시간대 설정 (KST)