# 🤖 9-Agent 미팅: Task I — 유튜브 자동 수집·요약 파이프라인

> **일시**: 2026-02-25 17:07  
> **안건**: 보험 유튜브 채널 영상 자동 수집 → 요약 → Google Drive 저장 → RAG 참조 파이프라인  
> **사회**: 🎯 PM  
> **참석**: PM / Backend / Frontend / Data / AI / Security / Legal / UX / QA

---

## 📋 요구사항 확정 (종혁님 제공)

| 항목 | 내용 |
|------|------|
| 채널 수 | 3~4개 (채널 ID 이미 확정) |
| 영상 언어 | 한국어 |
| 영상 길이 | **1시간~1시간 30분짜리 多** (핵심 과제) |
| 수집 주기 | 하루 2~4회 (신규 영상 유무 확인) |
| 검수 프로세스 | **검수 없음 — 완전 자동** |
| 우선순위 | 후순위 (운영 단계 기능) |
| 목적 | 설계사 상담 시 Reference로 활용 |

---

## 🔴 1라운드: 핵심 기술 도전 확인

### 🎯 PM
요구사항 중 가장 까다로운 건 **1시간~1.5시간짜리 한국어 영상**입니다. 각 Agent가 이 길이의 영상을 어떻게 처리할지 의견 주세요.

### 🧠 AI — 핵심 설계 결정

**Gemini 1.5 Pro의 유튜브 URL 직접 처리 방식을 추천합니다.**

```typescript
// Gemini가 YouTube URL을 직접 받아서 처리
const result = await model.generateContent([
    { fileData: { mimeType: 'video/mp4', fileUri: 'https://www.youtube.com/watch?v=...' } },
    { text: summaryPrompt }
]);
```

- Gemini 1.5 Pro는 **YouTube URL을 직접 입력**받아 처리 가능 (File API 업로드 불필요)
- 컨텍스트 윈도우 **100만 토큰** → 1시간 30분짜리도 처리 가능
- **단, 유료 API**: 1시간 영상 ≈ 약 36,000 토큰(영상 프레임+자막) → 약 $0.05~0.10/영상

**⚠️ 중요 제약**: Gemini File API로 유튜브 URL을 직접 처리하는 기능은 **Google AI Studio에서는 가능**하지만, **API로는 현재 YouTube URL 직접 지원이 제한적**입니다.

**현실적 대안 — 2-Track 접근:**

| Track | 방법 | 처리 가능 여부 | 비용 |
|-------|------|-------------|------|
| A (추천) | YouTube 자막 API → 자막 텍스트 추출 → Gemini 요약 | ✅ 안정적 | $0.001~0.01/영상 |
| B | youtube-transcript-api npm → 텍스트 → Gemini 요약 | ✅ 안정적 | 동일 |
| C | Gemini YouTube URL 직접 | ⚠️ API 지원 불안정 | $0.05~0.10/영상 |

**→ Track A 추천**: YouTube Data API로 자막 추출 + Gemini Flash로 요약

### 🔧 Backend

1시간 30분 영상의 자막은 한국어 기준 약 **12,000~18,000 토큰**입니다. Gemini 1.5 Flash(100만 컨텍스트)로 충분히 처리 가능.

**처리 흐름:**
```
Cloud Scheduler (6시간마다 = 하루 4회)
    ↓
crawlYoutubeChannels Cloud Function (v2, 타임아웃 540초)
    ↓
YouTube Data API: 채널별 최신 영상 목록 조회 (pageToken 활용)
    ↓
새 영상만 필터 (youtube_channels.lastCrawledAt 이후 업로드)
    ↓
영상별: 자막 추출 → Gemini Flash 요약
    ↓
Google Drive 업로드 (04_유튜브요약/{채널명}/{날짜}_{제목}.md)
    ↓
Gemini Embedding → insurance_chunks에 저장 (sourceType: 'youtube')
    ↓
기존 policy 청크와 유사도 비교 → conflictsWithPolicy 감지
    ↓
youtube_knowledge 컬렉션 저장
```

**주의사항**: 자막이 없는 영상(자동 자막도 없는 경우) → 스킵 + 로그

### 📊 Data

**Google Drive 폴더 구조 & 파일 형식:**
```
📁 InsuWiki_RAG/
└── 📁 04_유튜브요약/
    ├── 📁 채널명A/
    │   ├── 2026-02-25_영상제목_abc123.md
    │   └── 2026-02-24_영상제목_def456.md
    └── 📁 채널명B/
        └── 2026-02-25_영상제목_ghi789.md
```

**파일 형식:**
```markdown
# [영상 제목]

- **채널**: {채널명}
- **업로드일**: 2026-02-25
- **원본 URL**: https://youtube.com/watch?v={videoId}
- **영상 길이**: 1:23:45
- **처리일**: 2026-02-25T17:00:00+09:00

## 📝 핵심 요약 (3줄)
1. ...
2. ...
3. ...

## 💡 보험 설계사 활용 포인트
- ...

## ⚠️ 약관과 다른 내용 (확인 필요)
> 없음 / 발견된 경우 구체적 내용

## 🔍 상세 내용 (주요 섹션별)
### [섹션 제목 1]
...
### [섹션 제목 2]
...

---
*자동 생성 | Gemini 1.5 Flash | 원본 내용과 다를 수 있으니 반드시 약관 원문 우선*
```

### ⚖️ Legal

**유튜브 자막 활용의 법적 검토:**
- YouTube 자막은 **공개 콘텐츠의 텍스트 처리**로, 개인/업무 내부 참조 목적이면 저작권 침해 리스크 낮음
- 단, **외부 공개(웹사이트 노출) 시에는 저작권 문제** 발생 가능
- **→ Google Drive에만 저장하고 설계사 내부 참조용으로 제한** → 현재 용도 OK
- 요약 파일 하단에 "원본 출처 URL" 명시 → 저작권자 표시 의무 이행

### 🔒 Security

- YouTube Data API Key (`YOUTUBE_API_KEY`) → Firebase Secret Manager 등록
- 자막 처리 결과는 구글 드라이브에만 저장, 외부 노출 없음 → OK
- Cloud Functions에서 Google Drive 쓰기 권한 필요 → 서비스 계정에 `drive.file` 스코프 추가

### 🎭 UX

검수 없이 완전 자동화이므로 별도 UX 없음. 단, **오류 알림 채널** 필요:
- 자막 추출 실패, API 쿼터 부족 등 → **Firestore에 error_logs 저장 또는 이메일 알림**
- 설계사가 RAG 답변에서 유튜브 출처 배지({채널명} + 업로드일)를 통해 원본 확인 가능 (AnswerCard에서 이미 구현됨)

### ✅ QA

**테스트 체크리스트:**
1. 자막 없는 영상 스킵 동작 확인
2. 이미 처리한 영상 중복 처리 방지 (`youtube_knowledge` videoId 중복 확인)
3. 1.5시간짜리 자막 토큰 한도 확인 (Gemini Flash 컨텍스트)
4. Drive 업로드 실패 시 재시도 로직
5. `conflictsWithPolicy` 감지 정확도 수동 샘플 확인
6. Cloud Scheduler 6시간 주기 정상 동작

---

## 🟡 2라운드: 핵심 결정 사항

### 🧠 AI — 자막 처리 전략 (1시간 30분 영상)

**YouTube 자막 추출 방식 선택:**
```
youtube-caption (npm) 또는 YouTube Data API captions
    ↓
한국어 자막 텍스트 (약 12,000~18,000 토큰)
    ↓
Gemini 1.5 Flash (무료 티어 1분당 백만 토큰)
    ↓
보험 맥락 요약 프롬프트 (§12 spec 기반)
```

**요약 프롬프트 전략 (긴 영상 대응):**
```typescript
const YOUTUBE_SUMMARY_PROMPT = `
당신은 보험 정보를 분석하는 전문가입니다.
다음 보험 유튜브 영상 자막을 분석해 주세요.

[분석 항목]
1. 핵심 내용 3줄 요약
2. 보험 설계사가 고객 상담에 활용할 수 있는 포인트 (최대 5개)
3. 특정 보험 상품/회사명이 언급된 경우 → 추출
4. 약관 규정과 다를 수 있는 내용 (있으면 명시, 없으면 "없음")
5. 주제별 섹션 분류 요약

⚠️ 규칙:
- 자막에 없는 내용은 절대 추가하지 않습니다
- 보험료, 금액은 자막 원문 그대로만 인용
- 영상 제목과 채널명을 기준으로 신뢰도를 스스로 판단
`;
```

### 🔧 Backend — 중복 처리 방지

```typescript
// youtube_knowledge에 videoId 존재 여부 확인 후 스킵
const existing = await db.collection('youtube_knowledge')
    .where('videoId', '==', videoId)
    .limit(1)
    .get();
if (!existing.empty) {
    console.log(`Already processed: ${videoId}`);
    continue;
}
```

### 📊 Data — 자막 없는 영상 처리 전략

**자막 추출 실패 시 처리:**
1. 공식 자막 없음 → 자동 자막(auto-generated) 시도
2. 자동 자막도 없음 → **영상 제목 + 설명(description)만 요약** + "자막 없는 영상" 표시
3. 영상 자체가 한국어가 아님 → 스킵

---

## ✅ 최종 설계 확정

```
함수명: crawlYoutubeChannels (Cloud Functions v2, 540초 타임아웃)
스케줄: 매 6시간 (asia-northeast3, 한국 시간 기준)
트리거: Cloud Scheduler → Pub/Sub → Cloud Function

[순서]
1. youtube_channels 컬렉션에서 활성 채널 목록 로드
2. 채널별: YouTube Data API playlistItems (최신 영상 10개)
3. lastCrawledAt 이후 업로드된 영상만 필터
4. 영상별:
   a. youtube_knowledge에 videoId 중복 확인 (스킵 처리)
   b. YouTube captions API → 한국어 자막 추출
      (없으면 auto 자막 시도, 그래도 없으면 description 요약)
   c. Gemini 1.5 Flash: YOUTUBE_SUMMARY_PROMPT로 요약
   d. Google Drive 04_유튜브요약/{채널명}/{날짜}_{제목}.md 업로드
   e. Gemini text-embedding-004: 요약 텍스트 임베딩
   f. insurance_chunks 저장 (sourceType: 'youtube')
   g. 기존 policy 청크 벡터 비교 → conflictsWithPolicy 감지
   h. youtube_knowledge 저장
5. youtube_channels.lastCrawledAt 업데이트
```

---

## ⚠️ 위험 요소 & 미결 사항

### 🔒 Security
- `YOUTUBE_API_KEY` 할당량 주의: 무료 10,000 units/일, 채널당 영상 조회 ≈ 100 units → 하루 4회 × 4채널 = 1,600 units → **여유 있음**

### 🧠 AI
- Gemini Flash 무료 티어: 분당 15 요청 → 영상이 많을 경우 rate limit 주의, **지수 백오프(exponential backoff) 필수**
- 1.5시간 자막(18,000 토큰) + 요약 프롬프트 → Flash 무료 티어 내 처리 가능

### ✅ QA
- `conflictsWithPolicy` 자동 감지 정확도는 초기에 낮을 수 있음 → 첫 1주일은 수동 샘플링 권장 (종혁님 확인)

---

## 📋 구현 액션 아이템

| Task | 내용 | 파일 |
|------|------|------|
| I-1 | `youtube_channels` 초기 데이터 시딩 | Firestore Console에서 수동 등록 |
| I-2 | `crawlYoutubeChannels` Cloud Function 작성 | `functions/src/crawlYoutubeChannels.ts` |
| I-3 | Cloud Scheduler 설정 | `firebase.json` 또는 GCP Console |
| I-4 | Drive `04_유튜브요약/` 폴더 생성 | Google Drive 수동 |
| I-5 | Firestore Vector Index에 youtube 타입 포함 확인 | Firebase Console |

---

*회의록 작성: AI Agent PM / 2026-02-25 17:07*  
*다음 액션: Task I-2 `crawlYoutubeChannels.ts` 구현*
