DOCS/troubleshooting/250805_happybell80_AI응답개선Phase1.md
happybell80 3ea5929365 docs: AI 응답 개선 Phase 1 트러블슈팅 문서 추가
- async/await 처리 실수와 해결 과정
- 기억 개선 5단계 계획을 ideas로 이동
- Phase 1 성공적 구현 기록
2025-08-05 23:25:17 +09:00

4.1 KiB

AI 응답 단조로움 해결 - Phase 1 구현

날짜: 2025-08-05
작업자: happybell80 & Claude
관련 서비스: rb10508_micro

오후 1시 30분

문제 상황

서버팀 보고:

  • rb10508_micro의 AI 응답이 지나치게 단조로움
  • 3개의 고정 템플릿만 반복 사용
    • "흥미로운 이야기네요. 더 자세히 들려주시겠어요?"
    • "네, 이해했습니다. 어떻게 도와드릴까요?"
    • "그렇군요. 제가 어떤 도움을 드릴 수 있을까요?"

원인 분석:

# brain.py:298-302
responses = [
    "흥미로운 이야기네요. 더 자세히 들려주시겠어요?",
    "네, 이해했습니다. 어떻게 도와드릴까요?",
    "그렇군요. 제가 어떤 도움을 드릴 수 있을까요?"
]
return random.choice(responses)

5단계 개선 계획 수립

1단계: Gemini 전면 도입 (즉시 적용) 2-5단계: 캐시 시스템 구축 (점진적 구현)

오후 2시 00분

Phase 1 구현

목표: 모든 대화에 Gemini API 사용

구현 내용:

  1. config.py에 환경변수 추가

    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() 필요

올바른 해결:

# 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 불일치

    # 문제: 동기 함수를 asyncio.gather()에 전달
    novelty_task = self.memory.check_novelty(message, self.current_user_id)
    
  2. EmotionState() 빈 객체 전달

    # 문제: 실제 감정 대신 빈 객체
    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 기술의 발전 속도가 어마어마한 건 저도 매일 피부로 느끼고 있어요..."