Add: Slack 메시지 처리 아키텍처 분석 및 개선 방안 문서
This commit is contained in:
parent
6e6f6e32ca
commit
61321126a7
299
ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md
Normal file
299
ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
# Slack 메시지 처리 아키텍처 분석 및 개선 방안
|
||||||
|
|
||||||
|
작성일: 2025년 8월 12일
|
||||||
|
작성자: Claude (51124 서버)
|
||||||
|
|
||||||
|
## 1. 현재 상황 분석
|
||||||
|
|
||||||
|
### 1.1 rb10508_micro Slack 메시지 처리 흐름
|
||||||
|
|
||||||
|
#### 메시지 수신 경로
|
||||||
|
1. nginx (51123) → `/api/slack/events` (10508 포트)
|
||||||
|
2. endpoints.py:115-135에서 POST 요청 수신
|
||||||
|
3. BackgroundTasks로 비동기 처리 (Slack 3초 룰 준수)
|
||||||
|
4. 즉시 {"ok": True} 반환
|
||||||
|
|
||||||
|
#### 비동기 메시지 처리 (slack_service.py)
|
||||||
|
1. process_slack_event() 호출
|
||||||
|
2. 봇 자신 메시지 필터링 (bot_user_id 체크)
|
||||||
|
3. _handle_message_event() 비동기 실행
|
||||||
|
4. user_id, channel_id, text 추출
|
||||||
|
5. thread_ts 처리 (스레드 대화 유지)
|
||||||
|
|
||||||
|
#### Brain 처리 (think_functional)
|
||||||
|
1. 입력 추출: message, user_id, context
|
||||||
|
2. 의도 분석: "general_conversation" (하드코딩)
|
||||||
|
3. Identity 조회: user_name, robing_name
|
||||||
|
4. 이름 감지: "내 이름은", "너를 ~라고 부를게"
|
||||||
|
5. 메모리 검색: ChromaDB query (100개 → 선택)
|
||||||
|
6. Gemini API 응답 생성
|
||||||
|
7. 이모지/마크다운 제거
|
||||||
|
8. 메모리 저장 준비
|
||||||
|
9. ChromaDB 저장
|
||||||
|
10. 감정 분석
|
||||||
|
11. 결과 반환
|
||||||
|
|
||||||
|
#### 메모리 저장 (storage.py)
|
||||||
|
1. prepare_memory(): user/assistant 각각
|
||||||
|
2. save_memories(): 일괄 저장
|
||||||
|
3. ChromaDB collection: rb10508_test_episodic
|
||||||
|
4. HTTP 임베딩: skill-embedding (8515)
|
||||||
|
5. 메타데이터: user_id, role, timestamp
|
||||||
|
|
||||||
|
#### Slack 응답 전송
|
||||||
|
1. chat.postMessage API 호출
|
||||||
|
2. thread_ts 포함 (스레드 유지)
|
||||||
|
3. 응답 시간 추가 (선택)
|
||||||
|
|
||||||
|
### 1.2 저장 상태 확인
|
||||||
|
|
||||||
|
- **정상 작동 중**: 로그에서 확인
|
||||||
|
- "Processing message from U0925SXQFDK"
|
||||||
|
- "[메모리] 검색: 6개 → LLM 선택: 4개"
|
||||||
|
- "[대화] 2개 메모리 저장 완료"
|
||||||
|
- **ChromaDB 저장**: rb10508_test_episodic에 5개 문서
|
||||||
|
|
||||||
|
## 2. 현재 문제점
|
||||||
|
|
||||||
|
### 2.1 Slack 메시지 라우팅 문제
|
||||||
|
- skill-slack이 rb8001에만 연결됨
|
||||||
|
- rb10508_micro는 nginx를 통해서만 메시지 수신
|
||||||
|
- 직접적인 Slack 봇 연결 없음
|
||||||
|
|
||||||
|
### 2.2 사용자 식별 문제
|
||||||
|
- Slack user_id (U0925SXQFDK)를 그대로 사용
|
||||||
|
- 실제 시스템 user_id와 매핑 없음
|
||||||
|
- 모든 Slack 사용자가 같은 ChromaDB 컬렉션 공유
|
||||||
|
- 사용자별 개인화된 기억 분리 안 됨
|
||||||
|
|
||||||
|
### 2.3 데이터 저장량 부족
|
||||||
|
- 5개 문서만 저장됨 (실제 대화량 대비 적음)
|
||||||
|
- 저장은 되지만 누적이 제대로 안 됨
|
||||||
|
- 사용자별 컬렉션 분리 없어서 혼재 가능
|
||||||
|
|
||||||
|
### 2.4 아키텍처 불일치
|
||||||
|
- skill-slack → rb8001 (하드코딩)
|
||||||
|
- nginx → rb10508_micro (프록시)
|
||||||
|
- 이중 경로로 인한 혼란
|
||||||
|
|
||||||
|
### 2.5 Identity 관리 미흡
|
||||||
|
- user_name, robing_name은 저장하지만
|
||||||
|
- 실제 사용자 계정과 연결 안 됨
|
||||||
|
- OAuth 로그인과 Slack 사용자 매핑 없음
|
||||||
|
|
||||||
|
## 3. Slack 사용자 매핑 방안
|
||||||
|
|
||||||
|
### 3.1 필요한 DB 테이블 구조
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE slack_user_mapping (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
slack_user_id VARCHAR(100) NOT NULL, -- U04KJHGLS
|
||||||
|
slack_workspace_id VARCHAR(100), -- T1234567
|
||||||
|
user_id UUID REFERENCES users(id), -- 우리 시스템 사용자
|
||||||
|
robing_id VARCHAR(100), -- rb10508_micro
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
UNIQUE(slack_user_id, slack_workspace_id)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 사용자 식별 플로우
|
||||||
|
|
||||||
|
```
|
||||||
|
Slack 메시지 수신
|
||||||
|
↓
|
||||||
|
slack_user_id (U04KJHGLS) 추출
|
||||||
|
↓
|
||||||
|
DB 조회: slack_user_mapping
|
||||||
|
↓
|
||||||
|
user_id, robing_id 획득
|
||||||
|
↓
|
||||||
|
해당 로빙의 ChromaDB에 저장
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 구현 필요 사항
|
||||||
|
|
||||||
|
#### 51124 서버 (로빙)
|
||||||
|
- Slack 이벤트에서 user_id 추출
|
||||||
|
- DB 조회하여 사용자 매핑
|
||||||
|
- ChromaDB에 사용자별 컨텍스트 저장
|
||||||
|
|
||||||
|
#### 51123 서버 (DB)
|
||||||
|
- slack_user_mapping 테이블 생성
|
||||||
|
- API 엔드포인트 제공 (조회/생성)
|
||||||
|
|
||||||
|
### 3.4 초기 매핑 방법
|
||||||
|
- Slack OAuth 로그인 시 매핑 생성
|
||||||
|
- 또는 관리자가 수동 매핑
|
||||||
|
|
||||||
|
### 3.5 추가 고려사항
|
||||||
|
1. 멀티 workspace: 한 사용자가 여러 workspace 사용
|
||||||
|
2. 로빙 변경: 사용자가 다른 로빙 선택 시 업데이트
|
||||||
|
3. 권한 관리: Slack 봇 토큰 안전한 저장
|
||||||
|
|
||||||
|
## 4. skill-slack 서비스 분석
|
||||||
|
|
||||||
|
### 4.1 skill-slack이 하는 일
|
||||||
|
|
||||||
|
**skill-slack은 Slack API 기능만 제공하는 마이크로서비스입니다:**
|
||||||
|
|
||||||
|
#### 주요 기능
|
||||||
|
1. **메시지 전송** (`/api/v1/messages/send`)
|
||||||
|
- 다른 서비스가 Slack에 메시지 보낼 때 사용
|
||||||
|
- 채널, 텍스트, 블록 전송
|
||||||
|
|
||||||
|
2. **메시지 업데이트** (`/api/v1/messages/update`)
|
||||||
|
- 기존 메시지 수정
|
||||||
|
|
||||||
|
3. **다이제스트** (`/api/v1/digest`)
|
||||||
|
- 스레드 요약
|
||||||
|
|
||||||
|
4. **액션 처리** (`/api/v1/actions`)
|
||||||
|
- Slack 버튼/인터랙션 처리
|
||||||
|
|
||||||
|
### 4.2 중요한 발견
|
||||||
|
- **skill-slack은 Slack 이벤트를 수신하지 않습니다**
|
||||||
|
- **단순히 API 래퍼 역할만 합니다**
|
||||||
|
- **실제 Slack 봇 이벤트는 rb8001이나 rb10508이 직접 받습니다**
|
||||||
|
|
||||||
|
### 4.3 실제 상황
|
||||||
|
- rb10508_micro가 `/api/slack/events`로 이벤트 직접 수신
|
||||||
|
- skill-slack은 메시지 전송 도구일 뿐
|
||||||
|
- nginx 라우팅 설정이 핵심
|
||||||
|
|
||||||
|
## 5. 로빙 설계 철학과 Slack 통합
|
||||||
|
|
||||||
|
### 5.1 스킬 시스템 철학 (문서 분석)
|
||||||
|
- 스킬은 **"아이템"처럼 장착/해제** 가능한 능력
|
||||||
|
- 레벨과 스탯에 따라 사용 가능 여부 결정
|
||||||
|
- 외부 도구를 통합하는 **API 아이템** 개념
|
||||||
|
|
||||||
|
### 5.2 Slack의 위치
|
||||||
|
- **API 아이템 유형** (외부 서비스 접근권)
|
||||||
|
- 레벨 요구사항과 권한 관리 필요
|
||||||
|
- OAuth 기반 인증으로 보안 관리
|
||||||
|
|
||||||
|
### 5.3 아이템 시스템 적용
|
||||||
|
|
||||||
|
```python
|
||||||
|
class SlackItem(APIItem):
|
||||||
|
name = "Slack Messenger"
|
||||||
|
level_req = 3 # 레벨 3부터 사용 가능
|
||||||
|
permissions = ["chat:write", "channels:read"]
|
||||||
|
|
||||||
|
async def send_message(self, channel, text):
|
||||||
|
# skill-slack 서비스 호출
|
||||||
|
return await httpx.post(
|
||||||
|
"http://localhost:8502/api/v1/messages/send",
|
||||||
|
json={"channel": channel, "text": text}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 권장 아키텍처
|
||||||
|
|
||||||
|
### 6.1 Slack 아이템 방식 아키텍처
|
||||||
|
|
||||||
|
1. **Auth 서버에서 Slack 권한 관리**
|
||||||
|
- 사용자가 Slack OAuth 인증
|
||||||
|
- Auth 서버가 봇 토큰 저장
|
||||||
|
- 사용자별 workspace 권한 관리
|
||||||
|
|
||||||
|
2. **Slack 앱 설정의 Event URL**
|
||||||
|
- 직접 로빙 엔드포인트 지정
|
||||||
|
- 예: `https://ro-being.com/rb10508/api/slack/events`
|
||||||
|
- 각 로빙이 자체 Slack 이벤트 처리
|
||||||
|
|
||||||
|
3. **사용자-로빙 연결**
|
||||||
|
- Auth 서버가 사용자와 로빙 매핑
|
||||||
|
- Slack user_id → system user_id → robing_id
|
||||||
|
- 로빙이 직접 해당 사용자 메시지 처리
|
||||||
|
|
||||||
|
4. **skill-slack의 역할**
|
||||||
|
- 로빙이 응답 보낼 때만 사용
|
||||||
|
- 아이템처럼 필요시 호출
|
||||||
|
- 이벤트 수신 X, 전송 도구 O
|
||||||
|
|
||||||
|
### 6.2 장점
|
||||||
|
- ✅ 로빙 설계 철학과 일치
|
||||||
|
- ✅ 권한 관리 명확
|
||||||
|
- ✅ 다른 메신저로 교체 용이
|
||||||
|
- ✅ skill-slack 재사용
|
||||||
|
- ✅ 각 로빙이 독립적으로 Slack 이벤트 수신
|
||||||
|
|
||||||
|
## 7. 구현 제안
|
||||||
|
|
||||||
|
### 7.1 skill-slack을 아이템 서비스로 유지
|
||||||
|
- 메시지 전송, 수정, 스레드 관리
|
||||||
|
- 모든 로빙이 공유하는 Slack API 래퍼
|
||||||
|
|
||||||
|
### 7.2 각 로빙의 역할
|
||||||
|
- Slack 이벤트 직접 수신 (`/api/slack/events`)
|
||||||
|
- 메시지 처리 후 skill-slack으로 응답 전송
|
||||||
|
- Auth 서버에서 토큰 관리
|
||||||
|
|
||||||
|
### 7.3 사용자 매핑
|
||||||
|
- Auth 서버가 Slack OAuth 처리
|
||||||
|
- `slack_user_mapping` 테이블로 관리
|
||||||
|
- 로빙별 사용자 컨텍스트 분리
|
||||||
|
|
||||||
|
## 8. 마이그레이션 계획
|
||||||
|
|
||||||
|
### Phase 1: 현재 직접 통합 유지
|
||||||
|
- rb10508_micro 내부 Slack SDK 사용
|
||||||
|
- 기존 코드 안정화
|
||||||
|
|
||||||
|
### Phase 2: skill-slack 호출로 점진적 전환
|
||||||
|
- 응답 전송만 skill-slack 사용
|
||||||
|
- 이벤트 수신은 직접 처리
|
||||||
|
|
||||||
|
### Phase 3: Slack을 완전한 아이템으로 분리
|
||||||
|
- Auth 서버 통합 완료
|
||||||
|
- 사용자 매핑 테이블 활용
|
||||||
|
- 다중 메신저 지원 준비
|
||||||
|
|
||||||
|
## 9. 51123 서버/로컬 개발자와 논의 필요 사항
|
||||||
|
|
||||||
|
### 9.1 Slack 라우팅 아키텍처 결정
|
||||||
|
- **옵션 A**: skill-slack에서 다중 로빙 지원
|
||||||
|
- 환경변수로 rb8001, rb10508 둘 다 설정
|
||||||
|
- 사용자별로 어느 로빙 사용할지 결정 로직
|
||||||
|
- **옵션 B**: robing-gateway에서 중앙 라우팅
|
||||||
|
- Gateway가 사용자→로빙 매핑 관리
|
||||||
|
- skill-slack은 Gateway로만 전송
|
||||||
|
|
||||||
|
### 9.2 DB 스키마 추가
|
||||||
|
- slack_user_mapping 테이블 생성
|
||||||
|
- users 테이블과 연결
|
||||||
|
- 초기 데이터 마이그레이션 방법
|
||||||
|
|
||||||
|
### 9.3 인증 플로우 통합
|
||||||
|
- Slack OAuth 로그인 시 자동 매핑
|
||||||
|
- 기존 OAuth 사용자와 Slack 사용자 연결
|
||||||
|
- workspace별 봇 토큰 관리
|
||||||
|
|
||||||
|
### 9.4 메시지 필드 표준화
|
||||||
|
- "message" vs "text" 필드 통일
|
||||||
|
- Gateway에서 변환 vs 각 서비스에서 호환
|
||||||
|
|
||||||
|
### 9.5 ChromaDB 사용자 분리 전략
|
||||||
|
- 컬렉션 명명 규칙: `{robing_id}_{system_user_id}_{type}`
|
||||||
|
- 기존 데이터 마이그레이션 계획
|
||||||
|
- 백업 및 복구 정책
|
||||||
|
|
||||||
|
### 9.6 배포 우선순위
|
||||||
|
1. DB 테이블 생성 (51123)
|
||||||
|
2. Gateway 라우팅 로직 (로컬→배포)
|
||||||
|
3. skill-slack 수정 (로컬→배포)
|
||||||
|
4. rb10508_micro 사용자 매핑 적용
|
||||||
|
|
||||||
|
## 10. 결론
|
||||||
|
|
||||||
|
현재 rb10508_micro는 Slack 메시지를 정상적으로 처리하고 있지만, 사용자 식별과 매핑 시스템이 부재하여 개인화된 서비스 제공에 한계가 있습니다.
|
||||||
|
|
||||||
|
로빙 설계 철학에 따라 Slack을 "아이템"으로 취급하고, Auth 서버를 통한 중앙화된 권한 관리를 구현하는 것이 장기적으로 확장 가능한 아키텍처가 될 것입니다.
|
||||||
|
|
||||||
|
skill-slack 서비스는 메시지 전송 도구로서의 역할을 유지하고, 각 로빙이 독립적으로 이벤트를 수신하는 구조가 가장 이상적입니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*이 문서는 2025년 8월 12일 51124 서버에서 실측한 데이터를 기반으로 작성되었습니다.*
|
||||||
Loading…
x
Reference in New Issue
Block a user