AIと人間のためのカタログハーネス

Coding Agentと人とで協力して3DCGアセットを育てていくのに、ソースコードを中心としたカタログ化の仕組みを作って運用したらなかなか良い感じだったので共有します。カタログをCoding Agentに直接メンテナンスさせるのではなく、3DCGモデルのPythonコード側にカタログ用のメタデータを記述できるようにしておき、それをビルドするとカタログが出力されるようにしたところ、スムーズにアセットの開発と蓄積が進むようになりました。生成されたカタログデータを人間が確認するためのGUIを用意して運用してきて、アセットの出来栄えの確認やフィードバックもやりやすくなりました。この記事では、カタログシステムの紹介と利点や限界について説明したいと思います。

継続的なアセットの蓄積とカタログ化

前回のブログ記事でCodexとBlenderで大きめの3DCGモデルを、Pythonスクリプトの形で開発する取り組みについて紹介しました。その中で、一度に大きな構造物を作るのではなく、組み合わせ可能な部品を揃えていき、それを組み合わせるとCoding Agentで大きい構造物を作りやすい、という話をしました。Coding Agentの1回のセッションで部品制作と組み立てを終えるのではなく、作った部品を再利用できる形で蓄積していくと、制作した部品群が資産となりより大きなモデルだったり、1回の依頼では作れないようなモデルが作れるようになっていきます。

ただ、部品が増えてくると、ソースコードを全部読まなくても「どういう部品があり、どう使えるのか」を人間とAIの両方が把握できる必要が出てきます。とくに3DCGアセットは、関数名や説明文だけでは実際の見た目が分かりにくく、使う側が毎回レンダリングして確認するのも大変です。また、部品の出来が微妙だと、それを使って組み上げた作品全体も微妙になります。再利用する前提のアセットほど、単体での出来栄え、サイズ感、バリエーション、アニメーション、メッシュの重さなどを確認し、必要ならフィードバックできる画面がほしくなります。そこで、3DCGモデルを継続的に育てるための土台として、アセットカタログを作ることにしました。

コードを正本とするカタログシステム

今回作った仕組みでは、カタログを手書きのデータベースとして管理するのではなく、アセットのPythonコードを正本として扱っています。コードとカタログを二重管理すると、アセットを直したのに説明文やプレビューが古いまま、ということが簡単に起きます。そこで、アセット本体のコードに @asset でカタログ用のメタデータを付け、プレビュー生成用の関数を @asset_demo のようなデコレータで登録する形にしました。

簡略化すると、以下のようなイメージです。アセット定義にはID、タイトル、説明、カテゴリ、タグ、検証用スキーマを持たせ、プレビュー側ではBlenderで画像やGIFをレンダリングしたあと、record でカタログに載せたい情報を記録します。

@asset(
    asset_id="laser-fan-bank",
    title="Laser Fan Bank",
    description=(
        "Pure-emissive laser projectors that fan razor-thin saturated "
        "beams over the audience and scan in time."
    ),
    category="modules/live_stage/lighting",
    tags=["lighting", "live-stage", "laser", "animation"],
    schema=BeamLightingAssetSchema,
    depends_on=["laser.py", "_looks.py", "_render.py"],
)
class LaserFanBank(Component):
    ...


@asset_demo(
    asset_id="laser-fan-bank",
    expected_outputs=[
        "preview.png",
        "views/close_singer.png",
        "animations/fan_scan.gif",
        "laser_fan_summary.json",
        "mesh_metrics.json",
    ],
)
def preview_laser_fan_bank(output_dir: Path) -> None:
    bank = LaserFanBank(...)
    bank.build()

    render_still(..., output_dir / "preview.png")
    render_animation_gif(output_dir / "animations" / "fan_scan.gif")

    record({
        "image": "preview.png",
        "has_animation": True,
        "layout.summary": "laser_fan_summary.json",
        "metrics": {
            "projector_count": bank.layout.projector_count,
            "beam_count": bank.layout.beam_count,
        },
        "demo.animations": [
            {
                "id": "fan_scan",
                "title": "Fan Scan",
                "image": "animations/fan_scan.gif",
            },
        ],
    })

ビルド時には、指定したPythonファイルを読み込んで登録済みのアセットとデモを集め、Blenderを呼び出してプレビュー画像やメトリクスJSONを生成し、最後に asset.yaml としてカタログデータを書き出します。GUI側はこの生成済みのカタログを読むだけなので、アセットの実装と表示用データの責務を分けつつ、正本はあくまでPythonコードに置いておけます。

このやり方の利点は、まずカタログ化そのものを品質管理の流れに組み込めることです。たとえば、メッシュの三角形数、ライト数、バリエーション数、レンダリング時間などをプレビュー生成時に記録しておけば、見た目だけでなく重さなども確認できます。3DCGアセットは「見た目は良いけれど重すぎる」のような問題が起きやすいので、こうしたメトリクスをカタログに一緒に載せられるのは便利でした。

また、アセットの種類ごとに必須項目をスキーマとして用意できます。照明アセットなら正面確認、会場内での見え方、配置デバッグ用の画像を必須にする。アニメーションを持つアセットならGIFやタイムライン情報を必須にする。こうした「最低限ここまでは出してほしい」という足場を先に作っておくと、Coding Agentに実装を任せるときも成果物の形を機械的に揃えることができます。

さらに、レンダリング処理やカタログ登録の作法をカテゴリ別のヘルパーに寄せられるのも良かった点です。アセットを書く側は毎回Blenderの実行方法や出力ファイルの置き場所を考える必要がなく、部品の設計と見た目の改善に集中できます。人間はGUIで一覧し、AIは生成された asset.yaml やメタデータを読んで「どの部品が使えるか」を把握できるので、人とAIの共通の索引としても機能します。

今のところ、人間がイメージするものをAIがコードとして作れる範囲であれば、この仕組みでかなり進められました(微妙な書き方をしているのはこの次で説明します)。Agentが開発中に自身のチェックのためのカタログのビルドを実行すると、自動的にUI上でも結果がみられるようになるので、途中で介入するかどうかの判断もしやすく、共同作業の土台としてかなり使いやすいものになりました。

カタログだけではうまくいかないもの

一方で、カタログだけですべてがうまくいくわけではありません。静止画で確認できる形状や質感はかなり扱いやすいのですが、ライトの動きのような時間方向の調整だったり、見栄えがするような全体の配置、といった部分は言葉だけでは説明が難しく、人間側もやってみないとわからなかったりで、カタログベースでの会話だけでは調整が難しく感じました。

いずれモデルが賢くなると解決される話かもしれませんが(現時点では幻のFable5はかなりアニメーションもかっこいい印象でしたが)、Coding Agentの推論だけで思ったアウトプットになりにくいものについては、カタログとして閲覧するだけのUIではなく、人間が調整できるようなUIというかエディタのようなものを用意して連携する、など工夫がいるように思いました。

最後に

ということで簡単にですが、3DCGの取り組みで使っていたカタログシステムの紹介でした。ハーネスとしてAgent自身の動作を効率化・安定化させつつ、人との連携をスムーズにできるような仕組みは思った以上に強力で、土台が安定している上でのAgentとの3Dアセット作りはとても楽しいものでした。(作ったアセットをならべてカッコいいシーンを作ってもらったのが以下の図。なかなか気に入っています。)

問題によって適する仕組みは違うので、また今後も人とAIの共同作業の仕組みを作って試してみる、というのは継続してやっていきたいです。それでは。