# 로빙 아키텍처 원칙 위반 현황 및 개선 계획 ## 작성일: 2025-10-04 23:01:59 ## 작성자: happybell80 ## 위치: `/home/happybell80/ivada_project/DOCS/troubleshooting/20251004_happybell80_로빙_뇌_기관_원칙_위반_현황.md` ## 상태: 인지 완료, 점진적 개선 예정 --- ## 문제 인식 skill-slack 리포지토리에 Slack Lists API 테스트 파일이 추가되면서, 현재 rb8001이 Slack API를 직접 호출하는 구조가 로빙 아키텍처 원칙에 위배됨을 재확인했다. ## 로빙 아키텍처 핵심 원칙 ### 출처: `/DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md:7` > "컨테이너는 몸, 기억은 영혼 - 100개 로빙이 하나의 스킬 서비스를 공유한다" ### 출처: `/DOCS/300_architecture/README.md:38` > "Backend: FastAPI + Celery (로빙의 두뇌와 신경계)" ### 원칙 정리 - **로빙 컨테이너 (rb8001) = 두뇌(뇌)**: 판단과 라우팅만 수행 - **스킬 서비스 (skill-*) = 운동기관/감각기관**: 실제 실행 담당 - **DB (PostgreSQL/ChromaDB) = 기억/영혼**: 상태 저장 ### 출처: `/DOCS/troubleshooting/250721_happybell80_이메일스킬HTTP분리및아키텍처전환.md:99-113` > **교훈** > 1. "빠른 개발"이 항상 빠르지 않음 > 2. 아키텍처 원칙을 지키는 것이 장기적으로 이득 > 3. 마이크로서비스는 처음부터 제대로 분리해야 함 > > **CLAUDE.md 업데이트** > - 스킬 포트 범위: 8501-8599 > - HTTP API 통신 원칙 명시 > - 직접 import 금지 규칙 추가 --- ## 현재 원칙 위반 현황 ### 1. Slack API 직접 호출 위반 #### 250915_happybell80_Slack_메시징_운영_런북.md - **20-36줄**: `rb8001/app/router/slack_handler.py`가 WebClient로 직접 `chat_postMessage` 호출 - **38-45줄**: `rb8001/app/skills/dm_skill.py`가 직접 Slack SDK 사용 - **47-59줄**: `rb8001/app/skills/news_posting_skill.py`가 직접 Slack SDK 사용 - **176줄**: "이벤트/인터랙티브 응답: rb8001 slack_handler가 채널/스레드로 직접 전송" #### 250930_naverworks_slack_03_cold_mail_list.md - **36-40줄**: `rb8001/app/services/slack_lists_client.py` - 직접 Slack Lists API 호출 (aiohttp 사용) - **문제**: rb8001(뇌)이 직접 손을 움직이는 격 ### 2. 스킬 직접 Import 위반 #### 250819_rb8001_gmail_integration_completed.md - Gmail 스킬을 직접 import하는 구조 (HTTP API 사용 안함) #### 250914_happybell80_깡프로뉴스_용어추출_기능추가.md - rb8001이 스킬 로직 직접 포함 #### 250909_ocr_skill_implementation_plan.md - 스킬 직접 import 계획 ### 3. 관련 위반 사례 #### 250903_slack_multi_workspace_token_issue.md - rb8001이 여러 Slack 토큰 직접 관리 #### 250906_news_skill_publish_separation.md, 250907_company_x_news_implementation.md - rb8001이 뉴스 게시 직접 수행 --- ## 위반 패턴 분석 ### 잘못된 흐름 (현재) - rb8001(뇌) → 직접 Slack API 호출 - rb8001(뇌) → 직접 Lists API 호출 - rb8001(뇌) → 스킬 로직 import ### 올바른 흐름 (목표) - rb8001(뇌) → skill-slack(손)에 HTTP 요청 → Slack API 호출 - rb8001(뇌) → skill-slack(손)에 HTTP 요청 → Lists API 호출 - rb8001(뇌) → skill-*(기관)에 HTTP 요청 → 스킬 실행 --- ## 개선 계획 ### Phase 1: skill-slack Lists API 엔드포인트 추가 (우선) 1. skill-slack에 `/api/v1/lists/items` 엔드포인트 구현 - POST: 리스트 아이템 생성 (slackLists.items.create) - GET: 리스트 아이템 조회 (slackLists.items.list) - PUT: 리스트 아이템 수정 (slackLists.items.update) 2. `tests/test_slack_lists.py`의 헬퍼 함수를 서비스 모듈로 이동 3. rb8001의 `slack_lists_client.py` → skill-slack HTTP 호출로 변경 ### Phase 2: rb8001 Slack 직접 호출 제거 1. rb8001/app/router/slack_handler.py → skill-slack /api/v1/send 사용 2. rb8001/app/skills/dm_skill.py → skill-slack HTTP 호출로 변경 3. rb8001/app/skills/news_posting_skill.py → skill-slack HTTP 호출로 변경 4. Slack SDK (slack_sdk) 의존성 제거 ### Phase 3: 기타 스킬 분리 1. Gmail 스킬 HTTP API로 완전 분리 2. OCR 스킬 분리 시 HTTP API 기본 적용 3. 뉴스 스킬 로직 분리 ### Phase 4: 문서 업데이트 1. 위반 사례 문서에 "개선 완료" 표시 2. 아키텍처 원칙 문서 강화 3. 신규 스킬 개발 시 체크리스트 추가 --- ## 즉시 적용 가능한 원칙 ### skill-slack 테스트 파일 활용 1. `/home/happybell80/ivada_project/skill-slack/tests/test_slack_lists.py`의 헬퍼 함수: - `list_all_items()` → GET 엔드포인트 - `add_file_to_list()` → POST 엔드포인트 2. 실제 컬럼 구조 확인 후 구현 (추측 금지) 3. rb8001은 HTTP로만 호출 ### 개발 체크리스트 1. 로빙이 외부 API를 직접 호출하는가? → 스킬로 분리 2. 로빙이 스킬 로직을 포함하는가? → HTTP API로 분리 3. 로빙이 스킬을 import하는가? → HTTP 클라이언트로 교체 --- ## 교훈 1. **"빠른 개발"의 함정**: 직접 호출이 당장은 빠르지만, 나중에 더 큰 리팩토링 비용 발생 2. **아키텍처 일관성**: 원칙을 지키면 100개 로빙 운영 시 리소스 절감 (뇌 = 512MB, 스킬 = 공유) 3. **문서의 중요성**: 원칙 문서가 있었지만 실제 코드에 반영 안됨 → 주기적 점검 필요 --- ## 참고 문서 - `/DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md` - 핵심 원칙 - `/DOCS/300_architecture/README.md` - 아키텍처 개요 - `/DOCS/troubleshooting/250721_happybell80_이메일스킬HTTP분리및아키텍처전환.md` - 성공 사례 - `/DOCS/troubleshooting/250915_happybell80_Slack_메시징_운영_런북.md` - 위반 현황 - `/DOCS/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md` - Lists API 위반 --- *"컨테이너는 몸, 기억은 영혼 - 뇌는 판단만, 손발은 스킬이 담당한다"*