Was macht keepwatching?
Eine Datenbank benannter Kurzvideo-Formate, die rendert. Jedes Format besteht aus drei Dateien: einer Rendervorgabe, einer formulierten Hypothese und den Messergebnissen – einschließlich „bisher nichts“.
Die Regel, die diesen Skill nützlich macht: Erfinde niemals eine Retentionszahl. Jede Behauptung darüber, wie ein Format abschneidet, stammt aus formats/<slug>/data.yml, und jede davon führt eine n. Wenn n: 0 ist, lautet die ehrliche Antwort „nicht getestet“ – sag das auch.
Einrichtung – mach das zuerst, in jeder Sitzung
Dieser Skill steuert einen echten Renderer, der sich im keepwatching-Repository befindet. Die Anweisungen allein können nichts rendern, daher ist Schritt eins immer das Lokalisieren oder Installieren des Repos.
# 1. Finde es. Erster Treffer gewinnt; frage den Benutzer, wenn keines existiert.
KW="${KEEPWATCHING_HOME:-}"
[ -z "$KW" ] && [ -d ./keepwatching ] && KW="$PWD/keepwatching"
[ -z "$KW" ] && [ -d "$HOME/keepwatching" ] && KW="$HOME/keepwatching"
[ -z "$KW" ] && { git clone https://github.com/msertdev/keepwatching "$HOME/keepwatching" && KW="$HOME/keepwatching"; }
cd "$KW"
# 2. Einmalige Installation. Kann wiederholt ausgeführt werden; es tut nichts, wenn bereits erledigt.
npm install && npm run setup
# 3. Bestätige, dass die Bibliothek intakt ist, bevor du etwas anderes tust.
npx kw check
Die 24 Galerie-Vorschaubilder sind festgeschrieben, daher zeigt npx kw gallery die Seite in Sekunden ohne etwas zu rendern. npm run setup wird nur zum Rendern von Videos benötigt. Wenn du die scene eines Formats änderst, wird dessen festgeschriebene Vorschau veraltet – rendere sie neu und schreibe sie mit npx kw gallery --no-serve && git add site/previews fest, sonst wird CI's kw previews check fehlschlagen.
kw check, das „keine Probleme“ ausgibt, bedeutet, dass du bereit bist. Wenn es fehlende Schriftarten meldet, führe npm run setup erneut aus – die Komposition weigert sich, mit einer Ersatzschriftart zu rendern, da eine substituierte Schriftart stillschweigend jedes Bild ändern würde, das das Repository jemals gemessen hat.
Zwei praktische Hinweise.
- Shell-Variablen bleiben in den meisten Agent-Umgebungen nicht zwischen Tool-Aufrufen erhalten. Berechne
KWentweder in jedem Befehl neu oder beginne jeden mit einem explizitencd /absoluter/pfad/zu/keepwatching &&. Geh nicht davon aus, dass$KWüberlebt. npm run setupkann auf einer kalten Maschine Minuten dauern. Es lädt Inter (≈30 MB) und einen headless Chromium (≈150 MB) herunter. Auf einer Maschine, die beide bereits zwischengespeichert hat, ist es in Sekunden erledigt. Sage dem Benutzer, was gerade passiert, anstatt den Anschein zu erwecken, dass es hängt.
Jeder Befehl in dieser Datei setzt voraus, dass das Repository-Root das Arbeitsverzeichnis ist. Wenn der Benutzer in einem anderen Projekt arbeitet, rendere innerhalb des Repos und kopiere die MP4 zurück; kw läuft nicht von außerhalb.
Es gibt auch npm run check, das kw check plus tsc --noEmit ist. Verwende dieses, wenn du etwas unter engine/ bearbeitet hast.
Die vier Dinge, die du tun wirst
1. Ein Format für ein Thema auswählen
npx kw list # jedes Format, mit seiner Stichprobengröße und gemessener Retention
Lies formats/<slug>/meta.yml für die hypothesis, useWhen und avoidWhen. Stimme die Form des Inhalts auf die Formatfamilie ab, nicht auf das Thema.
Jedes Format in der folgenden Tabelle hat derzeit
n = 0. Dies sind Ausgangspunkte, die aus einer formulierten Hypothese gewählt wurden, keine Gewinner, die aus Beweisen ausgewählt wurden. Sage das, wenn du eines empfiehlst. Die Tabelle sagt dir, welches Format behauptet, zu einer Inhaltsform zu passen; sie sagt dir nicht, welches abschneidet.
| Der Inhalt ist… | Familie | Beginne mit |
|---|---|---|
| eine große Zahl | stat-counter | stat-counter-rise |
| eine Belohnung, die sich zu warten lohnt | countdown | countdown-clock |
| eine geordnete Menge von Elementen | ranking | ranking-suspense (Vollständigkeit) oder ranking-reveal (Anteile) |
| zwei Optionen, die sich in einer Zahl unterscheiden | comparison | split-compare |
| dasselbe Subjekt in zwei Zuständen | reveal | before-after |
| ein weit verbreiteter falscher Glaube | myth-fact | myth-vs-fact |
| ein starker Satz | cold-open | cold-open-line |
| ein Prozess mit echten Phasen | progress | progress-bar |
| Werte, die wirklich eskalieren | escalation | escalation-ladder |
| etwas Zirkuläres | reverse | loop-seam |
Wenn du eines empfiehlst, zitiere sein n. „ranking-suspense, obwohl es in diesem Repository nicht getestet ist (n=0)“ ist eine gute Empfehlung. „ranking-suspense erreicht 68 % Retention“ ist eine Erfindung, es sei denn, data.yml sagt das.
2. Ein Video rendern
Kopiere ein Format, fülle den data-Block aus, rendere:
npx kw new my-clip --from=stat-counter-rise
# bearbeite formats/my-clip/format.json -> "data": { ... }
npx kw render my-clip # -> out/my-clip/master.mp4
# Optional: Vorschau im Browser ansehen, ohne etwas zu kodieren.
# Blockiert, bis du es stoppst, daher überspringe es bei unbeaufsichtigtem Betrieb.
npx kw preview my-clip
Bearbeite nur data, es sei denn, das Layout muss sich wirklich ändern. Das scene-Array ist das Format; wenn du es änderst, wird der Clip zu einem anderen Format und seine Messungen sind nicht mehr übertragbar. Wenn du die Szene änderst, erhöhe version in format.json – die Varianten-ID leitet sich daraus ab.
Die Länge ändern – lies das, es ist die häufigste Anfrage.
Bibliotheksformate laufen 8–30 Sekunden (21 von 24 zwischen 8 und 14). Die drei 30-Sekunden-Formate – cold-open-question, countdown-clock, stat-counter-rise – sind die Stufen eines laufenden Experiments, nicht die Standardlänge. Jede Länge, die ein Format nicht bereits hat, erfordert die Bearbeitung der Szene, daher gilt „nur data bearbeiten“ nicht. Verwende diese Regel:
Multipliziere
canvas.durationSecund jede zeitliche Angabe in der Szene mitnewDuration / oldDuration. Betrachte dann das Ende: Die Skalierung dehnt das letzte Standbild um denselben Faktor, daher wird das Ende umso schlechter, je größer der Faktor ist.
Beispiel – stat-counter-rise von 10 s auf 30 s, Faktor 3,0. Dies sind die tatsächlich ausgelieferten Zahlen, nicht nur eine Veranschaulichung:
| Feld | 10 s | ×3 | ausgeliefert |
|---|---|---|---|
canvas.durationSec | 10 | 30 | 30 |
counter endSec | 6,4 | 19,2 | 21,0 |
bar endSec | 6,4 | 19,2 | 21,0 |
unit at | 6,4 | 19,2 | 21,0 |
context at / in.at | 6,5 | 19,5 | 21,6 |
source at | — | — | 25,5 – ein Schlag, der nicht existierte |
posterSec | 8,4 | 25,2 | 27,5 |
Die Skalierung allein ließ den letzten Schlag bei 19,5 s in einem 30-Sekunden-Clip: 10,5 Sekunden einer eingefrorenen Karte. Selbst die Verschiebung auf 21,6 s reichte nicht. Ab einem Faktor von etwa zwei hört die Arithmetik auf, die Antwort zu sein – der Clip braucht einen Schlag, den er nicht hatte. Hier ist das eine Zitierzeile bei 25,5 s, die das Format in seinen sources die ganze Zeit beansprucht und nie auf dem Bildschirm gezeigt hatte. Endstandbild: 4 Sekunden.
Eine Endkarte, die länger als etwa 3 Sekunden gehalten wird, ist tote Luft, und tote Luft am Ende tötet die Abschlussrate. kw frame0 schlägt bei 5 Sekunden eines bewegungslosen Bildschirms fehl: 3 ist die handwerkliche Empfehlung, 5 ist die harte Grenze. Es fand drei Formate, die bereits mit einem 6-Sekunden-Einfrieren am Ende ausgeliefert waren.
Einschränkungen und Prüfungen:
durationSec × fpsmuss eine ganze Anzahl von Frames ergeben.- Erhöhe
versioninformat.json, wann immer du die Szene änderst – Neuzeitlichung zählt. Ein neues Gerüst bei0.1.0, das du dann neu zeitlich abstimmst, wird zu0.2.0. Die Varianten-ID leitet sich vonversionplus einem Hash der Vorgabe ab, sodass eine zukünftige Messung zuordenbar bleibt. npx kw checkerfasst Zeitangaben, die über das Ende des Clips hinausgehen, undnpx kw frame0erfasst einen ersten Frame, der nichts malt, plus jeden bewegungslosen Lauf über 5 Sekunden. Keines von beiden kann dir sagen, dass ein Clip langweilig ist – öffne dazu nach dem Rendernout/<slug>/contact.png. Es tastet sechs Frames gleichmäßig über den Clip ab, sodass nahezu identische Kacheln auf einen Blick sichtbar sind.
Quellenangaben. kw new --from=<slug> setzt das Gerüst absichtlich auf sampleContent: placeholder zurück und entfernt die sources des übergeordneten Formats – die Zitate des übergeordneten Formats untermauerten dessen Zahlen, nicht deine. Wenn du eine echte Zahl auf den Bildschirm bringst, setze sampleContent: sourced und füge einen sources:-Eintrag mit einer URL und der genauen Behauptung hinzu, die er untermauert.
Eine bequellte Zahl ist erst dann bequellt, wenn sie erscheint. Wenn du einen Zähler auf eine zitierte Zahl animierst, markiere sie mit claim: "final" und halte die Einheit und jedes Wort wie „genau“ bis endSec vom Bildschirm fern – zeige bis dahin „zählt…“. Jedes andere Element, das während des Zählvorgangs sichtbar ist, benötigt neutralWhileCounting: true. kw check lehnt das Format andernfalls ab. Zähler, deren Zwischenwerte wahrheitsgemäß sind („Frames bisher“), sind mit claim: "running" markiert und sind ausgenommen.
Was als Quelle zählt: etwas, das ein Leser öffnen und die Zahl überprüfen kann – eine Primärpublikation oder ihr permanenter Datensatz (DOI, PubMed), eine Normungsorganisation, eine statistische Behörde, ein offizieller Bericht. Kein Listicle, kein Blog, der eines zusammenfasst, und keine eigene Erinnerung. Gib jede Rundung, die du für den Bildschirm vorgenommen hast, im claim-Feld an. kw check überprüft, ob eine URL und eine Behauptung vorhanden sind; es kann nicht überprüfen, ob sie wahr sind, daher liegt dieser Teil bei dir. Wenn du keine Quelle finden kannst, verwende stattdessen Platzhaltertext – eine erfundene Statistik ist derselbe Fehler wie eine erfundene Retentionszahl.
Siehe references/spec.md für die vollständige Referenz zu format.json.
3. Einen A/B-Test durchführen
Zwei Formate, gleicher Inhalt, gleicher Tag:
npx kw new test-a --from=cold-open-line
npx kw new test-b --from=redacted-reveal
# füge identischen Text in beide data-Blöcke ein
npx kw render test-a && npx kw render test-b
npx kw variant test-a # zeichne diesen String gegen den Upload auf
Die variantId in out/<slug>/variant.json macht das Ergebnis zuordenbar. Zeichne sie zum Zeitpunkt des Uploads gegen das veröffentlichte Video auf – sie wird auch in den Metadatenkommentar der MP4 geschrieben, falls du deine Notizen verlierst.
4. Messungen wieder einlesen
# Exportiere CSVs aus YouTube Studio / TikTok Analytics in measure/inbox/
npx kw measure # importieren + Bericht -> measure/report.md
npx kw measure apply # schreibe Ergebnisse in formats/*/data.yml
npx kw gallery # neu rendern + Galerie neu aufbauen
Keine API, kein OAuth. Siehe references/measuring.md für die genauen Exportschritte und das Format von mapping.csv.
Determinismus ist die Vereinbarung
Die gleiche format.json erzeugt die gleichen Frames, auf jeder Maschine, für immer. Das ermöglicht es, eine Retentionskurve einem Format zuzuordnen und nicht einem Render. Bearbeite niemals Date.now(), Math.random(), requestAnimationFrame, CSS-Übergänge oder CSS-Animationen in der Komposition. npx kw render <slug> --check-determinism sucht Frames in falscher Reihenfolge und schlägt fehl, wenn sich ein Pixel bewegt hat.
Zwei Messungen, die niemals vermischt werden dürfen
data.yml hat zwei Blöcke, und sie beantworten unterschiedliche Fragen:
| Block | Frage | Bewertet die Bibliothek? |
|---|---|---|
format | Wie schneidet diese Szenenstruktur ab? | Ja |
content_axis | Wie schneidet dieses Thema ab? | Nein |
Ein einzelnes veröffentlichtes Video trägt beide Labels – es ist ein Countdown und es ist über den Körper. Die Mittelung der beiden ergibt eine Zahl, die keine der beiden Fragen beantwortet, daher werden sie getrennt gespeichert, getrennt berichtet und in der Galerie in verschiedenen Farben angezeigt.
Wenn du ein Ergebnis meldest, sag, welches es ist:
- „
countdown-clockbehielt 62 % (n=6)“ – eine Formatbehauptung. - „persönliche/Körper-Themen behielten 68 % (n=9)“ – eine Achsenbehauptung.
- „persönliche/Körper-Countdowns behielten 68 %“ – keins von beiden, es sei denn, du sagst auch, wie viele Videos, in welchen Formaten, und dass die beiden vermischt sind.
measure/report.md druckt eine Spalte getragen von für jede Achse. Wenn eine Achse nur von einem Format getragen wurde, sind dieses Achsenergebnis und dieses Formergebnis dieselben Videos mit zwei Labels; sag das, anstatt sie als zwei unabhängige Ergebnisse zu präsentieren.
Inhaltsachsen werden in data/content-axes.yml deklariert und einem Video durch die optionale Spalte content_axis in measure/mapping.csv zugeordnet. Es sind die eigenen Achsen des Benutzers, nicht die der Bibliothek – füge jede Unterscheidung hinzu, die sie tatsächlich testen.
variant_id: not-in-library markiert ein veröffentlichtes Video, dessen Format nicht in diesem Repository ist. Es ist nur eine Inhaltsachsen-Stichprobe: Es erreicht weder die Formattafel noch irgendeine data.yml, und getragen von benennt es, damit die Lücke sichtbar ist. Ergebnisse auf Repository-Ebene für Achsen leben in data/content-axis-results.yml, weshalb eine Achse gemessen werden kann, während jedes Format noch n = 0 hat. Spekuliere nicht darüber, was ein solches Format ist – das Label sagt absichtlich nichts darüber aus.
Ehrlichkeitsregeln
Dies sind keine Stilpräferenzen. Das Repository ist wertlos, wenn sie verletzt werden.
n: 0bedeutet nicht getestet. Runde es niemals auf „vielversprechend“ oder „wahrscheinlich“ auf.- Unter n=5 ist eine Richtung, kein Ergebnis. Sage, welche du angibst.
- Verlierende Formate bleiben mit ihren Zahlen aufgelistet. Entferne sie nicht stillschweigend.
- Schreibe niemals
data.ymlvon Hand. Nurkw measure applyschreibt es. Zahlen, die aus dem Gedächtnis getippt wurden, sind nicht von Zahlen zu unterscheiden, die erfunden wurden. - Vermische niemals eine Formatnummer mit einer Achsennummer. Siehe die Tabelle oben.
- Jede Zahl auf dem Bildschirm benötigt eine Quelle. Ein Clip, den du generierst, trägt entweder
sampleContent: sourcedmit einer URL oderplaceholdermit offensichtlichem Füllmaterial. Das Erfinden einer plausiblen Statistik für eine Demo ist derselbe Fehler wie das Erfinden einer Retentionszahl. - Ausgangsdaten sind der Kanal eines einzigen Erstellers. Es ist ein Ausgangspunkt, kein Gesetz der Plattform. Sage, wessen Stichprobe es ist, wenn die Unterscheidung wichtig ist.
Referenzdateien
references/spec.md– die Element- und Animationsreferenz fürformat.jsonreferences/formats.md– die Formatbibliothek, nach Familie, mit Hypothesenreferences/measuring.md– CSV-Export, Zuordnung und der Berichtszyklusreferences/authoring.md– ein neues Format schreiben, das es wert ist, gemessen zu werden