はじめに
動画生成AIを使っていると、プロンプトがどんどん長くなり、気づけばメモ帳に似たような文章が何十個も並んでいる……という状態になりがちです。「被写体だけ差し替えたい」「カメラワークは前回のものを流用したい」と思っても、長文をコピペして手で直すのはミスのもとです。
そこで私は、プロンプトを 要素ごとにYAMLで管理し、Pythonで1本の文字列に組み立てる 運用に切り替えました。この記事ではその最小構成を紹介します。
方針:プロンプトを5つの要素に分解する
動画向けのプロンプトは、だいたい次の5要素に分けると扱いやすくなります。
| キー | 内容 | 例 |
|---|---|---|
| subject | 何が映っているか | 木のテーブルに置かれた白いマグカップ |
| motion | 何がどう動くか | 湯気がゆっくり立ちのぼる |
| camera | カメラの位置・動き | ローアングルからゆっくりドリーイン |
| lighting | 光の質・時間帯 | 窓からの柔らかい朝の自然光 |
| aspect | 画面比率 | 9:16 |
要素を分けておくと、「camera だけ3パターン試す」といった比較がとても楽になります。
YAMLファイルの例
shots.yaml に共通設定(defaults)とショットごとの設定を書きます。ショット側で書いたキーだけが defaults を上書きする仕組みです。
defaults:
lighting: 窓からの柔らかい朝の自然光
aspect: "9:16"
shots:
- id: mug_01
subject: 木のテーブルに置かれた白いマグカップ
motion: 湯気がゆっくり立ちのぼる
camera: ローアングルからゆっくりドリーイン
- id: mug_02
subject: マグカップを両手で包む人の手元
motion: 指先がわずかに動く
camera: 真上からの固定ショット
lighting: 夕方の暖色の逆光
aspect は "9:16" のようにクォートしておくのがポイントです。クォートしないと YAML 1.1 のパーサーによっては 9:16 が六十進数として数値に解釈されることがあります。
Pythonで組み立てる
PyYAML(pip install pyyaml)だけで動きます。
import sys
import yaml
ORDER = ["subject", "motion", "camera", "lighting"]
def build_prompt(shot: dict, defaults: dict) -> str:
merged = {**defaults, **shot}
missing = [k for k in ORDER + ["aspect"] if not merged.get(k)]
if missing:
raise ValueError(f"{shot.get('id', '?')}: 不足しているキー {missing}")
body = "、".join(str(merged[k]) for k in ORDER)
return f"{body}。画面比率 {merged['aspect']}。"
def main(path: str) -> None:
with open(path, encoding="utf-8") as f:
data = yaml.safe_load(f)
defaults = data.get("defaults", {})
for shot in data["shots"]:
print(f"[{shot['id']}] {build_prompt(shot, defaults)}")
if __name__ == "__main__":
main(sys.argv[1] if len(sys.argv) > 1 else "shots.yaml")
実行結果はこうなります。
$ python build_prompts.py shots.yaml
[mug_01] 木のテーブルに置かれた白いマグカップ、湯気がゆっくり立ちのぼる、ローアングルからゆっくりドリーイン、窓からの柔らかい朝の自然光。画面比率 9:16。
[mug_02] マグカップを両手で包む人の手元、指先がわずかに動く、真上からの固定ショット、夕方の暖色の逆光。画面比率 9:16。
キーが欠けている場合は ValueError で止まるので、「カメラ指定を書き忘れて生成してしまった」という事故を防げます。
運用してみて良かった点
- 差分が見やすい:YAMLをGitで管理すると、どの要素を変えたら結果が良くなったのかが履歴で追えます。
-
比較実験がしやすい:
cameraだけ違うショットを並べれば、カメラワークの影響を切り分けて確認できます。 - 言語の切り替えが楽:要素ごとに英語版のYAMLを用意すれば、ツールに合わせて言語を変えるのも簡単です。
逆に注意点として、要素を「、」でつなぐだけなので、文章としての自然さは多少犠牲になります。気になる場合は build_prompt の中でテンプレート文字列(例:"{subject}。{motion}。カメラは{camera}。")を使うように変えると読みやすくなります。
おわりに
プロンプトを「文章」ではなく「データ」として扱うだけで、試行錯誤のスピードがかなり変わりました。生成ツールが変わってもYAMLはそのまま使い回せるのも利点です。私は普段、ここで組み立てたプロンプトを Everygen に貼り付けて動画を試作していますが、どのツールを使う場合でも同じ考え方で応用できると思います。
ぜひ自分なりのキー構成を作ってみてください。