# 🤖 9-Agent 풀 미팅: InsuWiki 하이브리드 RAG v2 개발 전략

> **일시**: 2026-02-25 16:10  
> **안건**: Spec v2 (`260225-insuwiki-rag-spec-v2.md`) 기반 전체 개발 로드맵 수립  
> **사회**: 🎯 PM (Orchestrator)  
> **참석**: PM / Backend / Frontend / Data / AI / Security / Legal / UX / QA (9명)

---

## 📋 회의 배경

Spec v2는 v1 대비 다음을 추가로 정의:
- **정보 권위 계층** (§2): 약관 > 소식지 > 위키 > 유튜브
- **D형 복합형** 질의 분해 (§5)
- **Disambiguation 8케이스** 대화 로직 (§6)
- **면책기간 날짜 계산** (§7)
- **환각 방지 3중 구조** (§8)
- **법적 면책 문구 자동 삽입** (§9)
- **대화 세션 관리** `conversation_sessions` (§10)
- **용어 자동 추출 파이프라인** `insurance_terms` (§11)
- **유튜브 수집 파이프라인** (§12)
- **신뢰도 대시보드** (§17)

**현재 완료된 작업:**
- ✅ Phase 0 PoC 통과 (오차율 0%)
- ✅ Firestore TTL 정책 (jobs 10분, gemini_file_cache 48시간)
- ✅ Cloud Functions V2 `processDeepQuery` (C형)
- ✅ `/api/ai/query` Query Router 분기 (A/B/C/COMPLEX/AMBIGUOUS)
- ✅ `useAIPolling` + `InsurancePDFQuery` (C형 프론트엔드)
- ✅ `queryRouter.ts`, `answerValidator.ts` 유틸
- ✅ `firestore.ts` v2 스키마 전체 반영

---

## 🔴 1라운드: 빠른 현황 공유

### 🎯 PM
v2 Spec이 확정됐습니다. Step 순서를 v2 기준으로 재정렬하면:  
**Step 3(용어 추출) → Step 4(Query Router 고도화) → Step 5(Cloud Functions C형 고도화) → Step 6(Vector 인덱싱 B형) → Step 7(API Routes) → Step 8(프론트엔드) → Step 9(유튜브) → Step 10(캐시 무효화+대시보드)**  
각 Agent별로 v2에서 자기 파트가 어떻게 바뀌었는지 한 줄씩 보고해 주세요.

### 🔧 Backend
기존에 구현한 `processDeepQuery`는 C형에 해당합니다. v2에서 달라진 건:
1. **감사 로그 저장** — Job 완료 시 `query_logs` 컬렉션에도 기록 필요 (§13)
2. **`validateAnswer()` 통합** — 답변 생성 후 자동 검증, 실패 시 재처리 로직 추가 필요
3. **`GEMINI_SYSTEM_PROMPT` 적용** — 현재 프롬프트를 `answerValidator.ts`의 상수로 교체 필요
4. Drive 폴더 경로 파싱으로 `companyId/category` 자동 추출 로직 추가 (§3)

### 🎨 Frontend
기존 `InsurancePDFQuery`는 C형만 지원. v2 추가 UI 요구사항 (§15-2):
- **판매 중단 상품 배지** (`isSalesStopped: true` → "판매 종료 상품" 배지)
- **출처 배지 색상 구분** — 약관(파란색) / 소식지(초록) / 유튜브(빨간색)
- **유튜브-약관 상충 경고 배너** (⚠️ 경고 UI)
- **피드백 버튼** (맞음 / 틀림 / 불완전) → `query_logs.feedbackStatus` 저장
- **Disambiguation UX** — 8케이스별 다른 UI (선택 목록 / 조건 입력 폼 / 경고 배지 등)
- **면책기간 계산기** — 계약일 + 담보명 입력 → D-n일 표시

### 📊 Data
v2 §3 Google Drive 폴더 구조가 곧 메타데이터입니다. 가장 시급한:
1. **`insurance_metadata` 시딩** — Google Drive `InsuWiki_RAG/` 루트 하위 폴더 파싱 → 자동 컬렉션 생성 스크립트
2. **`insurance_terms` 파이프라인** (§11) — PDF 인덱싱 時 용어 자동 추출, `verified: false` 저장
3. **`insurance_tables` 시딩** — Phase 0 PoC 결과물(보험료 PDF)을 실제 Firestore로 ETL

### 🧠 AI
v2 §8 환각 방지 3중 구조 중 현재 코드에 있는 건 `validateAnswer()` + 시스템 프롬프트 상수뿐. 남은 것:
1. **유사도 게이트 실제 적용** — Vector Search 결과에 유사도 점수를 받아 0.70/0.85 임계값 비교 로직
2. **용어 정규화 전처리** (§11-2) — 질문 입력 → `insurance_terms` 동의어 확장 → 확장된 키워드로 검색
3. **D형 복합 질문 분해** (§5) — 현재 `decomposeComplexQuery()`는 규칙 기반 스텁. Gemini Flash로 의미 분해 추가 검토
4. **면책기간 추출 프롬프트** (§7) — 약관 원문에서 "계약일로부터 90일" 같은 패턴 추출 후 날짜 계산

### 🔒 Security
v2 §21 절대 금지 사항 중 코드 레벨 검토:
1. ✅ `GEMINI_API_KEY` — 서버 전용, 클라이언트 미노출 (`api/` 라우트 경유) 확인됨
2. ✅ `onSnapshot` 미사용, Polling 사용 확인됨
3. ⚠️ **Public 위키와 Private 노트를 동일 RAG 파이프라인에 혼재** 금지 — 현재 `insurance_chunks`에 `sourceType` 필드 있어 분리 가능. 단, `wiki` 유형 청킹 시 Private 노트 필터링 로직 명시적 추가 필요
4. ⚠️ `GEMINI_API_KEY`를 `.env`에만 두고 Firebase Secret Manager 미사용 — Cloud Functions에는 Secret Manager 도입 권장

### ⚖️ Legal
v2 §9 법적 면책 문구는 "모든 답변에 자동 삽입". 현재 `getDisclaimerText()` 함수는 있으나:
1. **Cloud Functions에서 답변 생성 직후 자동 append** 로직 미구현 — 반드시 코드에서 강제 삽입, UI에서 삭제 불가
2. **소식지/유튜브 답변 면책 문구** — 현재 약관 면책문구만 구현. 소식지/유튜브 케이스 추가 필요
3. **"※ 출처: {상품명} 약관 {페이지}p"** 형식 — 페이지 번호는 Gemini가 Long-Context 분석 시 명시해야 함 → 프롬프트에 출처 형식 명시 강화 필요
4. **판매 중단 상품 조회 허용** (§6 케이스 8) — 차단하지 않되 반드시 배지 표시 확인

### 🎭 UX
v2에서 UX가 가장 복잡해진 부분:
1. **Disambiguation 8케이스 UX 설계** — 케이스별 다른 인터랙션 필요:
   - 담보명 중복 → 라디오 버튼 목록 (`①②③`)
   - 고객 조건 미입력 → 인라인 폼 (나이/성별/흡연 입력)
   - 판매 중단 상품 → 자동 배지 + 조회 허용
   - 약관 DB 없음 → 업로드 요청 안내 카드
2. **대화 세션 UX** (§10) — "그럼 나나나 담보는?" 같은 연속 질문 지원. 현재 UI는 단발성. 채팅 스레드 형태로 확장 고려
3. **면책기간 계산기** — 별도 탭 or 인라인 도구
4. **신뢰도 점수 표시** — confidenceScore 배지 (0.85+ 초록, 0.70~0.85 노랑, 미만 빨강)

### ✅ QA
v2에서 테스트 케이스 대폭 증가:
1. **A형 테스트** — `insurance_tables` 구축 후 1원 단위 정확도 검증 (오차 허용 0%)
2. **B형 테스트** — Vector Search 유사도 임계값별 응답 검증 (0.85이상/0.70~0.85/0.70미만 각 케이스)
3. **C형 테스트** — Long-Context: validateAnswer() 통과 검증, 출처 형식, 면책 문구 자동 삽입 확인
4. **D형 테스트** — 복합 질문 분해 → 각 서브 질문 정확도
5. **Disambiguation 테스트** — 8케이스 각 분기 UX 동작 확인
6. **환각 테스트** — 불확실 표현 포함 답변 자동 폐기 검증
7. **유튜브 상충 테스트** — 약관과 다른 유튜브 내용 경고 배너 노출 확인

---

## 🟡 2라운드: 의존성 분석 및 선행 작업 확정

### 🎯 PM
의존성을 정리해 보겠습니다. 모든 검색 품질의 기반은 **`insurance_terms` 용어 정규화**입니다. 이게 없으면 "뇌졸중"으로 검색해도 "뇌혈관질환"이 담긴 삼성생명 약관을 못 찾아요. 최우선입니다.

```
[선행 필수]
insurance_terms 파이프라인 (Step 3)
    ↓
Vector 인덱싱 (Step 6) — 정규화된 키워드로 청킹
    ↓
Query Router 고도화 (Step 4) — 용어 정규화 전처리 포함
    ↓
[병렬 가능]
├── Cloud Functions 고도화 (Step 5) — validateAnswer + 면책 문구
├── API Routes 정비 (Step 7) — feedback 엔드포인트
└── 프론트엔드 (Step 8) — Disambiguation UX, 출처배지, 피드백버튼
    ↓
[나중에]
유튜브 파이프라인 (Step 9)
대화 세션 (§10) — 연속 질문 UX
신뢰도 대시보드 (§17)
```

### 🔧 Backend
`insurance_terms` 추출은 PDF 인덱싱 Cloud Function 안에 통합하는 게 효율적입니다.  
`onNewPdfUploaded` 트리거 (§14-1):
1. Drive 경로 파싱 → `companyId`, `category` 추출
2. PDF → 청크 분할 → Gemini Embedding → `insurance_chunks` 저장
3. **동시에** `TERM_EXTRACTION_PROMPT`로 용어 추출 → `insurance_terms` 저장 (`verified: false`)
4. `insurance_metadata` 자동 upsert

단일 PDF 업로드 이벤트 하나로 세 컬렉션을 동시에 채울 수 있습니다.

### 📊 Data
Google Drive `InsuWiki_RAG/` 폴더 구조 파싱 로직:
```
경로: 01_약관/생명보험/삼성생명/삼성생명_퍼펙트종신_2403.pdf
파싱:
  category = "life" (01_약관/생명보험)
  companyId = "samsung_life" (삼성생명)
  productId = "perfect_jongsin_2403" (파일명 규칙 기반)
  effectiveDateRange.start = "2024-03" (2403)
```
이 파싱 로직을 `onNewPdfUploaded` 함수 앞단에 구현하면 수동 시딩 없이도 Drive 업로드만으로 자동 등록됩니다.

### 🧠 AI
용어 정규화 캐싱 전략 제안: Firestore `insurance_terms` 조회는 매 질문마다 하면 API 호출이 많습니다.  
→ **서버 메모리 캐시** (Next.js revalidate 또는 인메모리 Map)로 1시간 TTL 캐싱 권장  
→ 신규 용어 추가 시 캐시 무효화 웹훅

---

## 🟢 3라운드: 최종 Task 분배 및 실행 순서 확정

### 🎯 PM — 최종 결정사항

```
🔴 다음 세션 즉시 착수 (이 순서대로):

[Task A] Drive 경로 파싱 + insurance_metadata 자동 시딩 스크립트
  담당: Data + Backend
  산출물: scripts/seed-insurance-metadata.ts

[Task B] PDF 인덱싱 Cloud Function (onNewPdfUploaded)
  담당: Backend
  산출물: functions/src/onNewPdfUploaded.ts
  포함: 청킹 → Embedding → insurance_chunks 저장
        용어 추출 → insurance_terms 저장
        insurance_metadata upsert

[Task C] Cloud Functions processDeepQuery 고도화
  담당: Backend + AI
  산출물: functions/src/processDeepQuery.ts (수정)
  포함: GEMINI_SYSTEM_PROMPT 적용
        validateAnswer() 통합 (실패 시 재처리/확인불가)
        면책 문구 자동 append
        query_logs 감사 로그 저장

[Task D] Query Router 고도화
  담당: AI + Backend
  산출물: src/lib/ai/queryRouter.ts (수정)
  포함: 용어 정규화 전처리 (insurance_terms 동의어 확장)
        D형 복합 질문 분해 고도화

🟡 그 다음 세션:

[Task E] /api/ai/vector-search 실제 구현 (B형)
  담당: Backend + AI
  포함: Gemini Embedding API 호출
        insurance_chunks Firestore Vector Index 쿼리
        유사도 0.85/0.70 게이트 적용

[Task F] /api/ai/feedback 엔드포인트
  담당: Backend
  산출물: src/app/api/ai/feedback/route.ts

[Task G] Disambiguation UX 컴포넌트 (8케이스)
  담당: Frontend + UX
  산출물: src/components/search/DisambiguationPanel.tsx

[Task H] 출처배지 + 판매중단배지 + 유튜브경고배너 UI
  담당: Frontend
  산출물: src/components/search/AnswerCard.tsx

🔵 나중에 (운영 단계):

[Task I] 유튜브 수집 파이프라인
  담당: Data + Backend
  산출물: functions/src/crawlYoutubeChannels.ts

[Task J] 대화 세션 관리 + 연속 질문 UX
  담당: Frontend + UX + Backend

[Task K] 신뢰도 대시보드
  담당: Data + Frontend
```

---

## 🔶 4라운드: 위험 요소 & 미결 사항

### ⚖️ Legal
**미결 사항**: "판매 중단 상품 약관을 조회 허용하되 배지 표시" — 법적으로 실무에서 허용되는지 추가 확인 필요. 현행 보험업법 상 판매 종료 상품 약관 정보 제공에 대한 명시적 금지 규정은 없으나, 보험사별로 상이할 수 있음. **종혁님 최종 확인 필요.**

### 🔒 Security
**Firebase Secret Manager 도입 건의**:  
현재 `GEMINI_API_KEY`가 `.env.local`에만 있음. Cloud Functions 환경에서는 `firebase functions:secrets:set GEMINI_API_KEY`로 Secret Manager 사용 강력 권장. Vercel 환경 변수는 현행 유지 가능.

### ✅ QA
**Phase 0 PoC 재검증 필요 케이스**:  
v2 §16에 따르면 "최극악 난이도(변액/CI, 조건부 주석 덕지덕지)" 샘플 미검증 상태. 해당 PDF 샘플 추가하여 통과 확인 후 `insurance_tables` 실 데이터 ETL 착수 권장.

### 🧠 AI
**D형 복합 질문 분해 한계**:  
현재 규칙 기반(`split`으로 접속사 분리)은 "삼성·한화 암+뇌혈관 보험료 비교"같은 자연어 분해를 못 함. Gemini Flash 서브 호출로 분해하는 방식은 추가 비용 발생. 우선 규칙 기반 유지 + AMBIGUOUS 처리로 사용자에게 유형 선택 유도가 현실적.

### 🎨 Frontend
**채팅형 UX 전환 검토**:  
§10 대화 세션 지원을 위해 현재 "단발 질문" UI에서 "채팅 스레드" UI로 전환이 필요. SearchModal 내에서 구현할지 별도 AI 채팅 페이지로 분리할지 결정 필요.  
**→ 제안: 현행 SearchModal 내 단발 유지, 별도 `/ai` 전용 페이지로 채팅형 구현 (종혁님 결정 사항)**

---

## ✅ 회의 결론 및 액션 아이템

| # | Task | 담당 | 우선순위 | 예상 세션 |
|---|------|------|---------|---------|
| A | Drive 경로 파싱 + insurance_metadata 시딩 스크립트 | Data/Backend | 🔴 즉시 | ✅ **완료** |
| B | PDF 인덱싱 Cloud Function (`onNewPdfUploaded`) | Backend | 🔴 즉시 | ✅ **완료** |
| C | processDeepQuery 고도화 (Prompt+검증+로그) | Backend/AI | 🔴 즉시 | ✅ **완료** |
| D | Query Router 용어 정규화 전처리 | AI/Backend | 🟡 다음 | ✅ **완료** (E에 통합) |
| E | Vector Search B형 실제 구현 | Backend/AI | 🟡 다음 | ✅ **완료** |
| F | /api/ai/feedback 엔드포인트 | Backend | 🟡 다음 | ✅ **완료** |
| G | Disambiguation UX 8케이스 | Frontend/UX | 🟡 다음 | ✅ **완료** |
| H | 출처배지+판매중단+유튜브경고 UI | Frontend | 🟡 다음 | ✅ **완료** |
| I | 유튜브 수집 파이프라인 | Data/Backend | 🔵 나중 | 🔄 **설계 중** |
| J | 대화 세션 + 연속 질문 UX | All | 🔵 나중 | ⬜ 미착수 |
| K | 신뢰도 대시보드 | Data/Frontend | 🔵 나중 | ⬜ 미착수 |

### 📌 종혁님 결정 완료 (2026-02-25 16:40)

| # | 결정 사항 | 결론 |
|---|---|---|
| 1 | 채팅형 AI UX 방향 | ✅ **현행 SearchModal 단발 유지** — 대화 세션은 추후 `/ai` 별도 페이지로 |
| 2 | 판매 중단 상품 약관 조회 | ✅ **무조건 허용** — 각 보험사 공시실 공개 자료 (배지 표시 유지) |
| 3 | Phase 0 PoC 3번 케이스 | ⏰ 나중에 체크 |

---

*회의록 작성: AI Agent PM / 2026-02-25 16:10*  
*다음 회의: Task A/B/C 완료 후 검토*
