# 250806 함수형 전환과 LLM 기반 메모리 선택 구현 ## 오후 7시 00분 ### 문제 상황 **대화 저장 안되는 문제 발견** - Slack 메시지는 수신되지만 ChromaDB에 저장 안됨 - `[대화]` 로그 전무 - 함수형 전환 후 Fire & Forget 패턴의 문제 ### 원인 분석 1. **Fire & Forget의 위험성** ```python asyncio.create_task(store_memory_fn(...)) # 에러 발생해도 모름 ``` - 에러가 발생해도 전파되지 않음 - 로그도 없어서 디버깅 불가 2. **store_memory 함수 문제** - try-except 없음 - 로그 없음 - return 값 없음 ## 오후 8시 00분 ### 함수형 해결책 구현 **완전 함수형 접근** ```python # 데이터 준비 (순수 함수) def prepare_memory(content: str, user_id: str, role: str) -> Dict # 일괄 저장 (I/O 함수) async def save_memories(memories: List[Dict]) -> bool ``` **결과** - 코드 42줄 → 27줄 (35% 감소) - 에러 처리 추가 - 배치 처리로 효율성 향상 ## 오후 10시 00분 ### 문맥 파악 문제 **증상** ``` 사용자: "어떤 내용이었어?" 로빙: "김종태님, 안녕하세요..." (엉뚱한 답변) ``` **원인** - 메모리 검색 10000개 반환 - 벡터 거리만 고려, 시간 무시 - "어떤 내용"이 너무 일반적 ## 오후 10시 30분 ### LLM 기반 동적 메모리 선택 **Mistral 통합 (하드코딩 제거)** 1. 질문 의도 파악 (참조/새주제) 2. 동적 임계값 계산 (백분위수 기반) 3. 초기 선택 (거리 기반) 4. LLM 검증 (충분성 판단) **황금비 사용** ```python golden_ratio = (1 + 5 ** 0.5) / 2 # 수학 상수 expanded = current + (max - current) / golden_ratio ``` ## 오후 11시 00분 ### 함수형 원칙 위반 발견 **문제** - "순수 함수"라고 주석 달고 API 호출 - 로그를 순수 함수에 포함 - I/O와 로직 혼재 **해결** - app/llm/mistral.py로 완전 분리 - 순수 함수: 프롬프트 생성, 파싱, 계산 - I/O 함수: API 호출만 ## 오후 11시 30분 ### 최종 구조 ``` app/llm/mistral.py (순수 함수) ├── create_intent_analysis_prompt() ├── parse_intent_response() ├── calculate_percentile_threshold() └── filter_memories_by_threshold() app/core/memory.py (I/O 레이어) ├── call_mistral_api() # I/O └── adaptive_memory_selection() # 조정자 ``` ## 오후 11시 59분 ### 배포 및 검증 **서버 테스트 결과** - ✅ 대화 저장 정상 - ✅ 메모리 리콜 정상 - ✅ Mistral API 연동 정상 - ✅ 함수형 100% 달성 - ✅ 하드코딩 0% ## 교훈 1. **Fire & Forget은 위험하다** - 명시적 await 사용 - 에러 처리 필수 2. **함수형 != 순수 함수만** - I/O는 불가피 - 중요한 건 분리 3. **하드코딩 제거 방법** - 수학적 상수 활용 (황금비) - 데이터 분포 활용 (백분위수) - 동적 계산 4. **LLM으로 휴리스틱 대체** - 임의의 숫자 대신 LLM 판단 - "충분한가?" 물어보기 5. **모듈 분리의 중요성** - 단일 책임 원칙 - 테스트 용이성 - 재사용 가능 --- 작성자: happybell80 & Claude 프로젝트: rb10508_micro 주제: 함수형 전환과 LLM 메모리 선택