Communitygithub.com

keepwatching

短尺動画フォーマットの保持率データベース。表示機能付き。9:16の名前付きフォーマットにコミット済みプレビュー、計測された保持率、表示サンプルサイズを備えています。Node + Playwright + ffmpeg ベースで、エージェントスキルとしてインストール可能。

keepwatching とは?

keepwatching は、短尺動画(主に9:16縦型)のフォーマットごとの視聴者保持率(リテンション)を管理・可視化するデータベーススキルです。Node.js、Playwright、ffmpeg を基盤としており、Claude Code などのAIエージェントが直接利用できるスキルとして設計されています。このスキルの根幹は「保持率を決して捏造しない」というルールにあり、すべてのクレームは実際の計測データ(`formats/<slug>/data.yml`)に基づいて行われ、サンプルサイズ `n` が常に明示されます。ユーザーは `npx kw` コマンド群を通じて、フォーマットの一覧表示、動画のレンダリング、A/Bテストの実行、計測結果の取り込みとレポート生成をエージェントに指示できます。レンダリングは決定論的であり、同一の `format.json` は常に同一のフレームを生成するため、保持率をフォーマットに正しく帰属させることが可能です。フォーマットライブラリは「統計カウンター」「カウントダウン」「ランキング」など様々なコンテンツタイプに対応し、各フォーマットには仮説(`hypothesis`)と使用条件が定義されています。また、データの誠実さを保つための厳格なルール(未検証のフォーマットは `n=0` と表示、ソースのない数値は画面に表示しないなど)が徹底されており、実験結果の信頼性を担保します。このスキルは主に、動画マーケティング担当者やコンテンツクリエイターが、どの動画フォーマットが最も視聴者を引きつけるかをデータドリブンで検証・最適化するために使用します。

対応~Claude Code~Codex CLI~Cursor
npx skills add msertdev/keepwatching

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

keepwatching は何をしますか?

名前付き短尺動画フォーマットのデータベース。表示機能付き。各フォーマットは3つのファイルで構成されます:レンダリング仕様、表明された仮説、そして計測結果(「まだ何もない」場合を含む)。

このスキルを有用にするルール:決して保持率を捏造しない。 フォーマットのパフォーマンスに関するすべての主張は formats/<slug>/data.yml に基づいており、すべてのエントリには n(サンプルサイズ)が記載されています。n: 0 の場合、正直な回答は「未テスト」です — そのように伝えてください。

セットアップ — 毎セッション、最初にこれを行う

このスキルは実際のレンダリングエンジンを駆動します。レンダリングエンジンは keepwatching リポジトリにあります。指示だけでは何もレンダリングできないため、最初のステップは常にリポジトリの場所を特定するか、インストールすることです。

# 1. リポジトリを探す。最初に見つかったものが優先。どれも存在しない場合はユーザーに確認する。
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. 一度だけのインストール。再実行しても安全;完了していれば何もしない。
npm install && npm run setup

# 3. 何かをする前にライブラリが正常であることを確認する。
npx kw check

24のギャラリープレビューはコミット済みなので、npx kw gallery は何もレンダリングせずに数秒でページを表示します。npm run setup はビデオをレンダリングする場合にのみ必要です。フォーマットの scene を変更した場合、コミット済みプレビューは古くなります — 再レンダリングして npx kw gallery --no-serve && git add site/previews でコミットするか、CIの kw previews check が失敗します。

kw check が no problems と表示すれば、準備完了です。フォントがないと報告された場合は、npm run setup を再度実行してください — フォールバックフォントを使用したレンダリングは拒否されます。なぜなら、代替フォントはリポジトリがこれまで計測したすべてのフレームを黙って変更してしまうからです。

2つの実用的な注意事項。

  • シェル変数はほとんどのエージェントハーネスにおいてツール呼び出し間で持続しません。 毎回のコマンドで KW を再計算するか、各コマンドを明示的な cd /絶対パス/keepwatching && で始めてください。$KW が残っていると想定しないでください。
  • npm run setup はコールドマシンでは数分かかることがあります。 Inter フォント(約30MB)とヘッドレス Chromium(約150MB)をダウンロードします。両方がキャッシュされているマシンでは数秒で終了します。ハングしているように見えないよう、どちらの状態が発生しているかをユーザーに伝えてください。

このファイルのすべてのコマンドは、リポジトリルートが作業ディレクトリであることを前提としています。 ユーザーが別のプロジェクトで作業している場合は、リポジトリ内でレンダリングしてMP4をコピーしてください;kw は外部からは実行できません。

npm run check もあります。これは kw check に加えて tsc --noEmit を実行します。engine/ 以下を編集した場合はこちらを使用してください。

依頼されるであろう4つのタスク

1. トピックに合ったフォーマットを選ぶ

npx kw list          # すべてのフォーマットと、そのサンプルサイズ、計測された保持率を表示

formats/<slug>/meta.yml を読んで、hypothesis(仮説)、useWhen(使用する時)、avoidWhen(避ける時)を確認してください。トピックではなく、コンテンツの形状をフォーマットファミリーにマッチさせてください。

以下の表のすべてのフォーマットは現在 n = 0 です。 これらはエビデンスから選ばれた勝者ではなく、表明された仮説から選ばれた出発点です。推奨する際にはその旨を伝えてください。この表は、どのフォーマットがどのようなコンテンツの形状に適していると主張しているかを示すものであり、どのフォーマットが実際に機能するかを示すものではありません。

コンテンツの種類…ファミリーまずこれから始める
一つの大きな数字stat-counterstat-counter-rise
待つ価値のある見返りcountdowncountdown-clock
順序付けられたアイテムのセットrankingranking-suspense(完走率)または ranking-reveal(シェア)
一つの数値だけが異なる二つの選択肢comparisonsplit-compare
二つの状態にある同じ主題revealbefore-after
広く信じられている誤った信念myth-factmyth-vs-fact
一つの強い文cold-opencold-open-line
実際の段階があるプロセスprogressprogress-bar
本当にエスカレートする値escalationescalation-ladder
循環するものreverseloop-seam

推奨する際は、その n を引用してください。「ranking-suspense、ただしこのリポジトリでは未テストです(n=0)」は良い推奨です。「ranking-suspense の保持率は68%です」は、data.yml がそう言っていない限り捏造です。

2. ビデオをレンダリングする

フォーマットをコピーし、data ブロックを埋めて、レンダリングします:

npx kw new my-clip --from=stat-counter-rise
# formats/my-clip/format.json を編集 -> "data": { ... }
npx kw render my-clip           # -> out/my-clip/master.mp4

# オプション:エンコードせずにブラウザで事前確認。
# 停止するまでブロックするので、無人実行時はスキップしてください。
npx kw preview my-clip

レイアウトを本当に変更する必要がない限り、data のみを編集してください。scene 配列はフォーマットそのものです;これを変更するとクリップは別のフォーマットになり、その計測結果は転用できなくなります。シーンを変更した場合は、format.json の version を上げてください — バリアントIDはそこから派生します。

長さの変更 — これをお読みください。最も一般的なリクエストです。

ライブラリフォーマットは 8~30秒 で動作します(24個中21個は8~14秒)。30秒の3つ(cold-open-question、countdown-clock、stat-counter-rise)は進行中の実験の段階であり、標準的な長さではありません。フォーマットがまだ持っていない長さはすべてシーンの編集を必要とするため、「data のみを編集」は適用されません。次のルールを使用してください:

canvas.durationSec とシーン内のすべてのタイミング に newDuration / oldDuration を乗算します。その後、末尾を確認します:スケーリングにより最終ホールドも同じ倍率で引き伸ばされるため、倍率が大きいほどエンディングは悪化します。

実例 — stat-counter-rise を10秒から30秒に、倍率3.0。以下は実際に出荷された数値であり、説明のためのものではありません:

フィールド10秒×3出荷値
canvas.durationSec103030
counter endSec6.419.221.0
bar endSec6.419.221.0
unit at6.419.221.0
context at / in.at6.519.521.6
source at——25.5 — 存在しなかったビート
posterSec8.425.227.5

スケーリングだけでは、最後のビートは30秒のクリップ中19.5秒に残りました:10.5秒もの静止カード。 それを21.6秒に押し上げても十分ではありませんでした。約2倍を超えると、算術は解決策ではなくなります — クリップにはこれまでになかったビートが必要です。ここでは25.5秒の引用行がそれであり、フォーマットは sources でずっと主張していたものを実際に画面に表示したことがありませんでした。最終ホールド:4秒。

最終カードが約3秒以上保持されるとデッドエアになり、クリップの最後のデッドエアは完走率を低下させます。kw frame0 は5秒の無動画面で完全に失敗します:3秒が制作上のアドバイスであり、5秒がハードリミットです。このツールは、すでに6秒の静止エンディングで出荷されていた3つのフォーマットを発見しました。

制約とチェック:

  • durationSec × fps はフレーム数の整数でなければなりません。
  • シーンを変更するたびに format.json の version を上げてください — タイミングの変更も含まれます。新しくスキャフォールドした 0.1.0 をタイミング変更すると 0.2.0 になります。バリアントIDは version と仕様のハッシュから派生するため、将来の計測結果を正しく帰属させることができます。
  • npx kw check はクリップの終わりを超えたタイミングを検出し、npx kw frame0 は何も描画しない最初のフレームと5秒を超える無動ランを検出します。どちらもクリップが退屈かどうかを判断することはできません — そのためには、レンダリング後に out/<slug>/contact.png を開いてください。クリップ全体から均等に6つのフレームをサンプリングするため、ほぼ同一のタイルが一目でわかります。

ソーシング(情報源の明示)。 kw new --from=<slug> は意図的にスキャフォールドを sampleContent: placeholder にリセットし、親の sources を削除します — 親の引用は親の数値を裏付けるものであり、あなたのものではありません。実際の数値を画面に表示する場合は、sampleContent: sourced に設定し、URLとそれが裏付ける正確な主張を含む sources: エントリを追加してください。

ソース付きの数値は、それが画面に表示されて初めてソース付きになります。 引用された数値にカウンターをアニメーションさせる場合、claim: "final" とマークし、単位や「正確に」などの言葉を endSec まで画面に表示しないでください — それまでは「counting…」と表示します。カウント中に表示される他のすべての要素は neutralWhileCounting: true が必要です。kw check はそうでなければフォーマットを拒否します。中間値が正直に真実であるカウンター(「これまでのフレーム数」)は claim: "running" とマークされ、免除されます。

ソースとして認められるもの:読者が開いて数値を確認できるもの — 一次論文またはその恒久的な記録(DOI、PubMed)、標準化団体、統計機関、公式報告書。リスト記事、それを要約したブログ、または自分自身の記憶ではありません。画面用に行った丸めは claim フィールドに記載してください。kw check はURLとクレームが存在することを検証します;それらが真実であることを検証することはできないため、その部分はあなたの責任です。ソースが見つからない場合は、代わりにフィラーコピーを使用してください — 統計値を捏造することは、保持率を捏造することと同じ失敗です。

完全な format.json リファレンスについては references/spec.md を参照してください。

3. A/Bテストを実行する

同じコンテンツ、同じ日付で2つのフォーマット:

npx kw new test-a --from=cold-open-line
npx kw new test-b --from=redacted-reveal
# 両方の data ブロックに同一のコピーを入れる
npx kw render test-a && npx kw render test-b
npx kw variant test-a           # この文字列をアップロードに対して記録する

out/<slug>/variant.json の variantId が結果を帰属可能にするものです。公開されたビデオに対してアップロード時に記録してください — メモを失った場合のために、MP4のメタデータコメントにも書き込まれます。

4. 計測結果を読み込む

# YouTube Studio / TikTok アナリティクスからCSVを measure/inbox/ にエクスポートする
npx kw measure                  # 取り込み + レポート -> measure/report.md
npx kw measure apply            # 結果を formats/*/data.yml に書き込む
npx kw gallery                  # 再レンダリング + ギャラリーの再構築

APIもOAuthも不要。正確なエクスポート手順と mapping.csv フォーマットについては references/measuring.md を参照してください。

決定論が契約である

同一の format.json は、どのマシンでも、永遠に同一のフレームを生成します。これにより、保持率カーブをレンダリングではなくフォーマットに帰属させることができます。エンジンを編集する際は、Date.now()、Math.random()、requestAnimationFrame、CSS transitions、CSS animations をコンポジションに導入しないでください。npx kw render <slug> --check-determinism はフレームを順不同で再シークし、いずれかのピクセルが移動した場合に失敗します。

決して混同してはならない二つの計測値

data.yml には2つのブロックがあり、異なる質問に答えます:

ブロック質問ライブラリをランク付けするか?
formatこのシーン構造はどのように機能するか?はい
content_axisこの主題はどのように機能するか?いいえ

公開された単一のビデオは両方のラベルを持ちます — それはカウントダウンであり、身体についてです。両方を平均するとどちらの質問にも答えない数値になるため、別々に保存され、別々に報告され、ギャラリーで異なる色で表示されます。

結果を報告する際は、どちらであるかを述べてください:

  • 「countdown-clock は62%維持しました(n=6)」 — フォーマットの主張。
  • 「パーソナル/身体の主題は68%維持しました(n=9)」 — 軸の主張。
  • 「パーソナル/身体のカウントダウンは68%維持しました」 — どちらでもない、何本のビデオがどのフォーマットで、そして両者が交絡しているかを言わない限り。

measure/report.md はすべての軸に carried by(担われたフォーマット)列を表示します。ある軸がたった一つのフォーマットによってのみ担われていた場合、その軸の結果とそのフォーマットの結果は、2つのラベルを着けた同じビデオです;それらを2つの独立した発見として提示するのではなく、そう述べてください。

コンテンツ軸は data/content-axes.yml で宣言され、measure/mapping.csv のオプションの content_axis 列によってビデオにアタッチされます。これらはユーザー自身の軸であり、ライブラリのものではありません — 彼らが実際にテストする任意の区別を追加してください。

variant_id: not-in-library は、このリポジトリにないフォーマットの公開ビデオを示します。これはコンテンツ軸サンプルのみです:フォーマットボードや data.yml には決して到達せず、carried by はギャップが見えるように名前を付けます。リポジトリレベルの軸結果は data/content-axis-results.yml に存在するため、すべてのフォーマットがまだ n = 0 の間でも軸を計測できます。そのようなフォーマットが何であるかについて推測しないでください — ラベルは意図的にそれについて何も語っていません。

誠実さのルール

これらはスタイルの好みではありません。これらが破られるとリポジトリは無価値になります。

  1. n: 0 は未テストを意味します。 決して「有望」や「可能性が高い」に切り上げないでください。
  2. n=5未満は方向性であり、結果ではありません。 どちらを伝えているかを述べてください。
  3. パフォーマンスの低いフォーマットも数値と共にリストに残します。 静かに削除しないでください。
  4. 決して手書きで data.yml を編集しないでください。 それを書き込むのは kw measure apply だけです。記憶からタイプされた数値は、捏造された数値と区別がつきません。
  5. フォーマットの数値と軸の数値を決してマージしないでください。 上の表を参照してください。
  6. 画面上のすべての数値にはソースが必要です。 あなたが生成するクリップは、sampleContent: sourced(URL付き)または placeholder(明らかなフィラー)のいずれかを保持します。デモのためにもっともらしい統計を捏造することは、保持率を捏造することと同じ失敗です。
  7. シードデータは一人のクリエイターのチャンネルからのものです。 それは出発点であり、プラットフォームの法則ではありません。その区別が重要な場合は、誰のサンプルであるかを述べてください。

リファレンスファイル

  • references/spec.md — format.json の要素とアニメーションリファレンス
  • references/formats.md — フォーマットライブラリ、ファミリー別、仮説付き
  • references/measuring.md — CSVエクスポート、マッピング、およびレポートループ
  • references/authoring.md — 計測する価値のある新しいフォーマットの作成方法

関連スキル