Skip to main content

summarize

URL/파일/미디어 요약 및 콘텐츠 추출. YouTube 영상, 웹페이지, PDF, 팟캐스트, 오디오/비디오 지원. 정본이 필요한 YouTube 자막은 youtube-transcript 스킬을 쓴다.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
junghan0611/agent-config
آخر نشاط في المصدر
٦ سبتمبر ٢٠٢٦ في ٠٧:١٠
لغة SKILL.md المكتشفة
الكورية
النجوم
٥
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
summarize
description
URL/파일/미디어 요약 및 콘텐츠 추출. YouTube 영상, 웹페이지, PDF, 팟캐스트, 오디오/비디오 지원. 정본이 필요한 YouTube 자막은 youtube-transcript 스킬을 쓴다.
# summarize [@steipete/summarize](https://github.com/steipete/summarize) 기반 콘텐츠 요약/추출 도구. v0.21.11 설치 확인됨 — 최신판, 새 기능 릴리스는 없다(보안 패치뿐). **버전이 아니라 기능을 몰라서 못 쓰고 있었다.** 이 문서는 실제로 커맨드를 돌려서 확인한 결과를 기반으로 한다. ## 경계 — YouTube 정본이 필요하면 이 스킬을 쓰지 마라 `summarize --extract`는 YouTube 자막도 뽑아준다. 하지만 **정본(authoritative source)이 목적이면 안 된다.** `youtube-transcript` 스킬은 별개 계약을 가진 별개 도구다 — 이 스킬이 그것을 대체하지 않는다. `youtube-transcript`의 계약(GLG 워딩, 원문은 `~/sync/org/notes/20250409T144319--...-유튜브-자막-정본과-...org`): > "너가 가져온 스크립트 자체를 더 기계적으로 재현가능하게 담아내야 한다 … 마침표 구분은 > 이건 생각하기 나름이다. LLM이 개입되면 안돼 … 사람이 발화하면 다 문장 구조를 맞춰서 > 하는 것은 아니잖아. 그대로 살려야지." 구현자(grok-4.5, agent-config)가 남긴 한 문장이 이 도구와의 차이를 정확히 가른다: > "없는 마침표·없는 화자·없는 문장 경계를 코드가 발명하는 순간, 그 파일은 증거가 > 아니라 해석본이 된다." `youtube-transcript`는 원본 `>>` 화자 경계로만 turn을 나누고, 모르는 화자는 라벨을 안 붙이고, 문장 부호를 LLM이 다듬지 않는다. 산출물은 `~/org/transcript`에 denote md 정본으로 남아 가든 아이디로 편입된다. `summarize --extract`는 이 계약이 전혀 없다 — 빠르고 편하지만, LLM 마크다운 변환(`--markdown-mode llm`)을 켜면 문장 경계·마침표가 재구성될 수 있고, 기본 readability 경로도 원본 스트림 그대로를 보증하지 않는다. **나눔 기준**: 인용·증거·가든 반입처럼 "누가 정확히 뭐라고 말했는가"가 중요하면 `youtube-transcript`. 빠르게 내용 파악만 하면 되는 리서치/스크리닝이면 `summarize --extract`. 헷갈리면 정본 쪽으로 fail — `youtube-transcript`를 쓴다. ## Setup ```bash pnpm add -g @steipete/summarize@latest ``` 설정 파일: `~/.summarize/config.json` — **반드시 둔다.** ```json { "model": { "id": "cli/claude/sonnet" } } ``` 이게 기본 레일이다(아래 "레일 선택" 절 참조) — 외부 계량 API가 아니라 기존 Claude Code 구독을 통해 돈다. 실측 확인: `summarize status` → `Model: cli/claude/sonnet (config)`. 환경변수 `GEMINI_API_KEY`는 `~/.env.local`에서 로드됨(Google 직결 폴백용, 아래 참조). 실행 전 항상 `source ~/.env.local &&`. ## ⚠️ `--model auto`를 쓰지 마라 — 실측으로 재현된 실패 설정 파일 없이 돌리거나 `--model auto`를 명시하면 이렇게 된다(2026-08-20, `--verbose`로 실측): 1. 내장 기본 후보 1순위 `google/gemini-3-flash` 시도 → **우리 Gemini 키에서 이미 실패** (`is not available via the Gemini API (v1beta) for this API key`). summarize 0.21.11에 박혀 있는 기본 모델 id가 현재 Google API 버전과 안 맞는다 — 우리 쪽 설정 문제가 아니라 패키지 내장 기본값이 낡았다. 2. `openai/gpt-5-mini` 시도 → `OPENAI_API_KEY` 없어서 skip. 3. **`openrouter/openai/gpt-5-mini`로 자동 폴백 — 실제로 OpenRouter API를 호출한다** (`OPENAI API error (404)`로 실패했을 뿐 호출 자체는 나갔다). 4. `anthropic/claude-sonnet-4-5` → 키 없어서 skip. 5. **`openrouter/anthropic/claude-sonnet-4.5`로 다시 OpenRouter 호출** → 가드레일에 막혀 404. 6. 전부 실패 → 요약 없이 추출된 원문만 그대로 출력(`via html, no model`). 즉 **우리 OpenRouter 계정의 가드레일 설정이 우연히 막아줬을 뿐**, 그 설정이 달랐다면 auto 모드는 조용히 OpenRouter로 새서 추론을 돌렸을 것이다. `OPENROUTER_API_KEY`가 환경에 있는 한 이 경로는 항상 열려 있다. **결론: 모델은 항상 명시적으로 고정한다.** `~/.summarize/config.json`에 `model.id`를 두면 auto 후보 목록 자체를 안 탄다 — `cli/claude/sonnet`로 고정한 뒤 `--verbose`로 재확인: `auto candidate` 로그 줄이 아예 안 뜬다(고정 모델은 auto 선택 로직을 건너뛴다). 확인: `summarize status` → `Model: cli/claude/sonnet (config)`. ## 핵심 원칙: 요약보다 `--extract`를 먼저 고려하라 "요약은 지어낼 수 있어 못 믿겠다"는 걱정에 대한 답은 **무손실 경로를 쓰는 것**이다. `--extract`는 LLM을 전혀 타지 않는다 — 실측 확인: ```bash source ~/.env.local && summarize "https://example.com" --extract --plain # → 3.8s, 모델/비용 표시 전혀 없음, 원문 그대로 ``` `--json` 출력에서도 `--extract` 모드는 LLM metrics 필드 자체가 비어 있다. 추출은 웹페이지, YouTube/미디어, 로컬 PDF에 다 된다(`-` stdin만 미지원). API 키가 아예 없어도 웹페이지/ YouTube 추출은 된다 — LLM을 안 타니까. (단, YouTube 정본이 목적이면 위 "경계" 절 참조 — `--extract`는 편의 경로지 정본 경로가 아니다.) ```bash # 웹페이지 원문 추출 (요약 없음, LLM 없음, 무료) summarize "https://example.com/article" --extract --format md --plain # YouTube 자막 원문 추출 (요약 없음, LLM 없음, 무료) — 빠른 스크리닝용, 정본 아님 summarize "https://youtu.be/VIDEO_ID" --extract --plain ``` 실측(YouTube, Rick Astley 클래식 영상): 캐시 없이도 1.2초, `captionTracks`에서 바로 자막 가져옴, 조회수까지 같이 출력(`YouTube views: 1,806,048,551`). 요약이 필요 없고 원문/자막만 빠르게 훑으면 되면 `--extract`가 먼저다 — 정본이 필요하면 `youtube-transcript`로 간다. ## 레일 선택 — 기본은 `--cli claude`, 이유는 비용이 아니라 레일 가짓수 **외부 계량 API를 기본으로 쓰지 않는다.** Google 직결(`google/*`, `GEMINI_API_KEY`)도 기본값에서 내린다 — API 키를 여러 개 열면 관리해야 할 레일이 늘어나고 사고 표면이 넓어진다("API 열면 지저분해져서"). 기본 config는 `model.id: "cli/claude/sonnet"`로 고정하고, Claude Code 기존 구독 하나로 돈다. **"우리가 파이프를 직접 짜면 되지 않나"에 대한 답 — 이미 측정됐다.** `summarize --extract` 로 뽑은 텍스트를 `claude -p`로 직접 파이프하는 방식과 `--cli claude`를 비교한 실측(같은 세션 계열, 위키 "Ship of Theseus" 2,557단어/16KB 기준): - `summarize --extract` (3.6s) → `claude -p --model claude-sonnet-5 --output-format json` (12.0s) = 15.6s. usage: input 2 / cache_read 15,224 / cache_write 20,282 / output 504 → **입력 약 35.5k 토큰.** - 즉 손으로 파이프를 짜면 `--cli claude`(아래 표의 31k)보다 **오히려 더 먹는다.** 그 30k대 토큰은 summarize의 오버헤드가 아니라 **Claude Code 하네스 자체의 시스템 프롬프트/툴 정의**다 — summarize든 손파이프든 Claude CLI를 부르는 순간 피할 수 없다. - 결론: 직접 파이프를 새로 만들 이유가 없다. `--cli claude`가 이미 그 방식이고, 캐시·재시도· 포맷 처리까지 더 잘 갖춰져 있다. ## 실측 비용/속도 (2026-08-20, `https://example.com` 기준 — 매우 짧은 페이지) | 경로 | 시간 | 토큰 | 비용 | |------|------|------|------| | `--extract` | 3.8s | — (LLM 없음) | $0 | | **`--cli claude` (기본 레일)** | 7.1–9.0s | ↑**31,160–31,254** ↓~100–130 | CLI가 표시하는 값은 $0.10 안팎이지만 이건 **API 환산 추정치**다. 실제 청구는 Claude Code 구독 쿼터에서 나간다 — $ 그 자체가 아니라 **형제들과 나눠 쓰는 5h/7d 윈도우를 얼마나 먹는지**로 읽어야 한다 | | `--model google/gemini-3-flash-preview` (폴백, config 아님) | 3.6–4.9s | ↑899 ↓99 | **~$0.0007** (Gemini 3 Flash Preview 공시가 $0.50/1M in, $3/1M out 기준 계산 — CLI가 직접 $ 표시는 안 함) | | `--model auto` (미고정) | 4s | ↑3,351×N회 시도 | 전부 실패 → 요약 안 나옴. 위 경고 참조 | **`--cli claude`는 짧은 페이지에도 프롬프트 토큰이 31k 들어간다** — Google 직결(899 토큰) 대비 34배. 위 "레일 선택" 절에서 확인했듯 이건 summarize 탓이 아니라 Claude CLI 하네스 자체의 오버헤드이고, 직접 파이프로 짜도 피할 수 없다(오히려 35.5k로 더 나온 사례도 있음). **대량 반복 요약 루프**에는 이 오버헤드가 누적되니 주의 — 그런 경우엔 Google 직결 폴백(아래)을 임시로 쓰는 게 합리적일 수 있다. ## 실행 방법 **반드시 `source ~/.env.local &&` 접두사와 함께 실행한다.** ```bash source ~/.env.local && summarize <input> [flags] ``` ## 핵심 사용법 ### 원문/자막만 추출 (요약 없음, LLM 없음) — 기본으로 먼저 시도 ```bash summarize "https://example.com/article" --extract --format md --plain summarize "https://youtu.be/VIDEO_ID" --extract --plain summarize "/path/to/file.pdf" --extract --plain ``` ### YouTube 영상 요약 ```bash summarize "https://www.youtube.com/watch?v=VIDEO_ID" --plain summarize "https://youtu.be/VIDEO_ID" --length long --lang ko --plain ``` YouTube는 자막 우선 추출이 기본이다(`--youtube auto`): `youtubei` API → `captionTracks` → `yt-dlp`(설정 시) → Apify(토큰 있을 시) 순으로 시도한다. 자막이 아예 없어도 `ytInitialPlayerResponse`의 설명(description)으로 최소한의 요약은 시도한다. (요약이 아니라 정본 자막이 목적이면 위 "경계" 절 — `youtube-transcript`로 간다.) ### 웹페이지 요약 / 추출 ```bash summarize "https://example.com/article" --plain summarize "https://example.com/article" --length long --lang ko --plain summarize "https://example.com" --extract --format md --plain ``` ### PDF / 로컬 오디오·비디오 요약 ```bash summarize "/path/to/file.pdf" --plain summarize "/path/to/audio.mp3" --plain summarize "/path/to/video.mp4" --plain ``` (`yt-dlp`, `ffmpeg` 시스템 설치 필요 — 미디어 처리용. 이 두 항목은 문서 확인만 했고 이번 조사에서 직접 오디오/비디오 파일로는 실행하지 않았다 — **미확인**.) ### 팟캐스트 요약 ```bash summarize "https://feeds.example.com/podcast.xml" --plain # RSS summarize "https://podcasts.apple.com/..." --plain # Apple Podcasts summarize "https://open.spotify.com/episode/..." --plain # Spotify ``` (**미확인** — 이번 조사에서 실제 팟캐스트 URL로는 돌려보지 않았다.) ### stdin 파이프 ```bash echo "긴 텍스트..." | summarize - --plain ``` (`--extract`는 stdin 미지원 — `docs/extract-only.md`에 명시. **미확인**: 실제 파이프 실행은 안 해봤다.) ### JSON 출력 (자동화용) ```bash summarize "https://example.com" --json --metrics off > out.json ``` `--json`은 `input`/`env`/`extracted`/`prompt`/`llm`/`metrics`/`summary` 필드를 준다. **주의**: `env` 블록에 `hasOpenRouterKey`/`hasGoogleKey` 등이 노출되지만 실제 키 값은 안 나온다. `llm.calls[].promptTokens/completionTokens`는 있지만 **$ 비용 필드는 JSON 어디에도 없다** — 비용은 사람이 읽는 stderr 푸터에만(그것도 CLI 레일에서만) 뜬다. 비용을 자동으로 추적하려면 토큰 수 × 공시 단가로 직접 계산해야 한다. ## 영상 속 슬라이드/장면 분석 — `--slides` ```bash summarize "https://www.youtube.com/watch?v=..." --slides # 요약 + 인라인 슬라이드 summarize "https://www.youtube.com/watch?v=..." --slides --extract # 전체 트랜스크립트 + 슬라이드 summarize slides "https://www.youtube.com/watch?v=..." --render auto # 슬라이드만, 요약 없음 ``` - 슬라이드 자체 설명 텍스트는 **모델을 안 탄다** — 타임스탬프 근처 트랜스크립트/OCR 텍스트를 그대로 붙인다(`docs/slides.md`: "no model"). 단, `--slides`(요약 모드, `slides` 서브커맨드 아님)로 내러티브를 짤 때는 그 내러티브 자체가 LLM 호출이다. - `yt-dlp` + ffmpeg 필요. 기본 출력 위치 `./slides/<videoId>/`. - `--slides-ocr`는 tesseract 필요. - (**문서 기반 확인, 실행 미확인** — yt-dlp 다운로드 비용/시간 때문에 이번 조사에서 실제 슬라이드 추출은 돌리지 않았다.) ## 화자 분리 / 화자 식별 ```bash summarize "URL" --extract --diarize # 화자 라벨만 summarize "URL" --extract --diarize elevenlabs --identify-speakers \ --speaker-profile PROFILE --speaker-at "0:12=이름" --remember-speakers ``` `--diarize`는 ElevenLabs(기본, `ELEVENLABS_API_KEY` 필요) → OpenAI 순. 화자 이름 매핑은 `~/.summarize/config.json`의 `speakers.profiles`에 저장/재사용된다. (**문서 기반, 실행 미확인** — 우리 환경에 `ELEVENLABS_API_KEY` 없음, 테스트 안 함.) ## 구독 CLI 레일 — `--cli` 기본 레일이 `cli/claude/sonnet`이므로 config를 그대로 두면 `--cli` 플래그 없이도 이걸 쓴다. 다른 CLI로 일시적으로 바꾸고 싶을 때만 명시: ```bash summarize "URL" --cli claude --plain # config 기본값과 동일 레일 summarize "URL" --cli codex --plain # 미실행(구독 쿼터 아끼기 위해 이번엔 안 돌림) ``` `summarize status`로 뭐가 살아있는지 확인: ``` Claude CLI: available Codex CLI: available Cursor Agent CLI: available GitHub Copilot CLI: available Antigravity CLI: available Pi CLI: available ``` 전부 "쓸 수 있음"이지 전부 "써도 되는 레일"은 아니다 — AGENTS.md가 정한 승인 레일(기존 Claude Code 구독, pi의 GPT/Codex, xAI, Z.AI)만 쓴다. `openrouter/*`는 이 목록에 없다. `--cli`는 계량 과금이 아니라 **구독 쿼터**를 먹는다. 위 "레일 선택" 절에서 확인했듯 이 오버헤드는 summarize를 거치든 손파이프를 짜든 피할 수 없는 Claude CLI 하네스 비용이다 — 대량 요약 루프를 자주 돌린다면 그만큼 형제들의 5h/7d 윈도우를 같이 쓰는 셈이니 계획해서 쓴다. ## 캐시 ```bash summarize --cache-stats # 캐시 크기/항목 수 확인 (실측: 40KB, entries=9) summarize --clear-cache # 캐시 DB 삭제 ``` - 요약/추출/트랜스크립트/슬라이드 각각 SQLite에 캐시됨(`~/.summarize/cache.sqlite`, 기본 512MB/30일). 미디어(yt-dlp 다운로드)는 별도 파일 캐시(`~/.summarize/cache/media`, 2GB/7일). - `--no-cache`는 **요약(LLM) 캐시만** 우회한다 — 추출/트랜스크립트 캐시는 그대로 적용됨. 미디어 다운로드 캐시를 끄려면 `--no-media-cache`. - **같은 URL을 반복 요약하면 두 번째부터는 캐시 히트라 사실상 무료다** — contentHash 기반이라 URL이 달라도 내용이 같으면 캐시가 맞는다. ## Preset / 모델별 규칙 `~/.summarize/config.json`의 `models` 블록으로 이름 붙인 프리셋을 만들 수 있다: ```json { "models": { "fallback": { "id": "google/gemini-3-flash-preview" } }, "model": "cli/claude/sonnet" } ``` `model.mode: "auto"` + `rules`로 콘텐츠 종류/토큰 길이별 후보 목록을 직접 정의할 수도 있다 — 하지만 위에서 확인했듯 **기본 내장 규칙(`DEFAULT_RULES`)은 지금 우리 키에서 깨져 있고 OpenRouter로 새는 경로가 있다.** 커스텀 auto 규칙을 쓰더라도 candidates 목록에 `openrouter/*`가 들어가지 않게 직접 확인할 것. (우리는 이 기능 자체를 안 쓰고 `model.id` 고정만 쓴다 — 그게 맞는 선택이었다.) ## 주요 플래그 (실측/`--help` 확인) | 플래그 | 설명 | 기본값 |
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub