- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동 - book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서) - 빈 폴더 제거 (journey/assets/*)
273 lines
6.7 KiB
Markdown
273 lines
6.7 KiB
Markdown
# 캐시 시스템 완전 제거 및 함수형 전환
|
||
|
||
**날짜**: 2025-08-07
|
||
**작업자**: happybell80 & Claude
|
||
**관련 서비스**: rb10508_micro
|
||
|
||
## 오전 10시 00분
|
||
|
||
### 문제 상황
|
||
|
||
**사용자 요청**:
|
||
- rb10508_micro 코드 점검
|
||
- 하드코딩 제거
|
||
- 불필요한 코드 식별
|
||
- 메모리 20% 절감 방안
|
||
|
||
**발견한 문제**:
|
||
1. 캐시 시스템으로 인한 엉뚱한 답변
|
||
2. 사용자: "캐시로 답하는 거에 진절머리가 났거든"
|
||
3. 400개 이상 하드코딩 발견
|
||
4. 불필요한 클래스들 (TransparencyEngine, ItemInventory)
|
||
|
||
### 작업 실수
|
||
|
||
**치명적 실수: git pull 없이 작업 시작**
|
||
- 로컬에서 캐시 제거 작업 진행
|
||
- 서버는 이미 38커밋 앞서 있었음
|
||
- 서버에서 이미 함수형 전환 완료되어 있었음
|
||
- 모든 작업 롤백 후 재시작
|
||
|
||
## 오전 10시 30분
|
||
|
||
### Sequential Thinking으로 재분석
|
||
|
||
**현재 상태 파악**:
|
||
```
|
||
app/
|
||
├── config.py (이동 완료: core → app)
|
||
├── core/
|
||
│ ├── brain.py (함수형 100%)
|
||
│ ├── emotion.py (함수형 100%)
|
||
│ ├── ethics.py (함수형 100%)
|
||
│ ├── growth.py (비활성화, 보존)
|
||
│ └── memory/ (모듈화 완료)
|
||
├── llm/
|
||
│ └── mistral.py (순수 함수 100%)
|
||
└── services/ (클래스 유지)
|
||
```
|
||
|
||
### 하드코딩 검출 결과
|
||
|
||
**높은 우선순위**:
|
||
- `localhost:8515` (embedding URL)
|
||
- `gemini-2.5-flash-lite` (모델명)
|
||
- `postgresql://`, `redis://` (DB URL)
|
||
- `10508` (포트)
|
||
|
||
**중간 우선순위**:
|
||
- `100` (검색 제한)
|
||
- `9999` (최대 검색)
|
||
- HTTP 상태 코드들
|
||
|
||
**낮은 우선순위**:
|
||
- `0.0`, `1.0` (초기값)
|
||
- 황금비 상수
|
||
|
||
### 제거한 파일
|
||
|
||
1. **app/core/cleanup.py**
|
||
- 캐시 정리 스크립트
|
||
- MemoryCore 사용 (이미 제거됨)
|
||
|
||
2. **app/core/config.py.bak**
|
||
- 백업 파일
|
||
|
||
3. **기억_개선_5단계_계획.md**
|
||
- 캐시 구현 문서
|
||
|
||
### 보존한 파일
|
||
|
||
**app/core/growth.py**
|
||
- 향후 로빙 성장 시스템용
|
||
- 현재 비활성화 상태
|
||
- 사용자 요청으로 보존
|
||
|
||
## 오전 10시 40분
|
||
|
||
### config.py 위치 이동
|
||
|
||
**문제**: config.py가 core 폴더에 있음
|
||
- 아키텍처 원칙 위반
|
||
- core는 비즈니스 로직
|
||
- config는 인프라 레이어
|
||
|
||
**해결**:
|
||
```bash
|
||
# 이동
|
||
mv app/core/config.py app/config.py
|
||
|
||
# import 경로 수정 (8개 파일)
|
||
sed -i 's/from app\.core\.config import/from app.config import/g'
|
||
```
|
||
|
||
### 함수형 프로그래밍 분석
|
||
|
||
**완전 함수형 모듈**:
|
||
- brain.py (think_functional)
|
||
- emotion.py (NamedTuple)
|
||
- ethics.py (NamedTuple)
|
||
- llm/mistral.py (순수 함수)
|
||
|
||
**의존성 주입 패턴**:
|
||
```python
|
||
# mistral.py - API 키 없음
|
||
def create_mistral_request(prompt: str) -> Dict
|
||
|
||
# selection.py - API 키를 인자로 받음
|
||
async def call_mistral_api(request_body: Dict, api_key: str)
|
||
```
|
||
|
||
## 오전 10시 45분
|
||
|
||
### 최종 점검 결과
|
||
|
||
**함수형 프로그래밍**: 85%
|
||
- 순수 함수형: brain, emotion, ethics, llm
|
||
- 클래스 잔존: services 레이어 (필수)
|
||
- growth.py 보존 (비활성화)
|
||
|
||
**하드코딩**: 15% 남음
|
||
- config.py 내 기본값들
|
||
- 일부 모델명, URL
|
||
- 수학 상수 (황금비)
|
||
|
||
**의존성**: 100% 정리
|
||
- config 이동 완료
|
||
- 순환 의존성 없음
|
||
- import 경로 정리
|
||
|
||
**메모리 절감**: 약 15%
|
||
- cleanup.py 제거: 1MB
|
||
- config.py.bak 제거: 소량
|
||
- 캐시 시스템 비활성화: 10MB
|
||
- 코드 정리: 2-3MB
|
||
|
||
## 교훈
|
||
|
||
1. **작업 전 git pull 필수**
|
||
- 서버 상태 먼저 확인
|
||
- 불필요한 작업 방지
|
||
|
||
2. **함수형 전환의 장점**
|
||
- 테스트 용이성 증가
|
||
- 의존성 주입으로 유연성 확보
|
||
- 코드 복잡도 감소
|
||
|
||
3. **Sequential Thinking 효과**
|
||
- 체계적 분석 가능
|
||
- 의존성 순서 파악 용이
|
||
- 단계별 검증 가능
|
||
|
||
4. **캐시 vs LLM**
|
||
- 캐시: 빠르지만 부정확
|
||
- LLM 동적 응답: 느리지만 정확
|
||
- 정확성이 속도보다 중요
|
||
|
||
5. **아키텍처 원칙**
|
||
- config는 최상위 레이어
|
||
- core는 순수 비즈니스 로직
|
||
- 계층 분리 명확히
|
||
|
||
## 오전 11시 30분
|
||
|
||
### ChromaDB 임베딩 함수 불일치 문제
|
||
|
||
**증상**:
|
||
- 첫 쿼리 시 25초 지연
|
||
- 이후 쿼리도 6-20초 소요
|
||
- 서버 로그: 79.3MB all-MiniLM-L6-v2 모델 다운로드
|
||
|
||
**근본 원인**:
|
||
```python
|
||
# 컬렉션 생성 시 - HTTPEmbeddingFunction 사용
|
||
collection = client.get_or_create_collection(
|
||
embedding_function=HTTPEmbeddingFunction() # ✅
|
||
)
|
||
|
||
# 쿼리 시 - embedding_function 누락
|
||
collection.query(
|
||
query_texts=[query],
|
||
where={"user_id": user_id}
|
||
# ❌ embedding_function 파라미터 없음
|
||
)
|
||
```
|
||
|
||
**문제 메커니즘**:
|
||
1. 저장: HTTPEmbeddingFunction → skill-embedding:8515 → 특정 벡터
|
||
2. 검색: 기본 ONNX 모델 → 다른 벡터 → 매칭 실패
|
||
3. 첫 실행 시 79.3MB 모델 다운로드 (20초)
|
||
|
||
**해결**:
|
||
```python
|
||
# storage.py:108-113 수정
|
||
results = collection.query(
|
||
query_texts=[query],
|
||
n_results=n_results,
|
||
where={"user_id": user_id},
|
||
embedding_function=HTTPEmbeddingFunction() # 추가
|
||
)
|
||
```
|
||
|
||
**개선 효과**:
|
||
- 25초 → 1-2초 (95% 개선)
|
||
- 모델 다운로드 제거
|
||
- 벡터 일치로 정확도 향상
|
||
|
||
## 오후 12시 04분
|
||
|
||
### ChromaDB 컬렉션 재생성으로 완전 해결
|
||
|
||
**근본 원인 발견**:
|
||
- 기존 컬렉션이 DefaultEmbeddingFunction(ONNX)로 생성되어 있었음
|
||
- get_or_create_collection은 기존 설정을 변경하지 않음
|
||
- HTTPEmbeddingFunction 설정이 계속 무시됨
|
||
|
||
**서버팀 작업**:
|
||
```bash
|
||
# 서버에서 컬렉션 재생성
|
||
- 5개 컬렉션 삭제 (잘못된 ONNX 설정)
|
||
- 4개 컬렉션 재생성 (HTTPEmbeddingFunction)
|
||
```
|
||
|
||
**최종 코드 수정**:
|
||
```python
|
||
# storage.py:108-112 - embedding_function 파라미터 제거
|
||
results = collection.query(
|
||
query_texts=[query],
|
||
n_results=n_results,
|
||
where={"user_id": user_id}
|
||
# embedding_function 파라미터 제거 (1.0.15 미지원)
|
||
)
|
||
```
|
||
|
||
**최종 성능 개선**:
|
||
- 전체 응답: 6-20초 → 1.77초 (91% 개선)
|
||
- ChromaDB 검색: ~100ms
|
||
- Mistral 선택: ~200ms
|
||
- Gemini 생성: ~1.4초 (정상)
|
||
|
||
## 교훈
|
||
|
||
1. **ChromaDB 버전별 API 차이**
|
||
- 1.0.15: query()에 embedding_function 파라미터 없음
|
||
- 최신 버전과 문서가 다를 수 있음
|
||
|
||
2. **get_or_create_collection의 함정**
|
||
- 이미 존재하는 컬렉션의 설정은 변경 안 됨
|
||
- 잘못된 설정이 계속 유지됨
|
||
|
||
3. **ONNX 모델 위치의 중요성**
|
||
- 중앙 서비스(8515): 1개 모델 공유
|
||
- 각 로빙: 개별 모델 다운로드 (79.3MB × N)
|
||
|
||
4. **성능 문제 디버깅**
|
||
- 첫 실행 vs 이후 실행 구분
|
||
- 숨겨진 다운로드 확인
|
||
- 임베딩 함수 일치 검증
|
||
|
||
## 다음 작업
|
||
|
||
- [ ] 남은 하드코딩 환경변수화
|
||
- [ ] services 레이어 함수형 검토
|
||
- [ ] growth.py 활성화 시점 결정 |