transcribe-summarize은(는) 무엇을 하나요?
오디오를 입력하면 전사본이 출력되고, 선택적으로 회의 노트도 생성됩니다. 기본 경로는 사용자의 기기에서 전체 처리를 실행합니다.
이 도구가 직접 Whisper를 호출하는 것과 다른 점은 두 가지이며, 설계보다는 측정 결과에서 비롯되었습니다:
- Whisper는 무음 구간에서 가상 발화를 생성하며, 더 큰 모델이 도움이 되지 않습니다. 실제 통화에서 40초의 접속 무음 구간 동안
large-v3는 한 단어를 55회 반복하는 18초 분량의 세그먼트를 생성했습니다. 이 스킬은 이러한 세그먼트를 필터링하고, 필터링된 이유와 측정 지표를 사이드카 파일에 보관하여 결정 내용을 감사 가능하게 만듭니다. - 오디오 정리가 모델 선택보다 효과적입니다. 정규화 및 무음 제거를 통해 가상 세그먼트가 2개에서 0개로 줄었고,
large-v3와turbo모두 잘못 인식한 단어를 수정했습니다. 이 기능은 기본적으로 활성화되어 있습니다.
설정
ffmpeg와 ffprobe가 PATH에 있어야 합니다 — macOS brew install ffmpeg, Windows winget install Gyan.FFmpeg, Linux apt install ffmpeg.
나머지는 모두 표준 라이브러리입니다. 백엔드는 자체 라이브러리를 가져오며, 선택한 백엔드만 가져오므로 uv run --with로 선택하세요:
| 백엔드 | 플랫폼 | --with 명세 |
|---|---|---|
mlx-whisper — Apple Silicon 기본값 | macOS arm64 전용 | 'mlx-whisper>=0.4.2' |
faster-whisper — 그 외 기본값 | mac / Windows / Linux | 'faster-whisper>=1.2' |
parakeet — 선택 사항 | Apple Silicon 확인됨 | 'parakeet-mlx' |
groq, openai, elevenlabs, gemini — 선택 사항, 네트워크 | 모든 OS | 설치할 항목 없음 |
라이브러리가 없으면 오류 메시지에 정확한 명령어가 출력됩니다. 추측하지 마세요.
실행
모든 명령 블록 상단에 헬퍼를 선언하세요 — 셸 상태는 도구 호출 간에 유지되지 않습니다:
ts() {
UV="$(command -v uv || ls "$HOME/.local/bin/uv" "$HOME/.cargo/bin/uv" \
/opt/homebrew/bin/uv /usr/local/bin/uv 2>/dev/null | head -1)"
"$UV" run --with "$1" --script "$HOME/.claude/skills/transcribe-summarize/scripts/transcribe.py" "${@:2}"
}
# Apple Silicon
ts 'mlx-whisper>=0.4.2' meeting.m4a
# Windows / Linux
ts 'faster-whisper>=1.2' meeting.m4a --backend faster-whisper
# 알려진 전문 용어에 디코더 편향 적용 및 항상 틀리는 이름 수정
ts 'mlx-whisper>=0.4.2' meeting.m4a --prompt 'Terragrunt, EKS' --replace 'north wind=Northwind'
절대 경로를 사용하세요. 상대 경로는 현재 작업 디렉토리가 스킬 디렉토리인 경우에만 해석됩니다.
출력 규약
<outdir>/
<stem>.md 전사본, [hh:mm:ss] 앵커 포함
<stem>-artifacts/
<stem>.srt 자막
<stem>.json 모든 세그먼트 (억제된 세그먼트 포함)
<stem>.run.json 백엔드, 모델, 트림 오프셋, 가드 집계
--json은 해당 경로를 JSON으로 stdout에 출력합니다. 사용자에게 절대 경로를 알려주세요; 찾아야 하는 파일은 결과물이 아닙니다.
타임스탬프는 원본 녹음의 클럭을 기준으로 합니다. 트리밍은 디코딩 중에 오디오를 단축시키며, 오프셋은 기록 전에 다시 매핑되므로 .srt가 사용자의 원본 파일과 일치합니다.
네트워크 규칙 — 명시한 후 준수
네트워크 백엔드는 사용자가 해당 호출에서 명시적으로 요청할 때만 접근 가능합니다. 절대 대체 수단으로 사용하지 않으며, 로컬 백엔드 실패 후에도, 더 빠르다고 해도 사용하지 않습니다. --backend auto는 네트워크 백엔드에 도달할 수 없습니다; 해당 코드 경로가 없습니다.
전송 전에 도구는 제공자, 엔드포인트, 파일 크기, 지속 시간 및 예상 비용을 출력한 후 대기합니다. --dry-run을 사용하여 커밋 전에 해당 블록을 사용자에게 보여주세요. 비대화형 세션에서는 확인되지 않은 업로드가 거부됩니다.
키는 환경 변수(백엔드당 하나)에서만 가져오며, 다른 곳에서는 가져오지 않습니다. 플래그로 키를 받거나, 에코하거나, 파일에 기록하지 마세요.
| 백엔드 | 키 | 모델 | $/시간 | 화자 분리 |
|---|---|---|---|---|
groq | GROQ_API_KEY | whisper-large-v3-turbo | 0.04 | 아니오 |
groq | GROQ_API_KEY | whisper-large-v3 (기본값) | 0.111 | 아니오 |
elevenlabs | ELEVENLABS_API_KEY | scribe_v2 | 0.22 | 최대 32명 |
gemini | GEMINI_API_KEY | gemini-3.5-transcribe | 0.306 | 최대 3명 |
openai | OPENAI_API_KEY | whisper-1 | 0.36 | 아니오 |
--backend gemini — 실행 전에 알아야 할 두 가지
ts '' /path/to/audio.m4a --backend gemini --dry-run # 블록 표시, 전송 안 함
ts '' /path/to/audio.m4a --backend gemini # 그런 다음 실행
설치할 항목이 없습니다 — 표준 라이브러리 http.client를 사용하므로 --with 인수는 비어 있습니다. 실행 전에 사용자에게 말해야 할 두 가지 사실이 있습니다. 명령줄에서 볼 수 없기 때문입니다:
- 오디오가 두 번 업로드됩니다. Gemini에는 단일 샷 엔드포인트가 없습니다: 파일이 먼저 Google의 Files API로 전송되고, 전사 요청은 반환된 URI만 전달합니다. Google은 해당 업로드를 48시간 동안 보관합니다. 공개 블록에 이 내용이 출력되므로 건너뛰지 마세요.
- 30분이 상한선이며, Google 자체 페이지에서 제시하는 1시간이 아닙니다. 1시간은 단어 타임스탬프나 화자 분리 없이 사용할 때만 적용되며, 이 백엔드는 항상 둘 다 요청합니다 — 단어 오프셋 없이는 사용자 파일에 다시 매핑할 클럭이 없기 때문입니다. 더 긴 녹음은 업로드 시작 전에 거부됩니다.
Gemini의 smart 모드를 제공하지 마세요. 의도적으로 연결되어 있지 않습니다. 사용자가 요청하는 경우 — 해당 모델의 주요 기능이며, 필러 단어를 제거하고 음성 자체 수정을 다시 작성합니다 — 답변은 Google의 API가 이와 함께 단어 타임스탬프와 화자 레이블을 거부하므로 .srt와 화자가 생성되지 않으며, 단어가 변경된다는 것입니다. 필러 제거는 대신 노트 단계에서 수행되며, 요약으로 레이블이 지정되고 확인됩니다. references/backends.md를 참조하세요.
품질 가드
기본적으로 활성화됩니다. 억제된 세그먼트는 이유와 측정 지표와 함께 .json에 남고, .md 및 .srt에서는 제외됩니다. --guard mark는 인라인에 플래그를 유지하고, --guard off는 비활성화합니다.
모든 백엔드로 전송되지는 않습니다. 강력한 규칙은 Whisper 디코더 측정 지표를 읽습니다. faster-whisper, Groq 및 OpenAI는 세 가지를 모두 반환하므로 가드는 동일한 코드를 사용합니다. Parakeet, ElevenLabs 및 Gemini는 그 중 어떤 것도 반환하지 않으며 백엔드 독립적 규칙만 사용합니다 — 도구는 실행 시 이를 알립니다. references/backends.md를 참조하세요.
사용자가 전사본의 특정 부분이 누락된 이유를 묻는 경우 .json을 읽으세요: 해당 부분을 제거하게 만든 수치와 함께 답이 있습니다.
이미 있는 전사본에서 시작하기
대부분의 회의는 이미 플랫폼에서 전사되었으며, 오디오가 전혀 없는 경우가 많습니다. Teams와 Zoom은 .vtt(때로는 .srt)를 제공하며, 이를 산문으로 읽기 어렵습니다: 몇 초마다 큐가 있고, 문장이 큐 사이에서 잘리고, 화자 이름이 모든 줄에 반복되며, 타임코드가 전체에 포함됩니다.
이는 지원되는 진입점입니다. 재전사되지 않습니다 — 오디오 경로를 완전히 건너뜁니다:
"$HOME/.claude/skills/transcribe-summarize/scripts/normalise_transcript.py" meeting.vtt
# -> meeting.md, 큐가 문단으로 재결합, 화자 귀속, 문단당 하나의 앵커
그런 다음 여기서 디코딩된 것과 정확히 동일하게 진행합니다: 읽고, 회의 사실을 요청하고, references/notes-register.md 아래에 노트를 작성합니다.
--no-speakers는 소스 레이블이 잘못되었거나 원치 않는 경우 귀속을 제거합니다.
형식 변환일 뿐이며 그 이상은 아닙니다. 단어가 변경되지 않고, 필러가 제거되지 않으며, 문법이 수정되지 않습니다. 무슨 말이 있었는지 결정하는 것은 요약 단계이며 자체 규칙이 있습니다. 사용자가 지저분한 전사본을 건네며 "정리"해 달라고 요청하면 여기서 형식을 정규화하고 노트에서 판단을 수행하세요 — 기록해야 하는 문서에서 누군가의 말을 조용히 다시 쓰지 마세요.
화자는 전사본에 유지되며 노트에서는 금지됩니다. 이는 모순이 아닙니다: 전사본은 작업 산출물이며 출처를 포함할 수 있습니다; 노트는 기록이며 포함할 수 없습니다. notes_check.py는 노트에 원시 Speaker 2 레이블이 있으면 여전히 거부합니다.
누군가 .vtt를 transcribe.py에 전달하면 디코딩을 시도하지 않고 여기서 중단하고 이 지점을 가리킵니다.
비디오 파일
.mp4는 Teams나 Zoom 다운로드의 실제 형식이며 직접 작동합니다 — 오디오를 먼저 추출할 필요가 없습니다. 확인된 작동 형식: .mp4, .mov, .mkv, .webm 및 모든 오디오 컨테이너 (.m4a, .mp3, .wav, .flac, .opus). ffmpeg가 오디오 트랙을 추출하며, 비디오는 무시되고 업로드되지 않습니다.
오디오 트랙이 없는 파일(음소거된 화면 녹화)은 네트워크 백엔드에 제공되기 전에 미리 거부됩니다. 이 검사는 특히 무음 비디오가 업로드되어 비용이 청구되지 않도록 송신 게이트 전에 실행됩니다.
검토는 선택 사항이 아닌 단계입니다
전사 출력은 초안입니다. 그렇게 말하고 사용자가 확인하도록 하세요.
기계 전사는 어떤 임계값도 잡아내지 못할 정도로 확실하게 잘못될 수 있습니다. 이 프로젝트에서 실제 오디오로 측정한 결과: large-v3는 화자의 숫자 음성 수정을 조용히 누락시켰고, 모든 백엔드는 "board pack"을 "board packs up"으로 잘못 들었습니다. 둘 다 완벽하게 유창하게 읽힙니다. 품질 가드는 무음 구간의 가상 발화를 잡아내지만, 그럴듯한 오청을 잡아낼 수는 없으며, 출력을 읽는 것만으로는 잡아낼 수 없습니다.
따라서 워크플로는 전사 → 사용자 확인 → 노트입니다:
- 전사본
.md는 "확인할 가치가 있는 항목" 섹션으로 끝납니다 — 다시 듣는 것이 가장 효과적일 가능성이 높은 타임스탬프 순위(가장 낮은 신뢰도의 세그먼트, 숫자가 포함된 모든 항목). 사용자에게 명시적으로 지적하세요. - 이름, 숫자 및 날짜가 확인할 사항입니다. 이들은 가장 먼저 저하되고 기록에서 잘못될 때 가장 비용이 많이 드는 항목입니다.
- 수정 사항은 재실행 시 수동으로 또는
--replace를 사용하여.md에 입력합니다. 그런 다음 이를 기반으로 구축된 모든 것을 다시 생성합니다.
전사본이나 노트 세트를 확인된 것으로 제시하지 마세요. 당신은 오디오를 듣지 않았습니다; 사용자가 들었습니다. 디코딩된 내용을 말하고, 가장 불확실한 부분을 알려주며, 확인하도록 하세요.
편집 및 재생성
.md가 소스입니다. 편집한 후 PDF를 재빌드하세요 — 재전사 불필요:
"$HOME/.claude/skills/transcribe-summarize/scripts/notes_check.py" notes.md
"$HOME/.claude/skills/transcribe-summarize/scripts/render_pdf.py" notes.md
편집 후에는 항상 검사기를 다시 실행하세요. 수동 편집은 정확히 출처 누출이나 추론된 "다음 단계" 줄이 도입되는 시점입니다.
노트 작성
사용자가 전사본 대신 회의 노트를 원할 경우, 당신이 작성합니다 — 전사본을 읽고 직접 문서를 생성합니다. scripts/summarize.py 대체 스크립트가 네트워크 모델을 호출하지만, 이는 Claude Code 세션 외부에서 이 파이프라인을 실행하기 위한 것입니다; 세션 내에서는 무의미한 업로드입니다.
먼저 물어보세요 — 오디오가 알려줄 수 없는 세 가지
여기 있는 거의 모든 백엔드는 화자를 식별하지 않습니다. 모든 Whisper 엔진과 Parakeet는 화자 필드를 전혀 반환하지 않습니다. 두 가지 예외: --backend elevenlabs (Scribe)는 최대 32명의 화자를 분리하고, --backend gemini는 최대 3명입니다. 둘 다 이름 대신 위치 레이블을 반환합니다 — 각각 speaker_0 및 spk:0 형식(2026-09-04 및 2026-09-06의 실제 응답에서 측정된 형식)이며, 등록 규정에 따라 노트 문서에서 원시 레이블을 금지합니다. 따라서 몇 명이 말했는지와 어떤 줄이 함께 속하는지는 알려주지만, 누구인지는 알려주지 않습니다. 귀속은 어느 쪽이든 사용자에게서 옵니다; 화자 분리는 기억 대신 전사본에서 매핑을 가능하게 할 뿐입니다.
노트를 작성하기 전에 다음을 물어보세요:
- 누가 참석했는지. 이름이 없으면 귀속 없이 노트를 작성하세요 — 비인칭으로, "다음과 같이 진술되었습니다…". 이름, 역할 또는 위치 레이블을 절대 임의로 만들지 마세요. 전사본에서 누가 말했는지 명확한 경우(누군가 이름으로 호명되는 경우) 귀속할 수 있습니다; 모호함은 이름 없음을 의미합니다.
- 회의 날짜. 오늘 날짜는 기본값일 뿐, 사실이 아닙니다. 오디오는 종종 대화 후 며칠 후에 작성되며, 사실 기록에 잘못된 날짜는 날짜가 없는 것보다 더 나쁩니다. 확인하세요.
- 회의의 성격 — 참가자 자신의 용어로 된 제목.
세 가지를 한 번에 하나씩이 아닌 하나의 메시지로 물어보고, 오늘 날짜를 기본값으로 제공하여 사용자가 수정만 하면 되도록 하세요. 사용자가 참석자 제공을 거부하면 귀속 없이 진행하고 그렇게 했다고 말하세요.
한 줄이라도 쓰기 전에 references/notes-register.md를 읽으세요. 짧고 전체 명세입니다. 스타일 조언이 아닙니다; 그 안의 규칙은 실제 문서에서 섹션이 수동으로 삭제된 경험을 통해 배운 것이며, 그 이유는 미학보다 법적입니다.
적용되는 두 가지 규칙:
- 사실적 요약만. 말해진 내용. 분석 없음, 함의 없음, "다음 단계" 없음, "다루지 않은 내용" 없음, 공백 채우기 없음.
- 현장에 있었던 사람이 작성한 의사록처럼 읽혀야 합니다. 녹음, 전사본, 오디오, 모델 또는 디코더 산출물(타임코드,
Speaker 2레이블)을 언급하지 않습니다.
그런 다음 매번 검사하세요 — 등록 규정은 자체 집행되지 않으며, 요약하라는 요청을 받은 모델은 프롬프트 없이 분석을 추가합니다:
"$HOME/.claude/skills/transcribe-summarize/scripts/notes_check.py" notes.md
종료 코드 0은 깨끗함; 종료 코드 1은 모든 위반에 대해 file:line을 나열합니다. 문서를 전달하기 전에 수정하세요. PDF에서도 실행하세요 — 렌더링된 파일에만 존재하는 누출도 여전히 문제입니다.
지침은 환영하지만, 노트 이후에 그리고 문서 외부에서 제공하세요. 대화 중이거나 별도 파일에 분석 내용을 제공하세요. 절대 노트에 추가하지 마세요.
"$HOME/.claude/skills/transcribe-summarize/scripts/render_pdf.py" notes.md
Headless Chrome, Chromium 또는 Edge가 자동으로 발견됩니다. 설치된 것이 없으면 HTML을 작성하고, 그렇게 말한 후 종료 코드 0으로 종료합니다 — HTML도 결과물입니다.
출처
로컬 디코딩은 mlx-whisper (MLX) 또는 faster-whisper (CTranslate2); 오디오 준비는 ffmpeg입니다. 네트워크 백엔드는 표준 라이브러리 urllib를 통해 Groq 및 OpenAI의 전사 엔드포인트를 직접 호출합니다 — 공급업체 SDK 없음.
노트 문서에서 출처를 제외하면 문서가 말하는 내용이 변경될 뿐, 실제로 일어난 일은 변경되지 않습니다. 동의 없이 통화를 녹음하는 것은 형사 범죄입니다...