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", }, ], })
ビルド時にはこの登録用のデコレーターを目印にカタログ化対象のアセットと対応するでも関数を識別し、Blenderの機能を使ってプレビュー画像やメトリクスJSONを生成し、アセットカタログ用のデータ本体である asset.yaml を書き出します。この asset.yaml を含むディレクトリをアセットのカタログデータとして扱う、ということを決めておけば、GUIはこれを読んで一覧表示とアセットの詳細を表示するようなシンプルなローカルようWebアプリとすることで、人間も確認しやすい仕組みが出来上がります。
このやり方の利点を列挙すると、
- コードのみを正本として扱うため管理しやすい(これはすでに述べた通り)
- Coding Agentがレンダリング結果確認のためにカタログビルドを必ず実行するので、作業途中に人間も結果を確認でき、作業の方向性があっているか確認しやすく、介入も早期にできる
- メッシュ数やライト数をメトリクスとして出力するとそこも確認しつつCoding Agentが作業できる。特に、閾値以上だとカタログビルドが失敗するようなルールを追加しておくと、重いモデルが作られてしまうのを機械的に防ぐことができる
- アセットの種類ごとに必須の項目(メトリクスやプレビューの種類)をスキーマとして定義(例えばライトならアニメーションGIFを必ず含むなど)しておくことで、AIと人間の確認に必要な項目の出力を機械的に揃えられる
といったあたりが主な点でしょうか。あとは、アセットとして明示的に「再利用する予定の部品」としてコードを書くことになるので、Coding Agentがわかりやすい名前や公開APIを意識してくれる、というのもあるかもしれません。書き方が揃っていればレンダリングの共通ヘルパーなども書きやすいため、アセットの開発をするエージェントが、毎回Blenderの実行周りを試行錯誤する必要がなく、アセット自体の制作にパワーを割けるのも良い点ですね。
人間のイメージをAIがコードで作れるような類のアセットであれば、この仕組みで数を揃えたり作り込んでいけると思います。
カタログだけではうまくいかないもの
一方で、カタログだけですべてがうまくいくわけではありません。静止画で確認できる形状などは割とうまく作ってくれる印象ですが、ライトの動きのパターンの制作だったり、見栄えがするように複数のアセットを並べたり、といった部分は、人間側もうまく言語化できていない問題もありますが、期待したかっこいいアウトプットにはなかなかならず、カタログベースでの会話だけでは調整が難しく感じました。
いずれモデルが賢くなると解決される話かもしれませんが、Coding Agentの推論だけで思ったアウトプットになりにくいものについては、カタログとして閲覧するだけのUIではなく、人間がパラメータなどを調整できるようなUIを用意して、連携や分担をする、など工夫が要るように思いました。
最後に
ということで簡単にですが、3DCGの取り組みで使っていたカタログシステムの紹介でした。ハーネスとしてAgent自身の動作を効率化・安定化させつつ、人との連携をスムーズにできるような仕組みは思った以上に強力で、土台が安定している上でのAgentとの3Dアセット作りはとても楽しいものでした。(作ったアセットをならべてカッコいいシーンを作ってもらったのが以下の図。なかなか気に入っています。)
問題によって適する仕組みは違うので、今後も人とAIの共同作業の仕組みを作って試してみる、というのは継続してやっていきたいです。それでは。