AI Navigate

[P] LLMコード生成のフィードバックループとしての視覚的検証

Reddit r/MachineLearning / 2026/3/13

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical UsageModels & Research

要点

  • この投稿はテキストプロンプトから Godot のゲームを自律的に生成するパイプラインの構築について論じ、単なるコンパイルを超えたLLM生成GDScriptコードの検証に焦点を当て、トレーニングデータセットにおけるGDScriptデータの制限という課題に対処します。
  • 正確なAPI使用を改善し幻覚を抑えるための3層リファレンスシステム(手書きの言語仕様、850超のエンジンクラスの全APIドキュメント、エンジンの癖データベース)を導入します。
  • 常時ロードされる約128クラスの小さなインデックスと、必要時に読み込む約730クラスの大きなインデックスという、2層のコンテキスト戦略によるエージェント的遅延ロードを提案します。各タスクは新しいフォーク済みコンテキストで実行されます。
  • 成功はコード生成のステップだけでなく、文脈管理の決定に左右されると論じます。
  • 検証は3段階を概説します。Godotのヘッドレスモードでのコンパイルから始まり、広範な検証ワークフローの一部として、構文エラーや型不一致を検出します。

テキストプロンプトからプレイ可能な Godot ゲームを生成する自律的なパイプラインを構築しました。ここで論じるべき二つの問題は、トレーニングデータで十分に表現されていない言語に対してLLMに正しいコードを書かせる方法と、単なるコンパイルを超えた正確性の検証方法です。これは論文ではありません — コードはオープンソースで、結果は再現可能です。こうした作業にはこれの方が有用だと考えています。

文脈からのワンショットコーディング、トレーニングデータではなく文脈から:

GDScriptはGodotのスクリプト言語です — 約850クラス、Pythonのような構文ですがPythonではありません。LLMの学習データにはGDScriptが相対的に少なく、構文を概ね正しくするには十分でも、エンジンの850クラスAPIを安定して使えるほどではありません。文脈内に参照資料がなければ、幻覚的なメソッドや作られたパターンを出してしまいます。参照資料を提供すると、質問は次のように変わります: モデルはそれを適切に使えるのか、という点です。これは、提供されたドキュメントをどれだけうまく活用できるかを、トレーニング優先度に頼るかどうかという真のベンチマークになります。

参照システムには3層あります:

  • 手書きの言語仕様 — チュートリアルではなく、GDScriptがモデルの期待とどこで分岐するかを正確に示す参照です( instantiate() が Variant を返すため型推論が失敗する、ポリモorphic な組み込みが明示的な型指定を必要とする、Python とは異なる lambda キャプチャの意味論 など)
  • 850超のエンジンクラス全体のAPIドキュメントを、Godot の XML ソースからコンパクトな Markdown に変換したもの
  • エンジンの癖データベース — ドキュメントだけでは気づきにくい挙動(例: MultiMeshInstance3D がシリアライズ後にメッシュ参照を黙って失う、ヘッドレスのシーン構築中に _ready() が呼ばれない、コールバック内の衝突状態の変化が黙って破棄される)

エージェント的な遅延ロード — コンテキスト管理の問題:

850クラスのド docs を一度に読み込むことはできません — それはコンテキストウィンドウ全体を消費します。ですが、エージェントが間違ったサブセットを選ぶと、見えないAPIに対してコードを書いてしまいます。その結果は、エージェントが自分の文脈を選ぶ能力に直接結びつきます。多すぎると推論が文書に埋もれ、少なすぎると必要なクラスを見逃します。

解決策は二層の遅延探索です。小さなインデックス(約128の共通クラス、各クラス1行)が常に読み込まれます。続くインデックスは残りの約730クラスをカバーします。エージェントはこのインデックスを確認し、その瞬間に必要な特定のクラスの完全なドキュメントだけを読み込みます。各タスクはフォークした文脈(新しいウィンドウ、累積状態なし)で実行され、文脈管理の判断はタスクごとにリセットされ、時間とともに劣化しません。

ここからがシステムの成否を決定づける部分です — コード生成の成否ではなく、文脈の選択にかかっています。

検証の3段階:

  1. コンパイル — Godot のヘッドレスモードが構文エラー、型の不一致、参照の欠落を検出します。これが最も簡単なフィルターです。
  2. エージェント的なスクリーンショット検証 — コーディングエージェント(Claude Code)は実行中のシーンからスクリーンショットを取得し、基本的な自己評価を行います。シーンがレンダリングされるか、期待される要素が存在するか、重大な破綻がないか。これは安価で大きな不具合を検出します。
  3. 専用の視覚品質保証エージェント — 別の Gemini Flash エージェントがスクリーンショットと参照画像を受け取り、タスク固有の基準に対して構造化検証を実行します。静止モード(地形/UIのための1フレーム)または動的モード(物理/アニメーションの2 FPSシーケンス — 時間的整合性を評価、単一フレームだけではなく)で動作します。コーディングエージェントが自分の出力について客観的に判断できない点を検出します。例えば、Zファイティング、浮遊物体、物理的爆発、自然な有機的配置であるべきグリッド風の配置、変化が指定されていた場合の一様なスケーリングなどです。

この分離は重要です。コーディングエージェントは自分の出力に偏りがちです。コードへのアクセスを持たず、レンダリング結果のみを見て独立した検証を行う別のビジョンエージェントが中立的な検証を提供します。

これが成し得ること:

寄稿の意図を明確にするために: これらの要素が揃う以前は、パイプラインは一貫してプレイ不能なゲームを作っていました — 衝突の破損、物理爆発、相互作用の欠落、視覚的アーティファクトなど。しばしばエージェントは検証を完全に回避し、チェックを技術的には通過する garbage output を出すことがありました。上で述べた各コンポーネントは、その閾値を超えるために必要でした。これは、動作するベースラインに対する段階的な改善ではなく、ベースライン自体が機能していませんでした。貢献は、全体として機能させる組み合わせです。

アーキテクチャ:

パイプラインはゲーム開発を段階に分解します(視覚ターゲット → 分解 → アーキテクチャ → アセット生成 → 検証付きタスク実行)。段階は対話ではなく、構造化された文書を通じて伝達されます。各タスクは新しい文脈をフォークします。生成された GDScript は、シーンビルダー(.tscn ファイルを直列化するヘッドレスプログラム)とランタイムスクリプト(ゲームロジック)に分割され、どの段階でどの API が利用可能かを厳密に区分します。

出力は Godot 4 の完全なプロジェクトです — シーン、スクリプト、生成された 2D/3D 資産。

この投稿は技術的な発見に焦点を当てていますが、完全なストーリーは—1年分の誤った道、4つの大規模なアーキテクチャの書き換え、そして機能しなかったすべての要素—詳細なブログ投稿として後日公開されます。「どうやってここに至ったのか」という過程に興味がある場合は、それを楽しみにしていてください。

4つのデモ — プロンプト → プレイ可能なゲーム: https://youtu.be/4_2Pl07Z7Ac コードは GitHub にあります https://github.com/htdt/godogen 。Twitter/X でも活動しています https://x.com/alex_erm。ブログ投稿が出たらこちらで共有します。

ここで質問にお答えします。