psychopomp について
psychopompは、ソフトウェア変更を解説するナレーション付きリールを制作するスキルです。変更の検証から台本、シーン作成、レビュー、レンダリングまでを導き、映像の動きをナレーションに合わせます。
主な機能
- 01差分やテストに基づく変更の検証
- 02クリップ単位のナレーション台本作成
- 03再利用可能な要素によるアニメーションシーン構成
- 04映像の動きと台詞のフレーズの同期
- 05リール全体のレビューとレンダリング
活用シーン
- 01アニメーションでプルリクエストを解説
- 02変更前後をナレーション付きで紹介
- 03タイミングを合わせた注釈やカウンターで動作変更を示す
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kitlangton/ psychopomp --skill psychopompインストール後、Claude Code で/psychopompを入力して読み込まれたか確認します。
同梱ファイルSTORY.md
詳細
Psychopomp 解説リール
解説リールとは、複数の独立して作成された Scene Plan をひとつの時間軸上でつないだものです。GPU Stage 上の動作ストーリー(オーブ、カード、ビーム、パケット、カメラ、ブルーム)、固定表示の Callout、Rolling Number、アニメーション付き Stepped Diff、ターミナル調の音声による字幕、そしてオプションのナレーションで構成されます。ナレーションを付けると、すべてのビジュアルのビートが文字起こし内のフレーズを待つため、声を録り直すとフィルムのタイミングも自動的に調整されます。
動作例は scenes/pr-walkthrough にあります。Stage フィルムからコードにズームインする src/flagship.rs(#50825)、Stage、Callout、Rolling Number、注釈付きコード差分へのズームを組み合わせた src/stop_stage.rs(#50042)、そしてシーケンス図を含む5つの PR のリールである src/lib.rs を参照してください。その構成を参考にし、空のクレートから始めないでください。コンポーネントのペイロード、チャンネル、コマンドは SCENE_PLANS.md(「ナレーション付き解説リールを作成する」)に、用語は CONTEXT.md に記載されています。作成を始める前に、両方を読んでください。エンジニアリングのルールは AGENTS.md に記載されています。
手順
-
事実を確認します。 変更ごとに、実際の差分と PR の説明(
gh pr diff、gh pr view)を読み、壊れていた動作、修正後の動作、変更内容をそれぞれ1文で書きます。ナレーションで述べるすべての主張をコード、テスト、または再現した実行結果にたどれる状態になったら完了です。検証できなかった点には印を付け、スクリプトには含めないでください。 -
スクリプトを作成します。
scenes/<name>/narration/script.jsonとして、パートごとに1つのクリップを作成します。順序は、イントロ、変更ごとの<slug>-before、<slug>-after、<slug>-code、そしてアウトロです。作成時は STORY.md に従ってください。各クリップの読み上げ時間が約30秒以内で、計画したビジュアルのビートそれぞれに、異なるアンカーフレーズが含まれていれば完了です。 -
音声を付けます(任意)。 まずは認証情報なしでドラフトを作成します(
--draftは macOS のsayを使用します)。または、ElevenLabs(engine: "elevenlabs"、デフォルトモデルはeleven_v4)か Fish Audio(engine: "fish")で最終ナレーションを合成します:{ "engine": "elevenlabs", "model": "eleven_v4", "voice": "<elevenlabs-voice-id>", "settings": { "stability": 0.5, "similarity": 0.7 }, "clips": [ { "id": "change-before", "text": "[warm, conversational voice] ..." } ] }# Draft (no API key required) bun scripts/narrate.ts scenes/<name>/narration/script.json --draft # ElevenLabs (requires ELEVENLABS_API_KEY and script.voice) ELEVENLABS_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.json # Fish Audio (requires FISH_AUDIO_API_KEY) FISH_AUDIO_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.jsonscripts/narrate.tsは音量を正規化し、Whisper で単語のタイミングを書き起こして、<id>.mp3、<id>.words.json、narration.jsonを書き出します。声やエンジンを切り替えるときは、新しい単語のタイミングに合わせて Scene Plan を作り直してください。または、Scene Program でナレーションを宣言します。
psychopomp-media(SCENE_PLANS.md、「ナレーションと音声を宣言する」)を使い、media.say(id, &voice, text)、media.dialogue、media.sfx、audio.derive(Effect::pitch(..))を指定してから、media.finish()?を呼び出します。各行は一度だけ生成され、media.lock.jsonに記録されます。その後の実行では、宣言に変更がない限り何も呼び出されません。また、ElevenLabs の単語データは、スクリプトの綴りに対応する文字アラインメントから取得されます。まずPSYCHOPOMP_MEDIA=plan cargo run -p <crate>でコストを確認し(API 呼び出しはゼロです)、PSYCHOPOMP_MEDIA=draftでタイミングを確認し、PSYCHOPOMP_MEDIA=pruneでクリーンアップします。cargo run -p psychopomp-media -- adopt scenes/<name>/narrationで narrate.ts のシーンを移行できます(再生成は行いません)。通常の実行で、すべてのリソースが=と報告されたら完了です。 -
シーンプログラムを作成する:
scenes/<name>に作成します(ワークスペースが自動的に取り込みます。主要な時刻をいくつか指定して、verify.jsonに追加してください)。psychopomp::score(SCENE_PLANS.md、「Author With The Score DSL」)を使い、PlanBuilderだけをmutバインディングにしてください。すべてのアクター(Stage、Camera、Caption、Callout、RollingNumber、Checklist、Meter、Bars、Subtitles、Confetti、Terminal、Chat、ChangedFiles、LowerThird、Lens)は不変値とし、そのメソッドは合成可能なBeat(.then、.also、.with、.on_end、.after、.early、stagger、each、at!(scene, time => ...))を返すようにします。Narration::readingでクリップをスケジュールし、StageElement::card|orb|beam|packet|label|ringと、StagePost::RESTRAINED上の相対的なpsychopomp::layout::Placementエンベロープで要素を構築します。Caption::header|chip|footerでフレームを構成し、sfx::*.beat(id, gain_db)(またはpsychopomp-mediaのaudio.beat(gain_db))でサウンドを再生します。explainer-motionスキルを読み込み、すべてのビートに適用します。カードにはsettle_in、ビームにはconnect、メッセージにはsend、返信には.reply()で待機、衝撃にはhit、主役にはorb_in、修正にはrewindを使います。Calloutで Stage 要素や Editor のコード範囲に注釈を固定し、RollingNumberでリアルタイムのカウンターやタイマーを表示します。カメラ移動はstage.camera()(establish、frame、follow、release、orbit、whip、dolly_zoom)で制御します。Stage のラベルやリングを手作業で組み立てるのではなく、ビジュアライゼーションやテキストのオーバーレイを活用します。実行・解決されるチェックにはChecklist、タイムアウトリングにはMeter(MeterPlan::countdown)、変更前後の数値にはBars、成功のビートにはConfetti、単語単位のタイミング付き字幕を映像に焼き込むにはSubtitles(SubtitlesPlan::from_spoken)を使います。変更は、各ステップがフレーズに対応付けられたkeep、add(step)、remove(step)の行からなるDiffです。cargo run -p <crate>でリールが書き出され、cargo run --release -- plan validate <reel>が有効と報告すれば完了です。フレーズが見つからないとクリップとともにパニックが発生します。その場合は、文字起こしに実際に含まれる単語にアンカーを変更してください。 -
レンダリング前にレビューする。
plan inspect <reel>でセグメントの範囲を取得し、各セグメントの開始前、切り替え、切り替え後、コードの各ビートでコンタクトシートを作成します。bun scripts/sheet.ts <reel> t1,t2,... --theme neutral --shutter --out output/sheet.jpg見た目を調整する際は、
PSYCHOPOMP_SHADER_DIR=crates/psychopomp-render/src/renderを設定して、stage.wgsl/stage_post.wgslを編集します。Rust を再ビルドしなくても、すべてのフレームとシートにシェーダーの変更が反映されます。 次に、音声付きで動作セグメントを1つレンダリングする(plan render <reel> out.mp4 --cue <scene-id>)か、2~3秒の範囲(--range a..b)をレンダリングし、動作中に抽出したフレームを確認します。すべてのセグメントを確認し、テキストの重なりやクリッピングがなく、誤ったチップに対してテキストが表示されていなければ完了です。 -
リール全体をレンダリングして検証するのは、シートと短い範囲の確認に合格してから一度だけにします。前面でタイムアウトを長めに設定して実行し、処理中のままターンを終了しないでください。
cargo run --release -- plan render <reel> output/<name>.mp4 --theme neutralffprobeで 1920x1080、60 fps、AAC 音声が確認でき、再生時間がplan inspectと一致し、ラウドネスが約 -16 LUFS、ピークが -1 dBFS 未満であれば完了です。 -
MP4 のパスを納品します。Psychopomp で、シーン、ナレーションアセット、およびエンジンに加えた変更を、Conventional Commits に沿ったメッセージでコミットします。
Psychopomp の改善
リールでエンジンにできないことが必要になった場合は、1 つのシーンで回避策を講じるのではなく、Psychopomp に追加してください。プランの型と検証は crates/psychopomp に、厳密なチャネルの事前チェックは plan_runtime に、ピクセル処理は render に追加します。また、GPU を使わないテストに加えて #[ignore] を付けた GPU テストを用意し、ドキュメントの AGENTS.md を最新の状態に保ちます。変更前に cargo run --release -- verify baseline を実行し、変更後に verify compare --expect <scenes you changed> を実行して、ほかのショールームやフィルムに変更がないことを確認してください。
小さく再利用可能な部品から構築してください。補間、イージング、曲線、シェイプポート、コネクターは psychopomp::math に配置します(pmndrs math のように、コアの lerp/remap/smoothstep、easing、curve、shapes、random で構成し、glam のベクトルを使用します)。レンダラーやシーンに数式を直接書き込むのではなく、このモジュールを拡張してください。また、render/stage.rs のように、レンダラーを要素ごとの小さなヘルパーに分割してください。cargo fmt --check、cargo clippy --workspace --all-targets --all-features -- -D warnings、cargo test --workspace がすべて成功する状態を保ってください。