本文へ移動
cccskills
無料GitHub で公開

narration-qa

ElevenLabsで生成したナレーション音声の品質を自動検証するスキル。「ナレーションチェック」「音声確認」「発音チェック」等のリクエストで発動。

インストール方法を見る

含まれるファイル(4)

  • SKILL.md12.7 KB
  • agents/openai.yaml157 B
  • SKILL.en.md1.1 KB
  • SKILL.es.md1.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Narration QA Skill

ElevenLabsで生成したナレーション音声の品質を自動検証するスキル。 ナレーション生成時は必ずこのスキルのフローに従うこと。

トリガー

  • ナレーション生成後の品質チェック依頼
  • 「ナレーションチェック」「音声確認」「発音チェック」
  • ナレーション生成を含むすべてのMV制作タスク(自動適用)

Step 0: TTS入力テキストのルール(生成前に必ず適用)

英語IT用語の日本語化ルール

英語をそのまま残すとElevenLabsが誤読する。全英語を日本語表記に変換してから生成する。

ルール例
定着カタカナがあればそれを使うGitHub→ギットハブ, Slack→スラック, Gmail→ジーメール, Google Drive→グーグルドライブ
カタカナ音写が不自然→日本語に意訳TODO→タスク, workflow→ワークフロー
ブランド名はカタカナClaude Code→クロードコード(中黒なし), LINE→ライン
略語はひらがな読みAI→えーあい, PMO→ぴーえむおー, PPTX→パワーポイント
固有名詞が誤読される場合→一般語に置換Claude Code→AIエージェント, GitHub Actions→自動ワークフロー

⚠️ 過剰ひらがな化の禁止(重要)

全文ひらがな化はTTSモデルを壊す。 PersonalPMODemo v3の実験で、以下が確認された:

  • ぴーえむおー → ElevenLabsが「ピアノ」と発音
  • えーあい → 「Eoi」と発音
  • 全ひらがな文 → リズム崩壊、意味不明な発音

正しいアプローチ: 自然な漢字かな混じり文をベースに、既知の誤読漢字のみをひらがな化する。

漢字のひらがな化ルール(選択的に適用)

ElevenLabs eleven_multilingual_v2 は特定の漢字を誤読する。以下のパターンに該当する漢字のみひらがなに置換する。それ以外の漢字はそのまま残す。

誤読パターン原因対策
返信→阪神音が近い漢字に化ける「へんしん」にひらがな化
受信→閉める漢字誤読「届いた」等の平易な表現に言い換え
議事録→石立漢字誤読「ぎじろく」にひらがな化
各→夫は単漢字の誤読「それぞれの」に言い換え
即座に→危機座に漢字誤読「すぐに」に言い換え
承認→チョンキン中国語発音混入「しょうにん」にひらがな化
税理士→推理師中国語発音混入「ぜいりし」にひらがな化
成果→成功類似音「せいか」にひらがな化
マッキンゼー→松銀瀬固有名詞の崩壊「コンサル」等の一般語に言い換え

原則: 上記テーブルに該当する漢字のみひらがな化。それ以外は自然な漢字かな混じり文のまま残す。自然な漢字かな混じり文 > 安全のために全ひらがな化(TTSモデルが壊れるため)。

ひらがな化すべきか? — 決定木

漢字を見つけた
→ 上記の誤読リストに該当する → ひらがな化する
→ リストにないが不安
  → ElevenLabsで1クリップだけテスト生成 → Gemini検証
    → 誤読あり → ひらがな化 or 平易な表現に言い換え → リストに追記
    → 問題なし → 漢字のまま残す
→ リストにない+一般的な漢字 → 漢字のまま残す(過剰ひらがな化しない)

数字の展開ルール

数字は全てひらがなで書く:

  • 7つの → ななつの
  • 8種類 → はっしゅるい
  • 12,800円 → いちまんにせんはっぴゃくえん
  • 95% → きゅうじゅうごパーセント

避けるべきパターン

NG理由OK
英語をそのまま残すElevenLabsが誤読全てカタカナ/ひらがな化
「トゥードゥー」「クロード・コード」日本語として不自然「タスク」「クロードコード」
同一用語の表記揺れ混乱統一表記
1文が長すぎる早口/尺超過7文字/秒を目安に分割

Step 1: 原稿の事前チェック(生成前)

1a. Step 0のルール適用確認

原稿テキストに以下がないことを確認:

  • 英語のまま残っている単語
  • 誤読リスクのある漢字(上記テーブル参照)
  • 展開されていない数字
  • 同一用語の表記揺れ

1b. 尺チェック

  • 各セグメントのテキスト文字数から推定発話時間を算出(目安: 日本語7文字/秒)
  • シーン尺(end - start)と比較
  • atempo 1.35x を超える場合は原稿を短縮すること(それ以上の加速は不自然)
  • 略語をフル読み(えーあい等)にすると尺が伸びる → 短い窓のシーンは特に注意

1c. 文体統一チェック

  • 「です・ます」調で統一されているか
  • 体言止めが混在していないか(Openingのキャッチコピーは例外OK)
  • 主語の省略が自然か

Step 2: 音声生成

ElevenLabs設定

voice_settings = {
    "stability": 0.70,       # 0.75以上だと棒読み感
    "similarity_boost": 0.80,
    "style": 0.10,            # 0.15以上だと抑揚過多
    "use_speaker_boost": True
}
model_id = "eleven_multilingual_v2"

生成後の尺チェック

# 各セグメントの尺を確認
for f in data/narration/s*.mp3; do
  dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f")
  echo "$f: ${dur}s"
done
  • ratio = audio_duration / scene_window を計算
  • ratio > 1.35 → 原稿を短縮して再生成(atempo で無理に収めない)
  • ratio <= 1.35 → ffmpeg -af "atempo={ratio}" で速度調整

Step 3: Gemini Flash 書き起こし検証(必須)

生成後、必ず全セグメントをGemini Flashで書き起こし検証する。省略不可。

実行コード

from google import genai
import json, os, time

client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))

with open("data/narration_script.json") as f:
    segments = json.load(f)

results = []
for seg in segments:
    sid = seg["id"]
    audio_file = client.files.upload(file=f"data/narration/{sid}.mp3")
    response = client.models.generate_content(
        model="gemini-3-flash-preview",
        contents=[
            "この日本語音声を正確に書き起こしてください。句読点も含めて。テキストのみ返してください。",
            audio_file
        ]
    )
    transcription = response.text.strip()
    # 原稿と照合
    print(f"{sid}:")
    print(f"  Script: {seg['text']}")
    print(f"  Heard:  {transcription}")
    results.append({"id": sid, "script": seg["text"], "heard": transcription})
    time.sleep(1)

# 結果をJSONに保存
with open("data/narration_qa_results.json", "w") as f:
    json.dump(results, f, ensure_ascii=False, indent=2)
print(f"\nQA results saved to data/narration_qa_results.json")

モデル選択: gemini-3-flash-preview を使用(2.0/2.5 Flash より日本語音声認識精度が大幅に向上)。

NG判定基準

深刻度条件対処
Critical意味が完全に変わる(返信→阪神、議事録→石立)原稿のひらがな化 → 再生成 → 再検証
Major固有名詞が別の単語に化ける(クロードコード→黒度思うこと)表現を言い換え → 再生成
Minor音は近いが漢字表記が異なる(同期→登記、成果物→性格物)Gemini STTの限界。人間の耳で許容範囲ならOK
Pass書き起こしと原稿の意味が一致そのまま使用

再生成ループ — 決定木

Gemini検証でNGが出た
→ Critical(意味が変わる)
  → 原稿のひらがな化 or 言い換え → 再生成 → 再検証
  → 2回目もNG → 文章構造自体を大幅に書き直す → 再生成 → 再検証
  → 3回目もNG → そのセグメントを削除 or シーンからナレーションを外す
→ Major(固有名詞崩壊)
  → 一般語に置換(例: クロードコード→AIエージェント)→ 再生成 → 再検証
→ Minor(漢字表記が異なるだけ)
  → Gemini STTの限界の可能性あり。実音声を聴いて許容範囲なら Pass とする(自動Passにしない)
→ Pass → そのまま使用

最大3ラウンド。3回でもCriticalが残るなら該当セグメントのナレーションを諦める。


Step 4: 音量バランス調整 & 最終ミックス

音量ルール

トラックvolume備考
ナレーション1.5メインコンテンツ。BGMより明確に大きく
BGM0.06ナレーションの邪魔をしない。存在感は感じる程度
BGM (ナレーションなし区間)0.15 - 0.20Opening/Closingなどナレーションがない区間はBGMを上げてOK

判定: 実音量比でナレーションがBGMの4倍以上であること。

⚠️ amix禁止 — amerge+pan を使う

ffmpeg amix は入力をN分割して正規化するため、volume設定が無視される。 必ず amerge + pan を使うこと。

# ナレーション全体をタイミング配置
# (adelay で各セグメントを配置 → amerge で結合)

# 動画 + BGM + ナレーションを一発ミックス (amerge + pan)
ffmpeg -y \
  -i out/video.mp4 \
  -i data/bgm.mp3 \
  -i data/narration_mix.mp3 \
  -filter_complex "\
    [1:a]volume=0.06,afade=t=out:st={total-4}:d=4[bgm];\
    [2:a]volume=1.5[narr];\
    [bgm][narr]amerge=inputs=2,pan=stereo|c0=c0+c2|c1=c1+c3[out]" \
  -map 0:v -map "[out]" -c:v copy -shortest \
  out/video_narrated.mp4

amix vs amerge の違い:

  • amix=inputs=2: 各入力を ÷2 に正規化 → BGM 0.06×0.5=0.03, ナレーション 1.5×0.5=0.75 → 比率は保つが全体音量が低下
  • amerge + pan: 正規化なし。volume値がそのまま反映される → 意図通りの音量バランス

Step 5: QA結果の報告

報告フォーマット

| Seg | Script (先頭30字) | Gemini書き起こし (先頭30字) | 判定 | 対処 |
|-----|-------------------|---------------------------|------|------|
| s00 | えーあい パーソナル... | AIパーソナル... | Pass | — |
| s03 | メッセージからタスクを... | メッセージからタスクを... | Pass | — |
| s06 | 閉めるを確認し... | 届いたメールを確認し... | NG | ひらがな化→再生成 |

トレードオフ判断基準

  • 原稿を短くして尺に収める > atempo 1.35倍超で無理に収める(不自然な早口になる)
  • 既知の誤読漢字のみひらがな化 > 安全のため全文ひらがな化(TTSが壊れる)
  • amerge+panで正確な音量制御 > amixで手軽にミックス(音量が崩壊する)
  • Gemini検証でMinor判定をPassにする > 完璧を求めて再生成ループを回し続ける(3回が上限)

Tone(QA報告時)

  • 検証結果は事実ベースで簡潔に。「Script」「Heard」「判定」の3列テーブルで報告
  • NGの場合は「原因 → 対処」を1行で添える(例: 「承認→チョンキン: 中国語発音混入 → しょうにんにひらがな化」)
  • 全セグメントPassの場合も省略せずテーブルを出す(確認の証跡として)

依存

  • ElevenLabs API: ELEVENLABS_API_KEY in .env
  • Gemini API: GEMINI_API_KEY in .env
  • ffmpeg: 音声処理用
  • pip: google-generativeai パッケージ(uv add --user --break-system-packages google-generativeai)

ファイル構成

data/
  narration_script.json    # ナレーション原稿(タイミング付き)
  narration/s00.mp3        # 各セグメントの生成音声
  narration/s00_fit.mp3    # 速度調整済み音声
  narration_mix.mp3        # ナレーション全体ミックス
  audio_final.mp3          # BGM + ナレーション最終ミックス
  bgm.mp3 / bgm_extended.mp3  # BGM
  narration_qa_results.json    # Gemini検証結果ログ

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

ab-test-setup

無料日本語概要

A/Bテストや実験の設計・実装を支援するスキル。 「A/Bテストを設計して」「スプリットテストしたい」「仮説を立ててテストしたい」「バリアントを比較」等のリクエストで発動。 トラッキング実装は analytics-tracking を参照。

minicoohei/ai-agent-camp3472026年10月7日 更新

agent-designer

無料日本語概要

マルチエージェントシステムのアーキテクチャ設計ツールキット。 「エージェントを設計して」「マルチエージェント構成」「エージェントのアーキテクチャ」「オーケストレーション設計」等のリクエストで発動。

minicoohei/ai-agent-camp3472026年10月7日 更新

aiagent-check-setup

無料日本語概要

ai-agent-campのローカル環境セットアップを確認するスキル。 「セットアップ確認」「環境チェック」「初期設定できてる?」「インストール確認」「依存関係チェック」等のリクエストで発動。

minicoohei/ai-agent-camp3472026年10月7日 更新

aiagent-command-router

無料日本語概要

ai-agent-campのスラッシュコマンドをCodexでルーティングするスキル。 「/start-0-1を実行」「スラッシュコマンドを使いたい」「コマンドルーティング」「Cursorのコマンドを使いたい」等のリクエストで発動。

minicoohei/ai-agent-camp3472026年10月7日 更新

aiagent-env-manager

無料日本語概要

ai-agent-campの環境変数・認証情報を安全に管理するスキル。 「APIキーを設定」「.envを管理」「環境変数の設定」「credential managerを使いたい」「秘密情報の管理」等のリクエストで発動。

minicoohei/ai-agent-camp3472026年10月7日 更新

aiagent-guide

無料日本語概要

ai-agent-campリポジトリの案内・オリエンテーションスキル。 「リポジトリ案内」「次のレッスンは?」「どこから始める」「ツールの違い」「aiagent概要」等のリクエストで発動。

minicoohei/ai-agent-camp3472026年10月7日 更新

minicoohei のスキルをすべて見る

このスキルの問題を報告する