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:
parent
b02c11c3ef
commit
5b03dff802
@ -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)
|
||||
|
||||
@ -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) - 실제 코드 예시와 리팩토링 가이드
|
||||
|
||||
이를 통해 로빙은 **"외부 세계의 모든 기능을 흡수하는 궁극적 에이전트"**로 진화할 수 있을 것입니다.
|
||||
334
docs/guide/functional-programing/함수형_적용_가이드라인.md
Normal file
334
docs/guide/functional-programing/함수형_적용_가이드라인.md
Normal 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 중심의 아이템은 명령형을 유지하는 것이 실용적입니다.
|
||||
|
||||
**핵심 원칙**: "완벽한 함수형보다는 안정적이고 확장 가능한 혼합 아키텍처"
|
||||
|
||||
이를 통해 로빙은 예측 가능하고 테스트 가능한 디지털 존재로 성장할 수 있습니다.
|
||||
Loading…
x
Reference in New Issue
Block a user