3.2 KiB
3.2 KiB
IR Deck 평가 Gemini Fallback 빈 응답 에러 처리
날짜: 2025-12-02 작성자: Auto 관련 파일:
rb8001/app/services/ir_analyzer.pyrb8001/app/services/llm/gemini_handler.py
문제 상황
IR Deck 평가 중 프론트엔드에서 "(템플릿) 평가 처리 중 오류가 발생했습니다." 메시지가 반복적으로 표시됨.
원인 분석
로그 분석 결과:
-
Fallback 체인 작동:
gemini-2.5-flash-lite(429 Rate Limit) →gemini-2.5-flash로 전환 성공 -
새로운 에러 발생:
gemini-2.5-flash에서 빈 응답 에러- 에러 메시지:
"Gemini API 응답이 비어있거나 잘못된 형식입니다. candidates: 1개, parts: 0개" - 위치:
gemini_handler.py:161(response.text접근 시) - 스택 트레이스:
google.generativeai.types.generation_types.py:255에서parts[0]접근 시 IndexError
- 에러 메시지:
-
Fallback 미작동: 빈 응답 에러는 429가 아니므로 fallback 조건에 포함되지 않아 다음 모델로 전환하지 않음
해결 과정
1. 안전한 응답 텍스트 추출 메서드 추가
파일: rb8001/app/services/llm/gemini_handler.py
_safe_get_response_text 메서드 추가:
response.text접근 실패 시 대체 방법 시도candidates경로로 텍스트 추출- 모든 방법 실패 시 명확한 에러 메시지 반환
2. 빈 응답 에러를 Fallback 조건에 추가
파일: rb8001/app/services/ir_analyzer.py
Fallback 조건 확장:
- 기존: 429 Rate Limit 에러만 fallback
- 개선: 빈 응답/잘못된 형식 에러도 fallback 조건에 포함
- "비어있거나 잘못된 형식" 메시지 포함
- "parts: 0개" 포함
- "list index out of range" 포함
3. 모든 response.text 접근을 안전한 메서드로 변경
gemini_handler.py의 3곳에서 response.text 직접 접근을 _safe_get_response_text() 호출로 변경:
- Line 161: async API 호출 후
- Line 176: sync executor fallback 후
- Line 194: coroutine warning fallback 후
해결 결과
Fallback 체인 개선
기존 동작:
gemini-2.5-flash-lite (429) → gemini-2.5-flash (빈 응답) → 실패
개선된 동작:
gemini-2.5-flash-lite (429) → gemini-2.5-flash (빈 응답) → gemini-2.0-flash (성공)
실제 테스트 결과
- Fallback 체인 정상 작동: Rate Limit(429) 및 빈 응답 에러 모두 자동 전환
- 평가 완료: 23페이지 PDF 평가 성공 (total_score=76, grade=B)
- 최종 사용 모델:
gemini-2.0-flash
교훈
- 에러 타입 확장: Rate Limit뿐만 아니라 빈 응답/잘못된 형식 에러도 fallback 대상으로 고려
- 안전한 API 접근:
response.text직접 접근 대신 안전한 메서드 사용으로 IndexError 방지 - 로깅 강화: Fallback 전환 시 에러 타입을 명확히 로깅하여 디버깅 용이성 향상
- 점진적 개선: 429 에러 처리 후 실제 운영 중 발견된 문제를 추가 개선
참고
- 관련 계획 문서:
DOCS/journey/plans/251201_ir_deck_gemini_fallback_api_expansion_plan.md - Gemini API Rate Limit 정보:
DOCS/journey/research/LLM_모델_비교_분석.md