# ADR-260225: 하이브리드 RAG 아키텍처 (Option F) 최종 채택

**날짜**: 2026-02-25  
**상태**: ✅ 확정 (Accepted)  
**결정권자**: 종혁님 (Product Owner)  
**관련 Task**: task00048

---

## 배경 (Context)

InsuWiki에 AI 기반 보험 약관 질의 기능을 추가하는 과정에서, 다음 4가지 기술적 제약이 동시에 존재했습니다.

1. **Vercel 10초 타임아웃**: 300페이지 약관 PDF를 한 번의 서버리스 함수로 처리할 수 없음
2. **NotebookLM 50개 파일 제한**: 수십 개 보험사 약관을 수용할 수 없는 구조적 한계
3. **Gemini File API 48시간 TTL**: 업로드된 파일이 자동 만료되는 캐시 관리 필요
4. **롱 컨텍스트 과금**: 128k 토큰 초과 시 비용 폭탄 위험

---

## 결정 (Decision)

단일 아키텍처의 한계를 인정하고, **데이터 특성별로 파이프라인을 분리하는 하이브리드 아키텍처(Option F)**를 채택합니다.

| 데이터 유형 | 파이프라인 |
|---|---|
| 위키/소식지 (경량) | Firestore Vector RAG (기존 방식) |
| 보험료 표 (구조화) | Gemini Vision 파싱 → Firestore NoSQL 컬렉션 적재 |
| 약관 PDF (대용량) | 사용자 사전 선별 → Cloud Functions V2 롱 컨텍스트 1회성 쿼리 |

### 핵심 기술 결정

| 항목 | 결정 사항 | 이유 |
|---|---|---|
| 비동기 처리 | Cloud Functions V2 (`timeoutSeconds: 540`) | Vercel 10초 타임아웃 우회 |
| 클라이언트 통신 | REST API Polling (4초 간격) | `onSnapshot` 대비 비용 및 모바일 안정성 우위 |
| Job 상태 관리 | Firestore `jobs` 컬렉션 (TTL: 10분) | 좀비 Job 자동 청소 |
| 파일 캐시 | Firestore `gemini_file_cache` (TTL: 48시간) | Gemini File API 수명 주기와 동기화 |
| 타임아웃 방어 | 프론트엔드 3분 로컬 타이머 | 서버 장애 시 무한 로딩 방지 |
| PDF 파싱 모델 | Gemini 2.5 Flash + File API | PoC 검증 결과 오차율 0% 달성 |

---

## 기각된 대안 (Rejected Alternatives)

- **Option A (Vertex AI Search)**: 월 기본 유지비 $20~50 발생으로 개인 규모에 부적합
- **Option B (Dify.ai)**: 설정 관리 부담 및 50MB 용량 한계
- **Option C (로컬 AnythingLLM)**: PC 켜져있을 때만 동작, 서버리스 불가
- **Option E (Gemini File API 직결 단일)**: 4대 기술 제약(타임아웃, 선별 불가, TTL, 과금) 해결 불가

---

## 결과 및 영향 (Consequences)

### 긍정적 영향
- Vercel 타임아웃 완전 우회: 롱 컨텍스트 약관도 9분 내 처리 가능
- RAG 비용 통제: 회사/상품 사전 선별로 쿼리 대상 최소화
- 캐시 Hit 시 Google Drive 재다운로드 없음 → 빠른 응답

### 고려사항 (현재 해결된)
- Firebase Blaze 플랜 활성화 필요 (기본 무료 범위 내 거의 무과금)
- Firestore Console에서 `expireAt` TTL 정책 수동 활성화 필요 (1회성 설정)

---

## 참고 문서

- 회의록: `docs/meetings/260225-00.41-notebooklm-drive-integration-agent-meeting.md`
- 구현: `functions/src/ragQuery.ts`, `nextapp/src/hooks/useAIPolling.ts`
