diff --git a/100_philosophy/125_베이즈_성장과_관계의_철학.md b/100_philosophy/125_베이즈_성장과_관계의_철학.md index d99470c..1f85802 100644 --- a/100_philosophy/125_베이즈_성장과_관계의_철학.md +++ b/100_philosophy/125_베이즈_성장과_관계의_철학.md @@ -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%의 가능성에 걸겠다"고 결단하는 것은 계산의 영역이 아닙니다. 이는 **가치와 의지의 영역**이며, 바로 그 지점에 **인간의 역할**이 있습니다. diff --git a/troubleshooting/250919_naverworks_slack_01_base_configuration.md b/troubleshooting/250919_naverworks_slack_01_base_configuration.md index 874fa54..caa6822 100644 --- a/troubleshooting/250919_naverworks_slack_01_base_configuration.md +++ b/troubleshooting/250919_naverworks_slack_01_base_configuration.md @@ -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 없을 시 명확한 에러 처리 diff --git a/troubleshooting/250919_naverworks_slack_02_daily_briefing.md b/troubleshooting/250919_naverworks_slack_02_daily_briefing.md index 7ec34bf..6ba6de4 100644 --- a/troubleshooting/250919_naverworks_slack_02_daily_briefing.md +++ b/troubleshooting/250919_naverworks_slack_02_daily_briefing.md @@ -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 조합 --- diff --git a/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md b/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md index bfbac69..d806a08 100644 --- a/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md +++ b/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md @@ -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. 구현 체크리스트 diff --git a/troubleshooting/250919_naverworks_to_slack_mail_integration.md b/troubleshooting/250919_naverworks_to_slack_mail_integration.md deleted file mode 100644 index e283343..0000000 --- a/troubleshooting/250919_naverworks_to_slack_mail_integration.md +++ /dev/null @@ -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) \ No newline at end of file