Was macht transcribe-summarize?
Audio rein, Transkript raus, und optional Besprechungsnotizen. Der Standardpfad läuft vollständig auf dem Rechner des Benutzers.
Zwei Dinge unterscheiden dies von einem direkten Whisper-Aufruf, und beide entstanden aus einem Tag voller Messungen statt Design:
- Whisper erfindet Sprache über Stille, und ein größeres Modell hilft nicht. Bei einem echten Gespräch mit 40 s Stille zu Beginn erzeugte
large-v3ein 18-Sekunden-Segment mit einem 55-mal wiederholten Wort. Diese Skill filtert solche Segmente heraus, behält sie aber – zusammen mit den Metriken, die zu ihrer Ablehnung führten – in einer Begleitdatei, sodass die Entscheidung nachvollziehbar bleibt. - Die Audiobereinigung ist wichtiger als die Modellwahl. Normalisierung und Stille-Trimmen reduzierten erfundene Segmente von 2 auf 0 und korrigierten ein Wort, das sowohl
large-v3als auchturbofalsch hatten. Diese Bereinigung ist standardmäßig aktiviert.
Einrichtung
ffmpeg und ffprobe müssen im PATH sein – macOS brew install ffmpeg, Windows winget install Gyan.FFmpeg, Linux apt install ffmpeg.
Alles andere ist stdlib. Das Backend bringt seine eigene Bibliothek mit, und zwar nur das ausgewählte. Wählen Sie es mit uv run --with:
| Backend | Plattform | --with-Angabe |
|---|---|---|
mlx-whisper – Standard auf Apple Silicon | macOS arm64 nur | 'mlx-whisper>=0.4.2' |
faster-whisper – Standard sonst | mac / Windows / Linux | 'faster-whisper>=1.2' |
parakeet – optional | Apple Silicon verifiziert | 'parakeet-mlx' |
groq, openai, elevenlabs, gemini – optional, Netzwerk | alle | nichts zu installieren |
Fehlt die Bibliothek, wird im Fehler der genaue Befehl ausgegeben. Nicht raten.
Ausführen
Deklarieren Sie den Helfer am Anfang jedes Befehlsblocks – der Shell-Zustand bleibt zwischen Tool-Aufrufen nicht erhalten:
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
# Decoder in Richtung bekannter Fachbegriffe lenken und einen immer falschen Namen korrigieren
ts 'mlx-whisper>=0.4.2' meeting.m4a --prompt 'Terragrunt, EKS' --replace 'north wind=Northwind'
Verwenden Sie den absoluten Pfad. Ein relativer Pfad wird nur aufgelöst, wenn das aktuelle Arbeitsverzeichnis zufällig das Skill-Verzeichnis ist.
Ausgabe-Kontrakt
<ausgabeverz>/
<stamm>.md das Transkript mit [hh:mm:ss]-Ankern
<stamm>-artifacts/
<stamm>.srt Untertitel
<stamm>.json jedes Segment, einschließlich der unterdrückten
<stamm>.run.json Backend, Modell, Trim-Offsets, Guard-Zählung
--json gibt diese Pfade als JSON auf stdout aus. Melden Sie dem Benutzer absolute Pfade; eine Datei, die gesucht werden muss, ist kein Ergebnis.
Die Zeitstempel beziehen sich auf die Uhr der Originalaufnahme. Das Trimmen verkürzt das Audio während der Dekodierung, und die Offsets werden vor dem Schreiben zurückgerechnet, sodass die .srt mit der Datei des Benutzers synchron ist.
Die Netzwerkregel – benennen, dann befolgen
Ein Netzwerk-Backend ist nur erreichbar, wenn der Benutzer es in diesem Aufruf explizit anfordert. Niemals als Fallback, niemals nachdem ein lokales Backend fehlgeschlagen ist, niemals weil es schneller wäre. --backend auto kann keines erreichen; es gibt keinen Codepfad dorthin.
Bevor etwas gesendet wird, gibt das Tool Anbieter, Endpunkt, Dateigröße, Dauer und geschätzte Kosten aus und wartet dann. Verwenden Sie --dry-run, um dem Benutzer diesen Block vor der Ausführung zu zeigen. In einer nicht-interaktiven Sitzung wird ein nicht bestätigter Upload abgelehnt.
Schlüssel kommen aus der Umgebung, eine Variable pro Backend, und nirgendwo anders. Akzeptieren Sie niemals einen als Flagge, geben Sie niemals einen aus, schreiben Sie niemals einen in eine Datei.
| Backend | Schlüssel | Modell | $/Stunde | Diarisiert |
|---|---|---|---|---|
groq | GROQ_API_KEY | whisper-large-v3-turbo | 0.04 | nein |
groq | GROQ_API_KEY | whisper-large-v3 (Standard) | 0.111 | nein |
elevenlabs | ELEVENLABS_API_KEY | scribe_v2 | 0.22 | bis zu 32 |
gemini | GEMINI_API_KEY | gemini-3.5-transcribe | 0.306 | bis zu 3 |
openai | OPENAI_API_KEY | whisper-1 | 0.36 | nein |
--backend gemini – die zwei Dinge, die Sie vor der Ausführung sagen sollten
ts '' /pfad/zu/audio.m4a --backend gemini --dry-run # Block anzeigen, nichts senden
ts '' /pfad/zu/audio.m4a --backend gemini # dann ausführen
Nichts zu installieren – es ist stdlib http.client, daher ist das --with-Argument leer. Zwei Fakten gehören in den Satz, den Sie dem Benutzer vor der Ausführung sagen, da keiner von der Befehlszeile aus sichtbar ist:
- Das Audio wird zweimal hochgeladen. Gemini hat keinen Single-Shot-Endpunkt: Die Datei geht zuerst an die Google Files API, und die Transkriptionsanfrage enthält dann nur den zurückgegebenen URI. Google behält diesen Upload 48 Stunden lang. Der Offenlegungsblock gibt dies aus; überspringen Sie ihn nicht.
- 30 Minuten sind die Obergrenze, nicht die Stunde, die Googles eigene Seite angibt. Die Stunde gilt nur ohne Wortzeitstempel oder Diarisierung, und dieses Backend fordert immer beides an – ohne Wortoffsets gibt es keine Uhr, die auf die Datei des Benutzers zurückgerechnet werden kann. Eine längere Aufnahme wird vor dem Upload abgelehnt.
Bieten Sie Geminis smart-Modus nicht an. Er ist bewusst nicht verdrahtet. Wenn der Benutzer danach fragt – es ist das Herzstück des Modells, das Füllwörter entfernt und gesprochene Selbstkorrekturen umschreibt – lautet die Antwort, dass Googles API in diesem Fall keine Wortzeitstempel und Sprecherkennungen liefert, sodass keine .srt und keine Sprecher erzeugt würden, und dass es die Wörter verändert. Die Entfernung von Füllwörtern erfolgt stattdessen im Notizen-Schritt, wo sie als Zusammenfassung gekennzeichnet und geprüft wird. Siehe references/backends.md.
Die Qualitätssicherung
Standardmäßig aktiviert. Unterdrückte Segmente bleiben mit Grund und Metriken in der .json; sie werden aus der .md und .srt entfernt. --guard mark belässt sie inline markiert, --guard off deaktiviert sie.
Sie wird nicht auf jedes Backend übertragen. Die strengen Regeln lesen Whisper-Decoder-Metriken. faster-whisper, Groq und OpenAI geben alle drei zurück, daher verwendet die Sicherung denselben Code. Parakeet, ElevenLabs und Gemini geben keine davon zurück und fallen nur auf die backend-unabhängigen Regeln zurück – das Tool teilt dies zur Laufzeit mit. Siehe references/backends.md.
Wenn der Benutzer fragt, warum ein Teil des Transkripts fehlt, lesen Sie die .json: Die Antwort steht dort mit den Zahlen, die dazu geführt haben.
Starten mit einem vorhandenen Transkript
Die meisten Besprechungen werden bereits von der Plattform transkribiert, und oft gibt es gar kein Audio. Teams und Zoom geben eine .vtt (manchmal .srt) aus, und sie ist als Prosa unlesbar: alle paar Sekunden ein Cue, Sätze über Cues hinweg zerschnitten, der Name des Sprechers in jeder Zeile wiederholt, überall Zeitcodes.
Das ist ein unterstützter Einstiegspunkt. Es wird nichts neu transkribiert – der Audio-Pfad wird vollständig übersprungen:
"$HOME/.claude/skills/transcribe-summarize/scripts/normalise_transcript.py" meeting.vtt
# -> meeting.md, Cues zu Absätzen zusammengefügt, Sprecher zugeordnet, ein Anker pro Absatz
Fahren Sie dann genau so fort, als ob das Transkript hier dekodiert worden wäre: Lesen Sie es, fragen Sie nach den Besprechungsdetails und schreiben Sie die Notizen unter references/notes-register.md.
--no-speakers entfernt die Zuordnung, wenn die Quellbezeichnungen falsch oder unerwünscht sind.
Es ist eine Formatkonvertierung und nichts weiter. Es werden keine Wörter geändert, keine Füllwörter entfernt, keine Grammatik korrigiert. Die Entscheidung, was gesagt wurde, ist der Schritt der Zusammenfassung und hat eigene Regeln. Wenn ein Benutzer Ihnen ein unordentliches Transkript gibt und um „Aufräumen“ bittet, normalisieren Sie hier das Format und treffen Sie das Urteil in den Notizen – schreiben Sie nicht stillschweigend die Worte einer Person in einem Dokument um, das sie aufzeichnen soll.
Sprecher werden im Transkript behalten und in den Notizen verboten, was kein Widerspruch ist: Ein Transkript ist ein Arbeitsdokument und kann Herkunftsinformationen enthalten; die Notizen sind ein Protokoll und dürfen das nicht. notes_check.py wird eine rohe Speaker 2-Bezeichnung in den Notizen dennoch ablehnen.
Wenn jemand eine .vtt an transcribe.py übergibt, stoppt das Skript und verweist hierher, anstatt zu versuchen, sie zu dekodieren.
Videodateien
.mp4 ist, was ein Teams- oder Zoom-Download tatsächlich ist, und funktioniert direkt – keine Notwendigkeit, das Audio vorher zu extrahieren. Verifiziert funktionierend: .mp4, .mov, .mkv, .webm, plus alle Audio-Container (.m4a, .mp3, .wav, .flac, .opus). ffmpeg extrahiert die Audiospur; das Video wird ignoriert und niemals hochgeladen.
Eine Datei ohne Audiospur – eine stummgeschaltete Bildschirmaufnahme – wird sofort abgelehnt, bevor sie einem Netzwerk-Backend angeboten wird. Diese Prüfung läuft vor der Ausgangssperre, damit eine stumme Videodatei niemals hochgeladen und berechnet wird.
Die Überprüfung ist ein Schritt, kein optionales Extra
Die Transkriptionsausgabe ist ein Entwurf. Sagen Sie das, und lassen Sie den Benutzer sie überprüfen.
Maschinelle Transkription ist selbstbewusst falsch auf eine Weise, die kein Schwellenwert abfängt. Gemessen an realem Audio in diesem Projekt: large-v3 ließ die gesprochene Korrektur einer Zahl durch einen Sprecher stillschweigend weg, und jedes Backend hörte „board pack“ als „board packs up“. Beide lesen sich vollkommen flüssig. Die Qualitätssicherung fängt Erfindungen über Stille auf; sie kann kein plausibles Fehlhören auffangen, und Sie können das auch nicht, indem Sie die Ausgabe lesen.
Daher ist der Arbeitsablauf transkribieren → Benutzer überprüft → dann Notizen:
- Die Transkript-
.mdendet mit einem Abschnitt „Prüfenswert“ – mit Zeitleisten, bei denen ein Rückhören am ehesten lohnt (unsicherste Segmente, alles mit Zahlen). Weisen Sie den Benutzer explizit darauf hin. - Namen, Zahlen und Daten sind zu überprüfen. Sie sind das Erste, was nachlässt, und das Teuerste, was in einem Protokoll falsch sein kann.
- Korrekturen werden in die
.mdeingetragen, von Hand oder mit--replacebei einem erneuten Durchlauf. Dann regenerieren Sie alles, was daraus erstellt wurde.
Präsentieren Sie niemals ein Transkript oder einen Satz Notizen als verifiziert. Sie haben das Audio nicht gehört; der Benutzer schon. Sagen Sie, was dekodiert wurde, sagen Sie, wo es am unsichersten ist, und lassen Sie den Benutzer bestätigen.
Bearbeiten und Regenerieren
Die .md ist die Quelle. Bearbeiten Sie sie, dann bauen Sie das PDF neu – keine erneute Transkription:
"$HOME/.claude/skills/transcribe-summarize/scripts/notes_check.py" notes.md
"$HOME/.claude/skills/transcribe-summarize/scripts/render_pdf.py" notes.md
Führen Sie die Prüfung nach jeder Bearbeitung erneut aus. Handbearbeitung ist genau der Moment, in dem ein Herkunftsverlust oder eine erschlossene „nächste Schritte“-Zeile eingeführt wird.
Die Notizen schreiben
Wenn der Benutzer Besprechungsnotizen und nicht nur ein Transkript wünscht, schreiben Sie sie – lesen Sie das Transkript und erstellen Sie das Dokument selbst. Es gibt ein Fallback-Skript scripts/summarize.py, das ein Netzwerkmodell aufruft, aber es ist für die Ausführung dieser Pipeline außerhalb einer Claude Code-Sitzung gedacht; innerhalb einer solchen ist es ein nutzloser Upload.
Fragen Sie zuerst – drei Dinge, die das Audio Ihnen nicht sagen kann
Fast kein Backend hier identifiziert Sprecher. Jede Whisper-Engine und Parakeet geben kein Sprecherfeld zurück. Zwei Ausnahmen: --backend elevenlabs (Scribe) diarisiert bis zu 32 Sprecher, und --backend gemini bis zu 3. Beide geben Positionsbezeichnungen zurück, keine Namen – speaker_0 bzw. spk:0, die Formate, die aus Live-Antworten vom 04.09.2026 und 06.09.2026 gemessen wurden – und das Register verbietet eine rohe Bezeichnung in einem Notizendokument, in beiden Formaten. Sie sagen Ihnen also, wie viele Personen gesprochen haben und welche Zeilen zusammengehören; sie können Ihnen dennoch nicht sagen, wer es war. Die Zuordnung kommt in beiden Fällen vom Benutzer; die Diarisierung macht die Zuordnung nur anhand des Transkripts statt aus dem Gedächtnis möglich.
Bevor Sie Notizen schreiben, fragen Sie nach:
- Wer anwesend war. Ohne Namen schreiben Sie die Notizen ohne jede Zuordnung – unpersönlich, „es wurde festgestellt, dass …“. Erfinden Sie niemals einen Namen, eine Rolle oder eine Positionsbezeichnung. Wenn aus dem Transkript offensichtlich ist, wer gesprochen hat (jemand wird namentlich angesprochen), dürfen Sie das zuordnen; bei Unklarheit kein Name.
- Das Datum der Besprechung. Das heutige Datum ist ein Standardwert, keine Tatsache. Audio wird oft Tage nach dem Gespräch aufgeschrieben, und ein falsches Datum in einem Tatsachenprotokoll ist schlimmer als gar keins. Bestätigen Sie es.
- Was die Besprechung war – ein Titel in den eigenen Worten der Teilnehmer.
Fragen Sie nach allen drei in einer einzigen Nachricht, nicht einzeln, und bieten Sie das heutige Datum als Standard an, damit der Benutzer es nur korrigieren muss. Wenn der Benutzer die Angabe von Teilnehmern ablehnt, fahren Sie ohne Zuordnung fort und sagen Sie, dass Sie das getan haben.
Bevor Sie eine einzige Zeile schreiben, lesen Sie references/notes-register.md. Es ist kurz und enthält die vollständige Spezifikation. Es ist kein Stilratschlag; die darin enthaltenen Regeln wurden gelernt, indem Abschnitte von Hand aus einem echten Dokument gelöscht wurden, und die Gründe sind rechtlicher und nicht ästhetischer Natur.
Die zwei Regeln, die es aktiviert:
- Nur sachliche Zusammenfassung. Was gesagt wurde. Keine Analyse, keine Implikationen, keine „nächsten Schritte“, kein „was nicht behandelt wurde“, keine Füllung von Lücken.
- Es liest sich wie eine Protokollaufzeichnung von jemandem, der dabei war. Es erwähnt niemals eine Aufnahme, ein Transkript, Audio, ein Modell oder ein Dekodierungsartefakt – keine Zeitcodes, keine
Speaker 2-Bezeichnungen.
Prüfen Sie es dann jedes Mal – das Register setzt sich nicht selbst durch, und ein Modell, das um eine Zusammenfassung gebeten wird, wird unaufgefordert Analyse hinzufügen:
"$HOME/.claude/skills/transcribe-summarize/scripts/notes_check.py" notes.md
Exit 0 ist sauber; Exit 1 listet datei:zeile für jede Verletzung auf. Beheben Sie diese, bevor Sie das Dokument übergeben. Führen Sie es auch für das PDF aus – ein Verlust, der nur in der gerenderten Datei existiert, zählt immer noch.
Hinweise sind willkommen, aber nach den Notizen und außerhalb des Dokuments. Bieten Sie Ihre Lesart im Gespräch an oder schreiben Sie sie in eine separate Datei. Hängen Sie sie niemals an.
Das PDF
"$HOME/.claude/skills/transcribe-summarize/scripts/render_pdf.py" notes.md
Headless Chrome, Chromium oder Edge, automatisch erkannt. Wenn keines installiert ist, wird das HTML geschrieben, der Hinweis ausgegeben, und Exit 0 – das HTML ist immer noch ein auslieferbares Ergebnis.
Herkunft
Die lokale Dekodierung erfolgt mit mlx-whisper (MLX) oder faster-whisper (CTranslate2); die Audio-Vorbereitung mit ffmpeg. Die Netzwerk-Backends rufen Groqs und OpenAIs Transkriptions-Endpunkte direkt über stdlib urllib auf – kein Vendor-SDK.
Die Herkunft aus einem Notizendokument herauszuhalten, ändert, was das Dokument sagt, nicht, was passiert ist. Das Aufzeichnen eines Gesprächs ohne Zustimmung ist strafbar…