# IR Deck 평가 KeyError 수정 및 LLM 호출 최적화

**날짜**: 2025-12-01  
**작성자**: Auto  
**관련 파일**:
- `rb8001/app/state/ir_valuation_repository.py`
- `rb8001/app/services/ir_deck_analyzer.py`
- `rb8001/scripts/migrate_ir_deck_score_nullable.py`

---

## 문제 상황

### 1. KeyError: 'score'
- `ir_valuation_repository.py:145`에서 `page_eval["score"]` 참조 시 KeyError 발생
- `evaluate_by_page()`는 `score` 필드를 반환하지 않음 (페이지별 점수 제거됨)
- DB 스키마: `ir_deck_page_evaluations.score`는 `NOT NULL` 제약 조건

### 2. Gemini API 할당량 초과
- 페이지당 11회 LLM 호출 (10개 스토리 평가 + 1회 피드백 추출)
- 10페이지 기준 110회 호출 → 할당량 초과 (15회/분)
- 429 `ResourceExhausted` 에러 발생

## 해결 방안

### 1. KeyError 수정
- `ir_valuation_repository.py:41`: ORM 모델 `score` 필드를 `nullable=True`로 변경
- `ir_valuation_repository.py:74`: DDL에서 `score INTEGER NULL`로 변경
- `ir_valuation_repository.py:145`: `page_eval.get("score")` 사용 (없으면 NULL 저장)
- `scripts/migrate_ir_deck_score_nullable.py`: 기존 DB 마이그레이션 스크립트 작성

### 2. LLM 호출 최적화
- `ir_deck_analyzer.py:246-273`: `evaluate_by_page()`에서 `score` 필드 제거
- `ir_deck_analyzer.py:275-365`: `_evaluate_page_comprehensive()` 메서드 추가
  - 단일 LLM 호출로 10개 스토리 평가 + 피드백 추출 통합
  - 11회 → 1회로 호출 횟수 감소
- `ir_deck_analyzer.py`: `_evaluate_story_coverage()` 메서드 제거 (기능 통합)

## 구현 완료

- 커밋: TBD (작업 진행 중)
- 테스트: `test_ir_deck_evaluation.py`에 검증 테스트 추가
  - `test_create_evaluation_without_score()`: score 없이 저장 검증
  - `test_evaluate_by_page_single_llm_call()`: 단일 LLM 호출 검증

## 교훈

### DB 스키마 변경 시 동기화 필수
- ORM 모델, DDL, Repository 코드를 동시에 수정해야 함
- 한 곳만 수정 시 런타임 에러 또는 스키마 불일치 발생
- 교훈: 스키마 변경 시 3곳(ORM/DDL/Repository) 동시 점검 체크리스트 작성

### LLM 호출 최적화 필요
- 페이지별 평가에서 11회 호출은 과도함
- 단일 프롬프트로 통합 가능한 작업은 반드시 통합
- 교훈: LLM 호출 전 호출 횟수 계산 및 최적화 검토 필수

### TDD 원칙 준수
- 테스트 작성 후 구현으로 버그 조기 발견
- `KeyError`는 테스트로 사전 발견 가능했던 문제
- 교훈: 스키마 변경 시 반드시 테스트 먼저 작성

