docs: IR Deck 평가 Gemini Fallback 빈 응답 에러 처리 문서화
- 문제: 프론트엔드에서 (템플릿) 오류 메시지 반복 발생 - 원인: 빈 응답(parts: 0개) 에러가 fallback 조건에 포함되지 않음 - 해결: 빈 응답 에러도 fallback 조건에 추가, _safe_get_response_text 메서드 구현 - 결과: Fallback 체인이 정상 작동하여 평가 완료
This commit is contained in:
parent
b9d35b7046
commit
9d95c276a7
@ -0,0 +1,87 @@
|
||||
# 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`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user