150 lines
4.1 KiB
Markdown
150 lines
4.1 KiB
Markdown
# AI 응답 단조로움 해결 - Phase 1 구현
|
|
|
|
**날짜**: 2025-08-05
|
|
**작업자**: happybell80 & Claude
|
|
**관련 서비스**: rb10508_micro
|
|
|
|
## 오후 1시 30분
|
|
|
|
### 문제 상황
|
|
|
|
서버팀 보고:
|
|
- rb10508_micro의 AI 응답이 지나치게 단조로움
|
|
- 3개의 고정 템플릿만 반복 사용
|
|
- "흥미로운 이야기네요. 더 자세히 들려주시겠어요?"
|
|
- "네, 이해했습니다. 어떻게 도와드릴까요?"
|
|
- "그렇군요. 제가 어떤 도움을 드릴 수 있을까요?"
|
|
|
|
**원인 분석**:
|
|
```python
|
|
# brain.py:298-302
|
|
responses = [
|
|
"흥미로운 이야기네요. 더 자세히 들려주시겠어요?",
|
|
"네, 이해했습니다. 어떻게 도와드릴까요?",
|
|
"그렇군요. 제가 어떤 도움을 드릴 수 있을까요?"
|
|
]
|
|
return random.choice(responses)
|
|
```
|
|
|
|
### 5단계 개선 계획 수립
|
|
|
|
1단계: Gemini 전면 도입 (즉시 적용)
|
|
2-5단계: 캐시 시스템 구축 (점진적 구현)
|
|
|
|
## 오후 2시 00분
|
|
|
|
### Phase 1 구현
|
|
|
|
**목표**: 모든 대화에 Gemini API 사용
|
|
|
|
**구현 내용**:
|
|
1. config.py에 환경변수 추가
|
|
```python
|
|
USE_GEMINI_CONVERSATION: bool = False
|
|
GEMINI_FALLBACK_MODEL: str = "gemini-2.5-flash-lite"
|
|
```
|
|
|
|
2. brain.py에 Gemini 전면 도입 및 병렬화
|
|
- 템플릿 응답 → Gemini 응답으로 전환
|
|
- novelty 체크와 병렬 처리
|
|
- 쿼터 초과 시 fallback 모델 사용
|
|
|
|
## 오후 2시 30분
|
|
|
|
### 서버팀 테스트 결과 - async 오류 발생
|
|
|
|
**에러 메시지**:
|
|
```
|
|
2025-08-05 13:41:08,707 - app.core.brain - ERROR - Gemini 호출 완전 실패:
|
|
An asyncio.Future, a coroutine or an awaitable is required
|
|
```
|
|
|
|
**문제**: Gemini API 호출에서 async/await 처리 오류
|
|
|
|
## 오후 10시 30분
|
|
|
|
### 첫 번째 실수 - 성급한 판단
|
|
|
|
**잘못된 분석**:
|
|
1. `generate_content_async()` 메서드가 존재하지 않는다고 판단
|
|
2. `_generate_gemini_response`를 async → 동기 함수로 변경
|
|
3. `await` 제거
|
|
|
|
**실제 문제**:
|
|
- `asyncio.gather()`에 동기 함수 결과값 전달
|
|
- awaitable이 아닌 일반 값이라 에러 발생
|
|
|
|
## 오후 11시 00분
|
|
|
|
### Sequential Thinking으로 재분석
|
|
|
|
GPT 검색 결과 확인:
|
|
- `google-generativeai` 0.3.x~0.5.x에는 `generate_content_async()` 없음
|
|
- 동기 메서드 `generate_content()`만 존재
|
|
- async로 사용하려면 `run_in_executor()` 필요
|
|
|
|
**올바른 해결**:
|
|
```python
|
|
# generate_content를 비동기로 실행
|
|
loop = asyncio.get_running_loop()
|
|
response = await loop.run_in_executor(
|
|
None,
|
|
self.gemini_model.generate_content,
|
|
prompt
|
|
)
|
|
```
|
|
|
|
## 오후 11시 20분
|
|
|
|
### 서버팀 추가 문제 발견
|
|
|
|
1. **check_novelty 함수 async 불일치**
|
|
```python
|
|
# 문제: 동기 함수를 asyncio.gather()에 전달
|
|
novelty_task = self.memory.check_novelty(message, self.current_user_id)
|
|
```
|
|
|
|
2. **EmotionState() 빈 객체 전달**
|
|
```python
|
|
# 문제: 실제 감정 대신 빈 객체
|
|
gemini_task = self._generate_gemini_response(message, memories, EmotionState())
|
|
```
|
|
|
|
### 최종 수정
|
|
|
|
1. check_novelty를 run_in_executor로 감싸기
|
|
2. 실제 emotion_state를 Gemini에 전달
|
|
3. _generate_conversational_response 시그니처 수정
|
|
|
|
## 교훈
|
|
|
|
1. **async/await 처리 주의**
|
|
- 라이브러리 문서 확인 필수
|
|
- 동기 함수는 `run_in_executor()`로 비동기 변환
|
|
- `asyncio.gather()`에는 awaitable만 전달
|
|
|
|
2. **성급한 판단 금지**
|
|
- 에러 메시지만 보고 판단하지 말기
|
|
- Sequential Thinking으로 차근차근 분석
|
|
- 실제 라이브러리 동작 확인
|
|
|
|
3. **파라미터 전달 확인**
|
|
- 빈 객체 대신 실제 데이터 전달
|
|
- 함수 시그니처 일관성 유지
|
|
- 데이터 흐름 추적
|
|
|
|
4. **테스트의 중요성**
|
|
- 로컬 테스트 환경 구축 필요
|
|
- 서버팀 피드백 적극 활용
|
|
- 단계별 검증
|
|
|
|
## 최종 성과
|
|
|
|
✅ Phase 1 완전 성공
|
|
- 단조로운 템플릿 → 자연스러운 AI 대화
|
|
- 메모리: 113.1MiB → 122.2MiB (+8.1%)
|
|
- 안정적인 async 처리
|
|
- 실제 감정 정보 활용
|
|
|
|
**개선된 응답 예시**:
|
|
"정말 그렇게 느껴지시나요? AI 기술의 발전 속도가 어마어마한 건 저도 매일 피부로 느끼고 있어요..." |