talking-avatar-skill について
talking-avatar-skillは、音声に合わせて口の形が変わる単一キャラクターの会話アプリ構築手順です。アバター素材の作成、OpenAI Realtime連携、リップシンク、APIキーの扱いを説明します。
主な機能
- 01ポートレートと口パーツの生成手順
- 02OpenAI Realtimeアプリ連携の指針
- 03音声に連動する口の動き
- 04BYOK APIキーのセキュリティ要件
- 05構築と検証のチェックリスト
活用シーン
- 01単一アバターの音声会話アプリ構築
- 02アプリへの音声連動リップシンク追加
- 03OpenAI Realtimeキーの安全な処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ buildfastwithai/ buildfast-skills --skill talking-avatar-skillインストール後、Claude Code で/talking-avatar-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdagents/openai.yamlassets/starter/app/globals.css.tmpllayout.tsx.tmplpage.tsx.tmplTalkingAvatarApp.tsx.tmplassets/starter/app/api/realtime/session/route.ts.tmplassets/starter/tests/talking-avatar.test.mjs.tmplreferences/app-contract.mdimage-pipeline.mdrealtime-lipsync.mdscripts/scaffold_app.pyvalidate_avatar_assets.py詳細
Talking Avatar
実際のリモート音声に合わせて口の形が変わる、固定のキャラクターポートレートを使った、焦点を絞った音声会話を1つ作成します。写真またはキャラクターの説明を受け取り、基本ポートレートと小さな口のスプライトを生成して、OpenAI Realtime を中心にアプリを構築します。
必要なスキルを連携させる
- 基本ポートレートや口のフレームの生成・編集には、必ず
imagegenを使用します。生成前に、手順全体を読んでください。 - 現在の Realtime WebRTC エンドポイント、セッションスキーマ、モデル、音声、認証情報のフローを確認するには、
openai-docsと、該当する場合はopenai-platform-api-keyを使用します。このスキルにあるモデルの例を、現行情報としてそのまま信用しないでください。 - インターフェースの作業には、利用可能なフロントエンドデザインスキルを使用します。
.openai/hosting.jsonが存在する場合は、デプロイまでsites-buildingとsites-hostingに従ってください。- ユーザーから明示的な依頼がない限り、背景、衣装、役割モード、複数のキャラクターを追加しないでください。標準の製品は、アバター1人と会話1つです。
入力方法を選択する
- 写真が提供されている場合:
view_imageで確認し、本人確認のための参照画像として扱います。顔の形、肌の色、髪、眼鏡、ひげなどの顔の毛、特徴的な要素を維持してください。 - キャラクターの説明がある場合: 説明を具体的なビジュアル仕様に整理します。写実的かイラスト調かなど、本人の印象を大きく左右する情報が不足している場合に限り、質問してください。それ以外は、適切な既定値で進めます。
- キャラクター名、簡潔なペルソナ、アプリ名、言語、希望する音声を決めます。問題がなければ、妥当な既定値を推定します。
アバターのアセットを作成または編集する前に、references/image-pipeline.md を読んでください。
アセット一式を作成する
- 正面向きで、均一に照らされ、口を閉じた基本ポートレートを1枚生成します。キャンバス、トリミング、頭の位置、視線、ポーズ、服装、背景、照明を固定します。
- この基本画像から、本人らしさを保ったまま、次の3つの編集画像を個別に生成します。
soft:唇をわずかに開く。round:自然な丸みのある母音の形にする。open:自然な中程度の開口にする。
- 各編集プロンプトで不変の要素を繰り返し指定します。変えるのは唇と口の内側だけにしてください。目、あご、眼鏡、頭、ひげ、服装、照明が動いたフレームは採用しないでください。
- 3つの発話フレームすべてから、実用上最小の同一サイズの矩形を切り出します。境界をなじませるために周囲の肌を十分に残しつつ、発話フレームの全体画像は含めないでください。
- 既定では、次のアセットだけをプロジェクトに保存します。
public/avatar/avatar-base.jpgpublic/avatar/mouth-soft.pngpublic/avatar/mouth-round.pngpublic/avatar/mouth-open.png
scripts/validate_avatar_assets.py --dir <project>/public/avatarを実行し、すべての失敗を修正します。
ポートレート全体をアニメーションさせないでください。口のパッチだけを差し替えます。
アプリを構築または統合する
既存の動作するスタックを優先します。新規プロジェクトでは、ユーザーの API キーをサーバールート経由で渡す必要があるため、Next.js または vinext を使用します。安全なバックエンドがすでにある場合に限り、プレーンな Vite を使用してください。
互換性のある新しい Next/vinext プロジェクトでは、実績のあるコアをひな形として使用します。
python3 <skill-dir>/scripts/scaffold_app.py \
--target <project-dir> \
--character-name "Mira" \
--app-name "Mira Live" \
--persona "a concise, curious field researcher" \
--model "<verified-realtime-model>" \
--transcription-model "<verified-transcription-model>" \
--voice "<verified-realtime-voice>"
対象プロジェクトには、フレームワークの設定と依存関係がすでに含まれている必要があります。不足している場合は framer-motion と @phosphor-icons/react をインストールします。置き換えるファイルを確認したうえで、新規初期化したプロジェクトに限り --force を使用します。既存の製品では、アーキテクチャを上書きするのではなく、assets/starter/ から個別のファイルをコピーまたは適応します。
Realtime ルート、API キーのフロー、イベント処理を変更する前に、references/app-contract.md を読んでください。
自然なリップシンクを実装する
references/realtime-lipsync.md を読み、次の動作仕様を守ってください。
- マイク入力や Realtime のイベント発生間隔ではなく、リモート出力の
MediaStreamを解析します。 - React の状態を更新せず、アニメーションフレームごとに音声をサンプリングします。
- 表示する口のポーズの更新頻度は、約 96 ms を超えないようにします。
- アタックと減衰を滑らかにし、ローリングピークを基準に正規化して、短い無音の後に口を閉じます。
- ポーズを飛ばさず、隣接するポーズ(
closed → soft → round → open)へ順に移行します。 - DOM の
data-mouth属性を設定し、CSS でパッチを正確に 1 つだけ表示します。 - ポートレートのピクセルは完全に静止した状態に保ちます。
無限に繰り返す既製の口のアニメーションは使用しないでください。response.output_audio.delta は発話状態を示しますが、リップシンクのタイミングは提供しません。
BYOK のセキュリティ境界を守る
- アプリ内で OpenAI API キーを入力するようユーザーに求めます。
- キーはコンポーネントのメモリ内だけに保持し、local storage、session storage、IndexedDB、アナリティクス、ログ、ソースファイルには決して保存しません。
- HTTPS 経由で、同一オリジンのセッションルートにキーを 1 回だけ送信し、ネゴシエーション後にクライアント側の状態を消去して、
Cache-Control: no-storeを返します。 - 長期間有効なキーを Realtime の WebRTC ピア接続に直接公開しないでください。
- 上流の認証エラーやレート制限エラーは、レスポンス本文やシークレットを表示せず、ユーザー向けの簡潔なエラーに変換します。
引き渡し前に検証する
- 本番ビルドを実行します。
- Lint と、利用可能な場合はスターターの回帰テストを実行します。
- ソースに
AnalyserNode、requestAnimationFrame、90~110 ms のポーズ間隔、隣接ポーズ間のステップ処理が含まれ、CSS の@keyframes mouth-*ループがないことを確認します。 - すべての口のパッチの寸法が同一で、デスクトップとモバイルの両サイズで基準となる口に重なることを確認します。
- 発話中に変化するのが口だけであることを確認します。まばたき、頭の上下動、ポーズのずれ、フレーム全体の切り替えは失敗とみなします。
- マイクのミュート、スピーカーのミュート、中断、トランスクリプトの差分、テキストメッセージ、切断時のクリーンアップ、オーディオコンテキストのクリーンアップ、空の状態、接続エラー、無効なキーのエラーを確認します。
- ユーザーがブラウザーでのビジュアル QA を依頼した場合は、実際の音声ターンをテストし、発話を観察してタイミングを調整します。それ以外の場合は、ブラウザーレベルでリップシンクを視覚的に検証したと主張しないでください。
- 依頼された場合、または有効なホスティングスキルで必要な場合はデプロイし、その後、稼働中の URL を返します。
成果物
実行可能なアプリ、最終的なアバターアセットのパス、生成プロンプトのセット、写真モードと説明モードのどちらを使用したか、その実行で検証した Realtime のモデルと音声、検証結果、および該当する場合はデプロイ済みの URL を返してください。