# IR Deck 평가 Gemini Fallback 빈 응답 에러 처리

**날짜**: 2025-12-02
**작성자**: Auto
**관련 파일**: 
- `rb8001/app/services/ir_analyzer.py`
- `rb8001/app/services/llm/gemini_handler.py`

---

## 문제 상황

IR Deck 평가 중 프론트엔드에서 "(템플릿) 평가 처리 중 오류가 발생했습니다." 메시지가 반복적으로 표시됨.

## 원인 분석

로그 분석 결과:

1. **Fallback 체인 작동**: `gemini-2.5-flash-lite` (429 Rate Limit) → `gemini-2.5-flash`로 전환 성공
2. **새로운 에러 발생**: `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

3. **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`

## 교훈

1. **에러 타입 확장**: Rate Limit뿐만 아니라 빈 응답/잘못된 형식 에러도 fallback 대상으로 고려
2. **안전한 API 접근**: `response.text` 직접 접근 대신 안전한 메서드 사용으로 IndexError 방지
3. **로깅 강화**: Fallback 전환 시 에러 타입을 명확히 로깅하여 디버깅 용이성 향상
4. **점진적 개선**: 429 에러 처리 후 실제 운영 중 발견된 문제를 추가 개선

## 참고

- 관련 계획 문서: `DOCS/journey/plans/251201_ir_deck_gemini_fallback_api_expansion_plan.md`
- Gemini API Rate Limit 정보: `DOCS/journey/research/LLM_모델_비교_분석.md`

