# task-2987 — 인슈위키 유튜브: 임베딩 엔진을 Gemini → Claude Sonnet 으로 전환

**레벨**: Lv.2 · **팀**: dev1-team (헤르메스) · **회장 지시** (2026-08-20)

## 배경
task-2980 Phase 2 에서 **요약** 엔진은 Gemini → Claude Sonnet CLI 로 전환해 정상 동작을 실증했다
(공개 카드 1건 생성 · 5,844자 · knowledge 151→152 · summarized 1).

그러나 **임베딩은 아직 Gemini(`genai`)에 묶여 있다.** `GEMINI_API_KEY` 가 폐기된 상태
(400 API_KEY_INVALID 실측)라 임베딩이 실패하고, 그 결과 `insurance_chunks` 에 아무것도 저장되지 않는다.
`youtube_knowledge` 문서에 `embedding_len=0` · `embeddingFailed=True` 로 남아 있다.

**회장 지시: 임베딩도 Sonnet 으로 전환한다.** 신규 Gemini 키 발급을 기다리지 않고 의존을 끊는 방향이다.

## ★ 먼저 확인할 것 — 착수 전 필수
Claude/Sonnet 계열은 **텍스트 생성 모델이고, 임베딩 전용 API 를 제공하지 않는다.**
따라서 "요약을 Sonnet 으로 바꾼 것"과 같은 방식의 1:1 치환이 **성립하지 않을 수 있다.**

착수 전에 다음을 **직접 확인하고 결론을 보고**하라. 확인 없이 구현하지 말 것.
1. 현재 사용 중인 Claude CLI/SDK 경로에서 **임베딩 엔드포인트가 실제로 제공되는지**
2. 제공되지 않는다면 실행 가능한 대안은 무엇인지. 최소 다음 3개를 비교해 장단점과 비용을 제시할 것:
   - (a) 로컬 임베딩 모델 (예: sentence-transformers 계열). GPU 는 이미 복구돼 사용 가능하다.
   - (b) 다른 임베딩 전용 API
   - (c) 신규 Gemini 키 발급 후 현행 유지
3. 기존 `insurance_chunks` 의 **벡터 차원(dimension)** 과 호환되는지. 차원이 바뀌면 기존 데이터 재색인이 필요하다.
   기존 151건이 어떤 차원으로 저장돼 있는지 실측하라.

**위 1~3 확인 결과를 먼저 보고하고, ANU 승인을 받은 뒤 구현에 착수한다.**
확인 결과 Sonnet 임베딩이 불가능하다면 그 사실을 근거와 함께 보고하는 것이 이 태스크의 정답이다.
억지로 우회 구현해서 "전환 완료"로 보고하지 말 것.

## 구현 (승인 후)
- 요약 전환 때와 동일한 구조를 따른다. `generate_summary` 가 `_call_claude_cli` 만 쓰도록 바꾼 방식 참고.
- `genai` 의존이 임베딩에서도 제거되면 패키지 의존 자체를 정리한다.
- 실패 시 조용히 넘어가지 말고 명시적으로 기록한다(현재 `embeddingFailed` 플래그 방식 유지).

## 검증
1. 실제 영상 1건으로 **E2E 재수행**: 전사 → 요약 → **임베딩 → `insurance_chunks` 저장**까지 도달
2. `insurance_chunks` 건수가 실제로 증가하는 것을 Firestore 에서 직접 확인 (0 → N)
3. `embedding_len` 이 0 이 아닌 값으로 기록되는지 확인
4. 유사도 검색이 실제로 동작하는지 쿼리 1건으로 실증
5. `pytest tests/` 회귀 유지 (Phase 2 기준 **83 passed**)

## 범위 · 주의
- 작업 위치: `scripts/youtube-pipeline/` 및 관련 파이프라인 코드
- **`.pyc` 를 새로 커밋하지 말 것.** 이 저장소는 `.gitignore` 에 `__pycache__` 규칙이 없어
  아무 생각 없이 `git add -A` 하면 컴파일 산출물이 다시 딸려 들어간다.
  커밋 전 `git status` 로 `.pyc` 가 포함되지 않았는지 반드시 확인한다.
- 시크릿 스캔은 `.py` 뿐 아니라 **컴파일 산출물까지** 훑는다.
- 키 로테이션(별건, 회장 결정 대기)과 이 태스크는 독립이다. 키 회전을 이 태스크에서 하지 말 것.

## allowed_resources (본 task의 capability)

```yaml
allowed_resources:
  paths:
    - "scripts/youtube-pipeline/**"
    - "functions/src/**"
    - "tests/**"
    - "memory/reports/task-2987.md"
  forbidden_paths:
    - "**/__pycache__/**"
    - "**/*.pyc"
    - ".github/**"
    - "firestore.rules"
  commands:
    - "pytest"
    - "python3 -m py_compile"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 완료 조건
사전 확인 3항목 보고 + ANU 승인 → 구현 → E2E 에서 `insurance_chunks` 실제 증가 실증 → pytest 83 유지

## 보고
`memory/reports/task-2987.md` 작성 후 ANU 콜백. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.

## goal_assertions (auto-generated)
- `pytest tests/`
