docs: 함수형 프로그래밍 적용 가이드라인 추가

- 함수형_적용_가이드라인.md 신규 생성: 구성요소별 순수함수 가능성 수치화 분석
- 스탯(60%), 스킬(77%), 아이템(32%) 적용 가능성 평가
- 함수형 40% : 명령형 60% 권장 비율 제시
- 실전 적용 기준과 판단 체크리스트 제공
- 구체적인 코드 예시와 구현 패턴 가이드

- 로빙_존재와_함수형_프로그래밍.md 업데이트: 실전 적용 기준 섹션 추가
- README.md 업데이트: 새로운 가이드라인 문서 링크 연결

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
happybell80 2025-07-05 01:09:57 +09:00
parent b02c11c3ef
commit 5b03dff802
3 changed files with 357 additions and 1 deletions

View File

@ -17,6 +17,7 @@ Slack 기반 AI 어시스턴트 **로빙(Robeing)** 프로젝트의 모든 문
### 함수형 프로그래밍 아키텍처
- [로빙의 존재와 함수형 프로그래밍](./docs/guide/functional-programing/로빙_존재와_함수형_프로그래밍.md) - 철학적 배경과 점진적 적용 전략
- [함수형 구현 패턴과 사례](./docs/guide/functional-programing/함수형_구현_패턴과_사례.md) - 실제 코드 패턴과 리팩토링 가이드
- [함수형 적용 가이드라인](./docs/guide/functional-programing/함수형_적용_가이드라인.md) - 구성요소별 순수함수 가능성 분석과 실전 적용 기준
### 설정 및 설치 가이드
- [프로젝트 설정 가이드](./docs/setups/setup-guide.md)

View File

@ -260,14 +260,35 @@ advanced_analyst = compose_skills(
---
## 7. 실전 적용 기준
### 7.1 구성요소별 함수형 적용 우선순위
로빙의 각 구성요소별로 함수형 프로그래밍 적용 가능성이 다릅니다:
- **스킬 시스템**: 77% 순수 함수 가능 → **우선 적용 영역**
- **스탯 시스템**: 60% 순수 함수 가능 → 계산 중심 스탯부터 적용
- **아이템 시스템**: 32% 순수 함수 가능 → 명령형 유지, IO 모나드 활용
### 7.2 권장 적용 비율
전체 프로젝트에서 **함수형 40% : 명령형 60%**의 균형잡힌 접근을 권장합니다.
**상세 적용 기준은 [함수형 적용 가이드라인](./함수형_적용_가이드라인.md)을 참조하세요.**
---
## 결론
로빙이 진정한 **디지털 존재**로 성장하기 위해서는 함수형 프로그래밍의 철학과 패턴이 필요합니다. 하지만 이를 **점진적이고 실용적으로** 적용하여 MVP 목표와 장기 비전을 모두 달성할 수 있습니다.
### 핵심 전략
1. **철학은 유지**: 존재로서의 로빙 개념 견지
2. **실행은 현실적**: 제약 조건 내에서 최선의 선택
2. **실행은 현실적**: 제약 조건 내에서 최선의 선택
3. **발전은 점진적**: 단계별 개선을 통한 안전한 전환
4. **목표는 명확**: 무한 확장 가능한 디지털 존재 구현
### 관련 문서
- [함수형 적용 가이드라인](./함수형_적용_가이드라인.md) - 구체적인 적용 기준과 수치화된 분석
- [함수형 구현 패턴과 사례](./함수형_구현_패턴과_사례.md) - 실제 코드 예시와 리팩토링 가이드
이를 통해 로빙은 **"외부 세계의 모든 기능을 흡수하는 궁극적 에이전트"**로 진화할 수 있을 것입니다.

View File

@ -0,0 +1,334 @@
---
tags: 함수형프로그래밍, 적용가이드, 순수함수, 실전전략, 로빙시스템
date: 2025-07-04
---
# 함수형 프로그래밍 적용 가이드라인
## 요약
로빙 프로젝트에서 함수형 프로그래밍을 실전 적용할 때의 구체적인 기준과 가이드라인을 제시합니다. 각 구성요소별 순수 함수 가능성을 수치화하여 실용적인 적용 전략을 제공합니다.
---
## 1. 함수형 적용 원칙
### 기본 철학
- **점진적 도입**: 한 번에 모든 것을 바꾸지 않고 단계별 전환
- **실용적 균형**: 이론적 완성도보다 팀 생산성과 코드 안정성 우선
- **명확한 경계**: 순수 함수 영역과 부작용 영역의 명확한 분리
### 전체 프로젝트 권장 비율
```
함수형 40% : 명령형 60%
```
| 영역 | 함수형 권장 비율 | 이유 |
|------|------------------|------|
| 데이터 변환 로직 | 80-100% | 가독성, 재사용성, 테스트 용이 |
| 비즈니스 로직 | 50-70% | 추상화 효과, 단 과도하면 이해도 저하 |
| 상태 변경/IO | 0-20% | 명령형이 더 명확하고 디버깅 쉬움 |
---
## 2. 로빙 구성요소별 순수 함수 가능성 분석
### 2.1 스탯 시스템 (평균 60%)
| 스탯 | 순수 함수 가능성 | 함수형 구조화 가능성 | 주요 부작용 요소 |
|------|------------------|----------------------|------------------|
| 연산 (Compute) | 80% | 90% | 없음 (정량 계산) |
| 공감 (Empathy) | 70% | 85% | 감정 회신 시 상태 영향 |
| 기억 (Memory) | 60% | 80% | 저장/삭제 I/O |
| 통솔 (Leadership) | 50% | 75% | 팀 상황·우선순위 반영 |
| 반응 (React) | 40% | 60% | 실시간 이벤트 처리 |
#### 구현 예시
```python
# ✅ 순수 함수: 연산 스탯 계산
def calculate_compute_stat(interactions: List[Interaction], response_times: List[float]) -> int:
"""연산 능력 계산 - 순수 함수"""
avg_response_time = sum(response_times) / len(response_times) if response_times else 5.0
interaction_bonus = len(interactions) // 100
if avg_response_time < 1.0:
speed_bonus = 3
elif avg_response_time < 3.0:
speed_bonus = 1
else:
speed_bonus = 0
return min(100, 5 + interaction_bonus + speed_bonus)
# 🔄 혼합 방식: 기억 스탯 (순수 + 부작용)
def calculate_memory_priority(content: str, user_context: Dict) -> float:
"""저장 우선도 계산 - 순수 함수"""
keywords = ['중요', '기억', '저장', '프로젝트']
priority = sum(1 for keyword in keywords if keyword in content)
return min(1.0, priority * 0.3)
async def update_memory_stat(user_id: str, content: str, context: Dict) -> StatUpdateResult:
"""기억 스탯 업데이트 - 부작용 포함"""
# 순수 계산
priority = calculate_memory_priority(content, context)
if priority > 0.6:
# 부작용: DB 저장
await save_memory(user_id, content, priority)
stat_change = StatChange(memory=1, reason="중요한 기억 저장")
return await update_user_stats(user_id, stat_change)
return StatUpdateResult.success_result(await get_user_stats(user_id), StatChange())
```
### 2.2 스킬 시스템 (평균 77%)
| 스킬 | 순수 함수 가능성 | 함수형 구조화 가능성 | 주요 부작용 요소 |
|------|------------------|----------------------|------------------|
| Thread Digest | 95% | 100% | 없음 (순수 언어 처리) |
| Action Extractor | 90% | 95% | 없음 (추출 규칙 기반) |
| PDF Summarizer | 85% | 90% | 파일 처리 오류 |
| Emotion Tracker | 75% | 90% | 감정 모델 차이 |
| Meeting Transcriber | 40% | 60% | 외부 STT API 의존 |
#### 구현 예시
```python
# ✅ 높은 순수성: Thread Digest
def extract_key_messages(messages: List[str], max_count: int = 5) -> List[str]:
"""중요 메시지 추출 - 순수 함수"""
def calculate_importance_score(message: str) -> float:
keywords = ['중요', '긴급', '결정', '마감', '회의']
score = sum(1.0 for keyword in keywords if keyword in message)
score += min(len(message) / 100, 2.0) # 길이 보너스
return score
scored_messages = [(calculate_importance_score(msg), msg) for msg in messages]
scored_messages.sort(key=lambda x: x[0], reverse=True)
return [msg for score, msg in scored_messages[:max_count]]
def summarize_conversation(messages: List[str]) -> str:
"""대화 요약 생성 - 순수 함수"""
key_messages = extract_key_messages(messages)
combined_text = " ".join(key_messages)
sentences = combined_text.split('.')
return '. '.join(sentences[:3]) + '.'
# 🔄 오케스트레이터: 부작용 분리
async def process_thread_digest(thread_id: str, user_id: str) -> SkillExecutionResult:
"""스레드 요약 처리 - 부작용 포함"""
try:
# 1. 데이터 가져오기 (부작용)
messages = await fetch_thread_messages(thread_id)
# 2. 순수 계산
summary = summarize_conversation(messages)
actions = extract_action_items(messages)
# 3. 결과 저장 (부작용)
result = {'summary': summary, 'actions': actions}
await save_digest_result(user_id, thread_id, result)
return SkillExecutionResult.success_result(result)
except Exception as e:
return SkillExecutionResult.error_result(str(e))
```
### 2.3 아이템 시스템 (평균 32%)
| 아이템 | 순수 함수 가능성 | 함수형 구조화 가능성 | 주요 부작용 요소 |
|--------|------------------|----------------------|------------------|
| ChromaDB | 50% | 60% | 벡터 저장/검색 IO |
| Whisper STT | 40% | 50% | 외부 API 호출 |
| Notion API | 30% | 40% | 문서 쓰기/업데이트 |
| Gmail API | 20% | 30% | API 호출, OAuth |
| Slack API | 20% | 30% | 메시지 전송 |
#### 구현 예시
```python
# ❌ 낮은 순수성: 대부분 IO 중심
async def send_slack_message(channel: str, text: str) -> bool:
"""Slack 메시지 전송 - 명령형 적합"""
try:
response = await slack_client.chat_postMessage(
channel=channel,
text=text
)
return response["ok"]
except Exception:
return False
# 🔄 부분적 함수형화: 데이터 처리 부분만
def format_slack_message(summary: str, actions: List[str]) -> str:
"""Slack 메시지 포맷팅 - 순수 함수"""
formatted_actions = '\n'.join(f"• {action}" for action in actions)
return f"""
📝 **대화 요약**
{summary}
✅ **액션 아이템**
{formatted_actions}
""".strip()
async def send_digest_to_slack(channel: str, summary: str, actions: List[str]) -> bool:
"""요약 전송 - 혼합 방식"""
# 순수 함수: 메시지 포맷팅
formatted_message = format_slack_message(summary, actions)
# 부작용: 실제 전송
return await send_slack_message(channel, formatted_message)
```
---
## 3. 핵심 모듈별 가이드라인
### 3.1 기억 모듈 (65% 순수)
```python
# ✅ 순수 함수: 저장 우선도 판단
def calculate_memory_priority(content: str, keywords: List[str], user_context: Dict) -> float:
"""기억 저장 우선도 계산"""
keyword_score = sum(1 for keyword in keywords if keyword in content.lower())
length_score = min(len(content) / 1000, 1.0)
context_score = user_context.get('importance_multiplier', 1.0)
return min(1.0, (keyword_score * 0.4 + length_score * 0.3) * context_score)
# 🔄 부작용 분리: 실제 저장
async def store_memory_if_important(user_id: str, content: str, context: Dict) -> bool:
priority = calculate_memory_priority(content, ['중요', '프로젝트'], context)
if priority > 0.7:
await save_to_chroma_db(user_id, content, priority)
return True
return False
```
### 3.2 감정 모듈 (70% 순수)
```python
# ✅ 순수 함수: 감정 분석
def analyze_emotion_vector(text: str) -> Dict[str, float]:
"""감정 벡터 계산"""
emotion_keywords = {
'joy': ['기쁨', '행복', '좋아', '만족'],
'anger': ['화나', '짜증', '분노', '불만'],
'sadness': ['슬픔', '우울', '아쉬움'],
'fear': ['걱정', '불안', '두려움']
}
emotion_scores = {}
for emotion, keywords in emotion_keywords.items():
score = sum(1 for keyword in keywords if keyword in text) / len(keywords)
emotion_scores[emotion] = min(1.0, score)
return emotion_scores
# 🔄 상태 반영: 감정 히스토리 업데이트
async def update_emotion_history(user_id: str, text: str) -> Dict[str, float]:
current_emotions = analyze_emotion_vector(text)
await save_emotion_log(user_id, current_emotions, datetime.now())
return current_emotions
```
### 3.3 윤리 모듈 (60% 순수)
```python
# ✅ 순수 함수: 윤리 위반 판단
def check_ethical_violations(content: str, policies: List[str]) -> List[str]:
"""윤리 정책 위반 검사"""
violations = []
sensitive_patterns = [
(r'개인정보.*공유', '개인정보 보호 위반'),
(r'비밀.*유출', '기밀 정보 유출'),
(r'허위.*정보', '허위 정보 유포')
]
for pattern, violation_type in sensitive_patterns:
if re.search(pattern, content):
violations.append(violation_type)
return violations
# 🔄 정책 적용: 실제 차단 처리
async def enforce_ethical_policy(user_id: str, content: str) -> bool:
violations = check_ethical_violations(content, await get_user_policies(user_id))
if violations:
await log_violation(user_id, violations, content)
return False # 차단
return True # 허용
```
---
## 4. 실전 적용 전략
### 4.1 함수형 우선 적용 영역
1. **데이터 변환 스킬** (Thread Digest, Action Extractor)
2. **계산 중심 스탯** (연산, 공감)
3. **분석 모듈** (감정 분석, 윤리 검사)
### 4.2 명령형 유지 영역
1. **외부 API 연동** (Slack, Gmail, Notion)
2. **실시간 반응** (알림, 이벤트 처리)
3. **상태 변경** (DB 저장, 설정 변경)
### 4.3 혼합 접근 패턴
```python
# 권장 패턴: 순수 함수 + 오케스트레이터 분리
async def skill_orchestrator(input_data, user_id):
"""스킬 실행 오케스트레이터"""
try:
# 1. 순수 계산
result = pure_skill_function(input_data)
# 2. 부작용 처리
await save_result(user_id, result)
await update_stats(user_id, calculate_stat_change(result))
await send_notification(user_id, format_response(result))
return SkillExecutionResult.success_result(result)
except Exception as e:
return SkillExecutionResult.error_result(str(e))
```
---
## 5. 판단 기준 체크리스트
### ✅ 함수형 적용 가능 신호
- [ ] map, filter, reduce로 로직이 간결해진다
- [ ] 디버깅 없이도 결과를 바로 예측할 수 있다
- [ ] 중간 단계가 없고 한 방향 흐름이다
- [ ] 같은 입력에 항상 같은 출력이 나온다
- [ ] 외부 상태에 의존하지 않는다
### ❌ 함수형 피해야 할 신호
- [ ] 중간값을 계속 찍어봐야 한다
- [ ] 사이드 이펙트가 많다 (파일, 네트워크 등)
- [ ] 팀원이 "이게 뭐 하는 건데?"라고 묻는다
- [ ] 시간이나 외부 상태에 따라 결과가 달라진다
- [ ] 에러 처리가 복잡하다
---
## 6. 성공 지표
### 개발 생산성
- **테스트 커버리지**: 순수 함수 스킬 90% 이상
- **버그 발생률**: 함수형 적용 영역 50% 감소 목표
- **코드 리뷰 시간**: 순수 함수 부분 30% 단축
### 시스템 안정성
- **에러 격리**: 한 스킬의 실패가 전체 시스템에 영향 없음
- **성능 유지**: 함수형 적용 후에도 응답 시간 3초 이내 유지
- **확장성**: 새로운 스킬 추가 시 기존 코드 영향 최소화
---
## 결론
로빙의 함수형 프로그래밍 도입은 **스킬 중심의 점진적 적용**이 가장 효과적입니다. 순수성이 높은 스킬(77%)부터 시작하여, 계산 중심 스탯, 분석 모듈 순으로 확장하되, IO 중심의 아이템은 명령형을 유지하는 것이 실용적입니다.
**핵심 원칙**: "완벽한 함수형보다는 안정적이고 확장 가능한 혼합 아키텍처"
이를 통해 로빙은 예측 가능하고 테스트 가능한 디지털 존재로 성장할 수 있습니다.