Add: 로빙 컨테이너 경량화 전략 문서

- 300_architecture에 경량화 전략 문서 추가
- 현재 문제점: 31개 파일, 82개 함수의 monolithic 구조
- 목표: Stateless Router + Microservices (512MB 메모리)
- 실행 로드맵: 3단계 (분석/설계 → 공용서비스 → 코어경량화)
- 스킬 서버 분리 (Email, News, Slack 등)
- 로그 관리, 환경변수, 함수형 프로그래밍, 보안 전략 포함
- README.md 업데이트
This commit is contained in:
Claude-51124 2025-07-31 22:43:23 +09:00
parent 285c7c0a5f
commit ee76763ed0
2 changed files with 329 additions and 0 deletions

View File

@ -0,0 +1,328 @@
# 360. 로빙 컨테이너 경량화 전략
## 개요
현재 rb10508은 31개 파일, 82개 함수가 거미줄처럼 얽혀있는 monolithic 구조로, 메모리 사용량이 2GB를 넘어가고 있습니다. 이를 512MB 이하의 경량 컨테이너로 전환하여 100개 이상의 로빙을 동시에 운영할 수 있는 구조로 개선하고자 합니다.
> "컨테이너는 몸, 기억은 영혼 - 100개 로빙이 하나의 스킬 서비스를 공유한다"
## 현재 상황 분석
### 문제점
1. **모든 기능이 한 컨테이너에 집중**
- LLM 호출, ChromaDB, PostgreSQL 접근
- 메모리 관리, 스킬 처리, Slack 통신
- 파일 간 강한 결합도
2. **리소스 과다 사용**
- 메모리: 2GB 이상
- CPU: 지속적인 높은 사용률
- 확장 시 비용 급증
3. **상태 의존성 (Stateful)**
- ChromaDB가 컨테이너 내부에 위치
- 재시작 시 상태 복구 필요
- 스케일링 어려움
## 목표 아키텍처
### Stateless Router + Microservices
```
현재 구조: 목표 구조:
┌─────────────────┐ ┌──────────────────┐
│ rb10508 │ │ rb10508-lite │
│ (2GB+) │ ──→ │ (512MB) │
│ - 모든 기능 포함 │ │ - 라우팅만 담당 │
└─────────────────┘ └────────┬─────────┘
┌──────────┴──────────┐
│ │
┌──────▼──────┐ ┌──────▼──────┐
│State Service│ │ LLM Service │
│ (공용 DB) │ │(Gemini/GPT) │
└─────────────┘ └─────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│Skill-Email │ │ Skill-News │ │ Skill-Slack │
│ (HTTP API) │ │ (HTTP API) │ │ (HTTP API) │
└─────────────┘ └─────────────┘ └─────────────┘
```
### 핵심 설계 원칙
1. **경량화**: 로빙 컨테이너는 최소한의 리소스로 운영
2. **무상태 (Stateless)**: 언제든 재시작 가능, 상태는 외부 관리
3. **확장성**: 스킬 서버는 독립적으로 스케일링
4. **비용 효율성**: LLM API는 공용 서버에서만 호출
5. **독립성**: 각 컴포넌트별 독립 배포/업데이트
## 실행 로드맵
### Phase 1: 분석 및 설계
#### 주요 작업
1. **의존성 맵 작성**
- file-graph-visualizer 결과 분석
- 실행 경로 기준 우선순위 설정
- 가장 빈번한 경로부터 분리 (예: Slack → 의도 분석 → LLM)
2. **API 인터페이스 정의**
- RESTful API + WebSocket (실시간 업데이트)
- 내부 서비스용 gRPC 검토
- 인증/인가 체계 설계
#### 용어 설명
- **의존성 맵**: 코드 파일들 간의 import/호출 관계를 시각화한 다이어그램
- **gRPC**: Google이 개발한 고성능 RPC 프레임워크, HTTP/2 기반으로 빠른 통신 지원
- **WebSocket**: 실시간 양방향 통신을 위한 프로토콜
### Phase 2: 공용 서비스 구축
#### State Service (상태 관리 서비스)
```python
# 주요 기능
- 사용자 상태 관리 (레벨, 스탯, 경험치)
- 메모리 저장/검색 (ChromaDB 통합)
- 회사별 설정 관리
- 실시간 상태 동기화
```
**구현 포인트**:
- PostgreSQL + ChromaDB 외부화
- 세션 데이터와 장기 기억 논리적 분리
- pgvector + materialized view로 검색 최적화
- 버전 필드로 점진적 마이그레이션 지원
#### LLM Service (언어모델 관리 서비스)
```python
# 주요 기능
- Gemini/OpenAI 통합 관리
- 지능형 캐싱 (프롬프트 해시 기반)
- Rate limiting 및 API 키 풀 관리
- 비용 최적화 (스탯 기반 모델 선택)
```
**구현 포인트**:
- 프롬프트 길이 ≥ n일 때만 캐싱 적용
- API 키를 3개 그룹으로 분류 (고속/보통/저비용)
- 연산 스탯에 따라 적절한 그룹 선택
#### 용어 설명
- **pgvector**: PostgreSQL의 벡터 검색 확장 기능
- **materialized view**: 쿼리 결과를 물리적으로 저장하는 뷰, 성능 향상
- **Rate limiting**: API 호출 횟수를 제한하여 과부하 방지
- **API 키 풀**: 여러 API 키를 순환 사용하여 한도 분산
### Phase 3: 로빙 코어 경량화
#### 남길 기능 (최소한의 핵심)
1. **Slack 이벤트 수신 및 ACK**
2. **간단한 키워드 기반 라우팅**
3. **외부 서비스 호출 클라이언트**
4. **헬스체크 및 모니터링**
#### 로빙 브레인의 새로운 역할
```python
class RobingBrain:
"""경량화된 로빙 브레인 - 라우터 역할만 수행"""
def __init__(self):
self.skill_endpoints = {
"email": "http://skill-email:8501",
"news": "http://skill-news:8505",
"slack": "http://skill-slack:8503",
"pdf": "http://skill-pdf:8502"
}
async def route_to_skill(self, message: str, user_id: str):
# 1. 간단한 키워드 매칭 (LLM 없이)
if "이메일" in message or "메일" in message:
skill_url = self.skill_endpoints["email"]
elif "뉴스" in message or "news" in message:
skill_url = self.skill_endpoints["news"]
elif "요약" in message or "스레드" in message:
skill_url = self.skill_endpoints["slack"]
# 2. 외부 스킬 서비스 호출
response = await self.http_client.post(
skill_url,
json={"message": message, "user_id": user_id}
)
# 3. 결과만 반환 (처리는 스킬 서버에서)
return response.json()
```
**현재**: 로빙이 직접 스킬 로직 실행
**개선**: 로빙은 라우팅만, 실제 처리는 독립된 스킬 서버에서
#### 제거할 기능 (외부 서비스로 이동)
1. **gemini_service.py** → LLM Service
2. **chroma_service.py** → State Service
3. **복잡한 의도 분석 로직** → LLM Service
4. **메모리 관리 로직** → State Service
#### 최적화 방법
- FastAPI → Starlette 다운사이징
- Uvicorn workers = 1로 제한
- 불필요한 의존성 제거
- Policy Object로 라우팅 결과 직렬화
#### 용어 설명
- **ACK (Acknowledgment)**: 메시지 수신 확인 응답
- **Starlette**: FastAPI의 기반이 되는 경량 웹 프레임워크
- **Uvicorn**: Python 비동기 웹 서버
- **Policy Object**: 의사결정 규칙을 객체로 표현한 패턴
## 즉시 실행 가능한 개선사항
### 1. 하드코딩 제거
```python
# 현재 (gemini_service.py:190-192)
좋은 답변: "김종태님, 아드님은 초등학교 2학년이시고..."
# 개선
# 모델 컨피그 테이블에서 동적으로 로드
```
### 2. 메모리 제한 설정
```yaml
# docker-compose.yml에 추가
deploy:
resources:
limits:
memory: 512m
cpus: '0.5'
reservations:
memory: 256m
```
### 3. 문서 이동 및 정리
- `/DOCS/_archive/docs/architecture/로빙_아키텍쳐_설계_경량.md`
- → `/DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md`
- ADR(Architecture Decision Record)로 등록
## 위험 요소 및 대응 방안
### 1. 네트워크 지연 증가
- **문제**: 서비스 분리로 1-2 RTT 추가
- **대응**:
- 내부 로드밸런서(Envoy) 사용
- Keep-alive 연결 유지
- 중요 경로 캐싱 강화
### 2. 운영 복잡도 증가
- **문제**: 서비스 수 증가로 관리 어려움
- **대응**:
- 공통 미들웨어 프레임워크
- 중앙집중식 로깅/모니터링
- 자동화된 헬스체크
### 3. 배포 파편화
- **문제**: 여러 서비스의 일관된 배포 어려움
- **대응**:
- GitOps (Argo CD) 도입
- Blue-Green 배포
- 단계별 트래픽 미러링
#### 용어 설명
- **RTT (Round Trip Time)**: 요청-응답 왕복 시간
- **Envoy**: 고성능 프록시 및 로드밸런서
- **GitOps**: Git을 통한 인프라 관리 방법론
- **Blue-Green 배포**: 두 환경을 번갈아 사용하는 무중단 배포
## 기대 효과
### 리소스 절감
- 메모리: 2GB+ → 512MB (75% 감소)
- CPU: 1 core → 0.5 core (50% 감소)
- 비용: 서버당 약 70% 절감
### 확장성 향상
- 현재: 서버당 5-10개 로빙
- 목표: 서버당 100+ 로빙
- 수평 확장 용이
### 운영 효율성
- 컴포넌트별 독립 배포
- 장애 격리 및 빠른 복구
- 중앙집중식 모니터링
## 추가 고려사항
### 로그 관리 전략
```yaml
# 현재: SSD에 로그 저장 (문제)
volumes:
- ./logs:/code/logs
# 개선: HDD로 심링크 설정
# 호스트에서: ln -s /mnt/hdd/logs/rb10508 ./logs
volumes:
- ./logs:/code/logs:rw
```
**로그 경량화**:
- 로그 레벨 동적 조정 (DEBUG → INFO)
- 구조화된 로그 (JSON 형식)
- 외부 로그 수집기로 전송 (Fluentd/Logstash)
### 환경변수 관리
```python
# State Service에서 중앙 관리
class ConfigService:
async def get_robing_config(self, robing_id: str):
return {
"log_level": "INFO",
"memory_limit": "512m",
"skill_endpoints": {...},
"feature_flags": {...}
}
```
### 함수형 프로그래밍 접근
```python
# 순수 함수로 스킬 처리
def route_message(message: str, skill_map: dict) -> str:
"""부작용 없는 라우팅 함수"""
for keyword, skill in skill_map.items():
if keyword in message:
return skill
return "default"
# 불변성 유지
RouteResult = namedtuple('RouteResult', ['skill', 'confidence'])
```
### 메트릭 수집
```python
# Prometheus 메트릭
robing_request_count = Counter('robing_requests_total', 'Total requests')
robing_memory_usage = Gauge('robing_memory_bytes', 'Memory usage')
robing_response_time = Histogram('robing_response_seconds', 'Response time')
```
### 보안 강화
- **네트워크 격리**: 스킬 서버는 내부망에서만 접근
- **인증 토큰 순환**: JWT 토큰 주기적 갱신
- **Rate Limiting**: 로빙별 요청 제한
- **감사 로그**: 모든 API 호출 기록
## 다음 단계
1. **아키텍처 결정**
- State Service와 LLM Service 간 통신 방식
- 이벤트 버스(Kafka/NATS) vs HTTP + 캐시
2. **파일럿 프로젝트**
- rb10508_lite 프로토타입 개발
- 성능 벤치마크 및 검증
3. **점진적 마이그레이션**
- 기능별 단계적 분리
- 트래픽 미러링으로 안정성 확보
---
*"로빙을 가볍게, 그러나 더 강하게 - 진정한 디지털 동료로의 진화"*

View File

@ -29,6 +29,7 @@
- [330. 백엔드: PostgreSQL + ChromaDB Vector Memory](./300_architecture/330_백엔드_PostgreSQL_ChromaDB_Vector_Memory.md)
- [340. GUI 공유 아키텍처: 레벨 기반 권한](./300_architecture/340_GUI_공유_아키텍처_레벨기반_권한.md)
- [350. DID 기반 정체성과 다중 에이전트](./300_architecture/350_DID_기반_정체성과_다중에이전트.md)
- [360. 로빙 컨테이너 경량화 전략](./300_architecture/360_로빙_컨테이너_경량화_전략.md)
#### Part 4: 성장과 진화 (400_growth)
- [410. 레벨업 알고리즘과 사용자 피드백](./400_growth/410_레벨업_알고리즘과_사용자_피드백.md)