diff --git a/troubleshooting/250819_happybell80_skill-email_Gemini통합.md b/troubleshooting/250819_happybell80_skill-email_Gemini통합.md new file mode 100644 index 0000000..fa3f97b --- /dev/null +++ b/troubleshooting/250819_happybell80_skill-email_Gemini통합.md @@ -0,0 +1,141 @@ +# skill-email Gemini API 통합 및 rb10508_micro 연동 문제 해결 + +## 작성일: 2025-08-19 +## 작성자: happybell80 +## 관련 서비스: rb10508_micro, skill-email + +--- + +## 오후 6시 14분 + +### rb10508_micro channel_id 속성 누락 문제 + +#### 문제 상황 +- rb10508_micro에서 skill-email 호출 시 `'ThinkInput' object has no attribute 'channel_id'` 에러 발생 +- /api/message 엔드포인트에서 channel_id가 전달되지 않음 + +#### 해결 과정 +1. ThinkInput NamedTuple에 `channel_id: Optional[str] = None` 속성 추가 +2. extract_message 함수에서 channel_id 추출 로직 추가 +3. MessageRequest Pydantic 모델에 channel_id 필드 추가 +4. /api/message와 /api/think 엔드포인트에서 channel_id 전달 + +#### 결과 +- channel_id 에러 해결 +- skill-email 호출 시 필요한 모든 파라미터 전달 성공 + +--- + +## 오후 8시 30분 + +### skill-email LLM 서비스 연결 실패 문제 + +#### 문제 상황 +- skill-email이 `http://localhost:8003` LLM 서비스 호출 시 "All connection attempts failed" 에러 +- 8003 포트에 실제 서비스가 존재하지 않음 +- 이메일 정보 추출 실패 (to, subject, body 모두 null) + +#### 원인 분석 +- conversation_handler.py의 `_extract_email_info` 함수가 존재하지 않는 8003 서비스에 의존 +- 원래 중앙 LLM 프록시 서비스를 가정한 설계였으나 실제로 구현되지 않음 + +#### 해결 과정 + +##### 1차 시도: Gemini 폴백 추가 +```python +except Exception as e: + # 8003 실패시 Gemini 직접 호출 + genai.configure(api_key=os.getenv("GEMINI_API_KEY")) + response = genai.GenerativeModel('gemini-2.5-flash-lite').generate_content(prompt) +``` +- 문제: except 블록이 실행되지 않음 (httpx가 예외를 발생시키지 않음) + +##### 2차 시도: 디버깅 로그 추가 +- GEMINI_API_KEY 존재 여부 확인 로깅 +- 예외 타입 및 상세 정보 로깅 +- 발견: Gemini 폴백 코드가 아예 실행되지 않음 + +##### 최종 해결: 8003 스킵하고 Gemini 직접 호출 +```python +use_gemini_direct = True # 8003 서비스가 없으므로 True + +if use_gemini_direct: + # Gemini 직접 호출 + api_key = os.getenv("GEMINI_API_KEY") + genai.configure(api_key=api_key) + gemini_response = genai.GenerativeModel('gemini-2.5-flash-lite').generate_content(prompt) + # 8003 응답 형식으로 맞춤 + result = {"content": gemini_response.text} + response_status = 200 +else: + # 8003 서비스 호출 (나중에 복원 가능) + response = await self.http_client.post(...) +``` + +#### 추가 작업 +1. requirements.txt에 `google-generativeai>=0.3.0` 추가 +2. docker-compose.yml에 환경변수 추가: + - DATABASE_URL + - POSTGRES_CONNECTION_STRING + - GEMINI_API_KEY + +--- + +## 오후 11시 45분 + +### 코드 리팩토링 - 기존 코드 최대한 재사용 + +#### 개선 내용 +- 8003 서비스 코드 완전 보존 (주석 처리 없이 조건부 실행) +- JSON 추출 로직 100% 재사용 +- 응답을 8003 형식(`{"content": "..."}`)으로 통일 +- `use_gemini_direct` 플래그로 쉽게 전환 가능 + +#### 장점 +- 8003 서비스가 나중에 생기면 플래그만 False로 변경 +- 코드 중복 제거 +- 기존 로직 그대로 유지 + +--- + +## 최종 테스트 결과 + +### 성공한 부분 +1. Gemini API 정상 호출 +2. 이메일 정보 부분 추출 성공 (subject 인식) +3. 대화형 처리 작동 (누락된 필드 이어받기) + +### 개선 필요 사항 (추후 작업) +1. 이메일 주소 인식 정확도 개선 +2. "종태님" 같은 한국어 이름 → 이메일 매핑 +3. 대화형 응답 메시지 다양화 + +--- + +## 교훈 + +### 1. 외부 의존성 최소화 +- 존재하지 않는 서비스(8003)에 의존하는 설계는 위험 +- 폴백 메커니즘을 처음부터 고려해야 함 + +### 2. 기존 코드 재사용의 중요성 +- 처음엔 Gemini 폴백을 별도로 구현하려 했으나, 기존 JSON 추출 로직을 재사용하는 것이 훨씬 깔끔 +- 응답 형식을 통일하면 하나의 처리 로직으로 여러 소스 처리 가능 + +### 3. 디버깅 로그의 중요성 +- 문제 원인 파악을 위해 단계별 로깅 필수 +- 특히 API 키 존재 여부, 응답 내용 등 핵심 정보 로깅 + +### 4. 점진적 개선 전략 +- 완벽한 이메일 정보 추출보다 먼저 기본 동작 확보 +- 정확도 개선은 나중에 고도화 단계에서 진행 + +--- + +## 관련 커밋 +- rb10508_micro: `18f06c7` - channel_id 속성 누락 문제 해결 +- skill-email: `75efb4f` - 기존 코드 최대한 재사용하며 Gemini 통합 + +--- + +**문서 끝** \ No newline at end of file