idea_world_labDEV JOURNAL
2026年6月30日火曜日

Qwen Validation Debugger 戦略と実装記録

作成日: 2026 年 6 月 30 日

目的

この文書は tools/qwen-validation-debugger を作成した理由と実際の動作フローを記録する。

6 月 28 日には Qwen で Godot コードチャンクと JSONL を手作業で作成し、プロンプト + コードチャンク + JSONL を直接結合して はい/いいえ がどう出るか確認した。この方法は方向性をつかむには良かったが、項目が増えるにつれて手でコピーし、生成基準を覚えて、結果を比較するコストが大きくなった。

そこで 6 月 30 日にこのプロセスを別のウェブツールとして作った。このツールの目的は最終モデルの学習ではなく、Qwen が生成したテストコードと JSONL が互いにどのような関係にあるかを目で追跡し、誤った はい/いいえ 判定を迅速に発見することにある。

現在の画面

現在のツールは http://localhost:8520/ で実行する。

Qwen Validation Debugger 現在の画面

画面は大きく 3 つの領域に分かれる。

  • 左側: 50 件の Godot テスト項目チェックリスト
  • 中央/右上: 選択した項目の AI ラベルと Godot コード生成結果
  • 下部: docs_chunks, api_mapping, label_prototypes JSONL 生成/検証スロット

なぜ別ツールが必要だったか

元々は Qwen チャットボットに直接次をリクエストした。

Godotコードのチャンクを1つ作成し、  
docs_chunks/api_mapping/label_prototypes形式に合った正解JSONLと不正解JSONLを作成してください。  
そして、SOURCE_CODEとJSONLを結合したときに「はい」/「いいえ」が正しく出力されるか確認します。

しかし手動テストを行ってみると、実際に確認すべき軸が思ったよりも多かった。

確認すべきこと
テスト項目 _ready(), _process(delta), 移動, 衝突, UI, 保存/ロードなど 50項目
文法範囲 Godot 3/4 共通か、バージョン別に分ける必要があるか
コード基準 共通コード 1つまたは Godot 3 コード + Godot 4 コード
テーブル docs_chunks, api_mapping, label_prototypes
JSONL の性質 説明根拠、他のコード説明、変換が必要、すでに適用、共通/不要、無関係変換
検証対象 JSONL を作成したコードと同じコードで検証するか、逆バージョンのコードで検証するか

共通文法であればスロットは 6 つです。

共通コード
  docs_chunks       説明根拠 / 他のコード説明
  api_mapping       共通/不要 / 無関係 変換
  label_prototypes  共通/不要 / 無関係 変換

バージョン分離構文なら、スロットは12個です。

Godot 3 コード
  docs_chunks       説明根拠 / 他のコード説明
  api_mapping       変換必要 / 無関係変換
  label_prototypes  変換必要 / 無関係変換

Godot 4 コード
  docs_chunks       説明根拠 / 他のコード説明
  api_mapping       既に適用 / 無関係変換
  label_prototypes  既に適用 / 無関係変換

これを手作業で作り続けると、テスト自体よりもコピー/貼り付けや結果の整理に多くの時間がかかります。そのため、GUIで項目、コード、JSONL、検証結果を一画面にまとめました。

全体の流れ

flowchart TD
  A["50個のテスト項目"] --> B["項目選択"]
  B --> C["Qwen ラベリング"]
  C --> D{"共通文法ですか?"}
  D -->|"common"| E["共通コード生成"]
  D -->|"separate"| F["Godot 3 コード生成"]
  D -->|"separate"| G["Godot 4 コード生成"]
  E --> H["JSONL スロット 6個"]
  F --> I["Godot 3 基準 JSONL 6個"]
  G --> J["Godot 4 基準 JSONL 6個"]
  I --> K["Godot 3 コード検証"]
  I --> L["Godot 4 コード検証"]
  J --> K
  J --> L
  H --> M["共通コード検証"]

ツールは Qwen を 3 つの役割に分けて呼び出す。

段階 Qwen に指示すること 保存されるもの
ラベリング テスト項目が共通文法かバージョン分離かを判定 classification
コード生成 共通コードまたは Godot 3/4 コードを生成 codes
JSONL 生成 テーブルとスロットの性質に合わせた JSONL を生成 slots[].jsonlText
検証 SOURCE_CODE + JSONL が直接根拠か はい/いいえ を判定 slots[].verifications

ラベリング段階

項目をクリックするとまず Qwen が共通文法かバージョン分離かを判断する。

ラベリング中画面

例えば _process(delta) は Godot 3 と Godot 4 の両方でフレーム更新関数として使用されるため、共通文法とみなすことができる。

共通コードスロット画面

逆に プレイヤー移動速度および加速度の適用 は物理ボディと move_and_slide() の呼び出し方法がバージョンごとに異なる可能性があるため、Godot 3 用コードと Godot 4 用コードを別々に作成する。

バージョン分離スロット画面

JSONL スロット設計

当初はスロットを単に 正解 JSONL不正解 JSONL に分けていた。しかしこの基準はあまりにも粗かった。

docs_chunks は説明根拠である。したがってコードと直接合致する説明であれば はい、別のコード動作を説明する文書であれば いいえ が自然である。

しかし api_mappinglabel_prototypes は単なる説明ではなく、Godot 3 から Godot 4 へ移行する際の変換根拠である。そのため、すでに Godot 4 用に書かれたコードに api_mappinglabel_prototypesはい と付くと、「すでに Godot 4 なのにさらに移行せよ」というように受け取られる可能性がある。

そこでスロット名を次のように変更した。

テーブル コード基準 スロット意味 生成基準期待
docs_chunks 共通/Godot 3/Godot 4 説明根拠 JSONL はい
docs_chunks 共通/Godot 3/Godot 4 他コード説明 JSONL いいえ
api_mapping Godot 3 変換必要 JSONL はい
api_mapping Godot 4 すでに適用 JSONL いいえ
api_mapping 共通 共通/不要 JSONL いいえ
api_mapping すべてのコード 無関係変換 JSONL いいえ
label_prototypes Godot 3 変換必要 JSONL はい
label_prototypes Godot 4 すでに適用 JSONL いいえ
label_prototypes 共通 共通/不要 JSONL いいえ
label_prototypes すべてのコード 無関係変換 JSONL いいえ

この基準のおかげで はい/いいえ が単なる関連性判定ではなく、テーブルの用途に合わせた判定に変わった。

生成基準コードと検証対象コードの分離

今日最も重要になった変更点はこの箇所である。

最初の実装では 1 つのスロットが自分のコードに対してのみ検証されていた。

Godot 3 コードで作成した JSONL  
  -> Godot 3 コードのみで検証  

Godot 4 コードで作成した JSONL  
  -> Godot 4 コードのみで検証

しかし実際に必要な検証はこれより広い。

Godot 3 のコードで作成した JSONL が Godot 4 のコードに貼り付けられたときも いいえ が出る必要がある。逆に Godot 4 のコードで作成した JSONL が Godot 3 のコードに貼り付けられたときにどのような結果になるかも確認しなければならない。そうすれば source/target 文字列が混ざって誤って はい が出る問題を見つけることができる。

そこでボタンを一つから二つに分割した。

Godot 3/4 検証ボタン分離

これでバージョン分離項目の各スロットは次の検証をすべて実行できる。

Godot 3 コードで生成した JSONL
  -> Godot 3 コード検証
  -> Godot 4 コード検証

Godot 4 コードで生成した JSONL
  -> Godot 3 コード検証
  -> Godot 4 コード検証

ツール内部ではこれを次のように分割します。

意味
slot.versionKey JSONL を作成したときに使用したコードバージョン
sourceVersionKey 検証 API に渡す JSONL 作成基準バージョン
targetVersionKey 実際の検証に使用するコードバージョン
slot.verifications.godot3 この JSONL を Godot 3 のコードに貼り付けて検証した結果
slot.verifications.godot4 この JSONL を Godot 4 のコードに貼り付けて検証した結果

期待応答計算基準

検証結果は依然として Qwen から「はい」または「いいえ」で受け取ります。ただし、期待応答はもうスロット一つだけを見て計算せず、テーブル + JSONL 作成基準バージョン + 検証対象バージョン + スロットの性格 を合わせて判断します。

ケース 期待応答
docs_chunks 説明根拠 JSONL を同じバージョンコードで検証 はい
docs_chunks 説明根拠 JSONL を別バージョンコードで検証 いいえ
docs_chunks 他コード説明 JSONL いいえ
Godot 3 基準 api_mapping/label_prototypes 変換必要 JSONL を Godot 3 コードで検証 はい
Godot 3 基準 api_mapping/label_prototypes 変換必要 JSONL を Godot 4 コードで検証 いいえ
Godot 4 基準 api_mapping/label_prototypes 既に適用済み JSONL いいえ
共通コード基準 api_mapping/label_prototypes 共通/不要 JSONL いいえ
無関係変換 JSONL いいえ

この基準は完成した最終評価基準というより、現在の段階で Qwen の根拠マッチングがどこで揺らいでいるかを見るためのデバッグ基準です。

検証プロンプトの変化

検証プロンプトにはこれから二つのバージョン情報が入ります。

JSONL_GENERATED_FROM_CODE_VERSION:
godot3

VERIFY_TARGET_CODE_VERSION:
godot4

このように入れる理由は、Qwen が単に JSONL 内の target_api が現在のコードと合っているからといって はい と答えないようにするためです。

api_mappinglabel_prototypes では次の基準が重要です。

  • source_apisource_patterninput_patternbefore_coderequired_when_seen_in_code が現在のコードに直接存在すれば はい
  • target_apiafter_code、推奨 target 形だけが現在のコードと合っていればすでに適用された状態なので いいえ
  • signature_stableno_changecommon のように変換が不要であることを示す場合は いいえ
  • Godot 4 のコードまたは共通文法コードにマイグレーション JSONL が付いていても追加変換が必要でなければ いいえ

50項目テスト記録

1/50 _ready() 関数の初期化およびビューポートサイズ設定

7月3日に 50項目テストのうち 1番目の項目を先に検証しました。この項目は共通コードとしてラベリングし、基準コードは次のようでした。

func _ready():
    var vp_size = get_viewport().get_visible_rect().size
    position = Vector2(vp_size.x / 2, vp_size.y / 2)

最初は docs_chunks の誤答スロットを 無関係説明 JSONL と呼んでいた。しかし実際にテストしてみるとこの名前は不正確だった。このスロットはあえて異常な、あるいは間違った JSONL を作るための場所ではなく、Retriever が検索候補として取得できる別の公式ドキュメント説明を入れ、Qwen が最終検証で除外できるかを見るための場所である。

したがってこのスロットの意味を 別コード説明 JSONL と整理した。

このテストで問題となった JSONL は Viewport.get_visible_rect_ready() を説明していたが、実際の内容は safe area、UI scaling、$Label$Button.rect_position といった別のコード動作に関する説明だった。SOURCE_CODE はビューポートのサイズを読み取り、現在のノードの position を画面中央に移すコードであるため、いくつかの API が重なっていても直接的な根拠とはみなさない。

期待された回答は いいえ だったが、Qwen は はい を返した。原因は検証プロンプトが 実際の文字列/API 呼び出しと直接一致 を過度に広く解釈するようになっており、同じ API が含まれる別のドキュメント説明までを直接根拠として受け入れた点にあった。

修正内容:

  • docs_chunks 誤答スロット名を 無関係説明 JSONL から 別コード説明 JSONL に変更
  • JSONL 作成プロンプトでこのスロットを「検索候補のように一部 API/テーマが重複する可能性はあるが、実際には別コード動作を説明する公式ドキュメント形式 JSONL」と定義
  • 検証プロンプトで docs_chunksはい 基準を単なる API 文字列一致ではなく、コードの核心目的、対象オブジェクト、最終的な動作/結果が直接合致しているかに強化
  • 同じ API や同じメソッドが出てきても、JSONL が別の目的、別の対象オブジェクト、別の結果を説明している場合は検索候補に過ぎず直接根拠ではないため いいえ と明示
  • フロント UI のスロットラベルとプレビュー文言も同じ基準で調整
  • その基準がプロンプトに保持されているかを確認するために core.test.js にテストを追加

2/50 _process(delta) フレーム別更新ループ

7月3日に 2 項目を検証した。この項目は Qwen が共通コードとしてラベリングした。

ラベリング要約:

syntax_scope: common
label: _process(delta) フレーム別更新
reason: Godot 3 と 4 の両方で _process(delta) 関数のシグネチャと呼び出し方式は同じであり、フレーム単位のロジック作成に文法的な違いはありません。

検証結果は6つのスロットすべてが期待応答と一致した。

項目
スロット数 6
合格 6
不一致 0

今回の項目は共通文法で docs_chunks は説明根拠として はいapi_mappinglabel_prototypes は共通/不要または無関係変換として いいえ が出る流れが正常に動作した事例として記録する。

3/50 プレイヤー移動入力処理

3番目の項目は Qwen がバージョン分離コードでラベリングした。

ラベリング要約:

syntax_scope: separate
label: プレイヤーの移動入力処理
reason: 入力チェック自体は似ていますが、Godot 4で導入された Input.get_vector() と CharacterBody2D の move_and_slide() のシグネチャ変更により、コード構造を分離する必要があります。
godot3_focus: KinematicBody2D 継承、手動で velocity.x/y を計算し、move_and_slide(up_direction) を呼び出す
godot4_focus: CharacterBody2D 継承、Input.get_vector() による対角移動の簡素化と move_and_slide() のパラメータ削除を適用

検証結果:

項目
スロット数 12
検証数 24
合格 20
不一致 4

不一致:

スロット 検証対象 期待 応答 観察
godot3:api_mapping:positive Godot 4 コード いいえ はい Godot 3 基準変換 JSONL を Godot 4 コードに貼り付けても はい が出た。すでに Godot 4 形式であれば関連変換説明があっても現在のマイグレーション適用対象ではない。
godot3:label_prototypes:positive Godot 4 コード いいえ はい label_prototypes · 変換必要 JSONL は現在のコードが変更前の使用方法のときだけ はい であるべきだ。Godot 4 コードに貼ったときに はい が出ると「すでに Godot 4 なのに再度マイグレーションせよ」という意味になり問題になる。
godot3:label_prototypes:negative Godot 4 コード いいえ はい 無関係変換 JSONL は現在のコードが Godot 4 であれ Godot 3 であれ、そのコードに実際に適用する変換でなければ いいえ であるべきだ。
godot4:label_prototypes:negative Godot 3 コード いいえ はい Godot 4 基準で作成した無関係変換 JSONL を Godot 3 コードに貼ったときに はい が出た。これも誤った結果だ。検証質問は「どの程度関連があるか」ではなく「この SOURCE_CODE にこの変換を適用すべきか」であるべきだ。

プロンプト観察:

ハイブリッドサーチではコードチャンクと似た JSONL 候補が一緒に上がるのが自然である。したがって検証プロンプトは検索候補が現在の SOURCE_CODE に実際に適用すべき根拠かどうかを判定しなければならない。3 件の不一致はこの質問が十分に固定されておらず、Qwen が api_mappinglabel_prototypes をマイグレーション必要性ではなく広い関連性マッチングとして解釈した事例である。

特に 3 件目で次の問題が顕在化した。

  • move_and_slide のように Godot 3/4 両方に出現し得る関数名が単独でマッチすると Qwen が はい に傾くことがある。
  • Godot 3 基準 JSONL を Godot 4 コードに貼ったとき、すでに変更後コードであれば label_prototypes · 変換必要はい と出てはいけない。
  • Godot 4 基準無関係変換 JSONL を Godot 3 コードに貼ったときも、現在のコードに実際に適用する変換でなければ はい が出てはいけない。
  • 核心は JSONL の生成方式ではなく検証質問である。現在のコードが変更前コードか、すでに変更後コードか、あるいは全く別の変換かを判定させる必要がある。

したがってプロンプト基準を次のように改めた。

  • 検証質問を「JSONL とコードが関連があるか」から「この JSONL を根拠に現在の SOURCE_CODE にマイグレーションを適用すべきか」に変更する。
  • 現在の SOURCE_CODE がすでに Godot 4 ターゲット形態であれば、JSONL がマイグレーション説明と関連して見えても「すでに適用済み」なので いいえ と明示する。
  • label_prototypes · 変換必要 は現在の SOURCE_CODE が変更前の使用方法、引数構成、呼び出しパターンを実際に含んでいるときだけ はい と明示する。
  • 無関係変換 JSONL は検証対象が Godot 3 コードであっても現在の SOURCE_CODE に適用すべき変換でなければ いいえ と明示する。
  • JSONL の各フィールドは判断文脈である。検証段階ではその文脈を見て現在の SOURCE_CODE が変更前状態か、すでに変更後状態かを判断する。
  • source_api と target_api が同名を共有したり、match_terms に source/target 用語が同時に入ることがあるので、単一関数名や広い match_terms だけが一致しても はい ではないと明示する。
  • 関数名が同じでも呼び出し引数、戻り値処理、継承ノード、周辺コード構造など、JSONL が示す source-side 変更前パターンが SOURCE_CODE に直接残っている場合にのみ はい と明示する。
  • JSONL_GENERATED_FROM_CODE_VERSIONVERIFY_TARGET_CODE_VERSION が異なる場合、現在の SOURCE_CODE が JSONL の変更前コードかすでに変更後コードかをまず区別するよう指示する。

4/50 プレイヤー移動速度および加速度適用

4 番目の項目も Qwen がバージョン分離コードとしてラベリングした。

ラベリング要約:

label: プレイヤーの移動速度と加速度の適用  
reason: Godot 4では物理ノードがKinematicBodyからCharacterBodyに変更され、move_and_slide() のシグネチャが引数渡し方式に変わったため、コード構造が変わります。  
godot3_focus: velocity プロパティに速度を代入した後 move_and_slide() を呼び出し、KinematicBody2D/3D を使用  
godot4_focus: move_and_slide(velocity) で引数を渡し、CharacterBody2D/3D を使用、加速度を適用する際は lerp() または move_toward() を活用

検証結果:

項目
スロット数 12
検証数 24
合格 23
不一致 1

不一致:

スロット 検証対象 期待 応答 観察
godot3:api_mapping:positive Godot 4 コード いいえ はい Godot 3 基準 move_and_slide 変換 JSONL を Godot 4 コードに貼り付けても はい が出た。すでに Godot 4 形式であれば変換説明が関連していても現在のコードにマイグレーションを適用する対象ではない。

プロンプト観察:

4番の不一致は3番より少なかったが、原因は同じです。api_mapping で source と target の関数名が同じか似ていると、Qwen が「この JSONL が該当関数の変更を説明している」という広い関連性判断で はい を付けることがあります。しかしこのツールで必要なのは関連性判定ではなく、現在のコードに適用すべきマイグレーションの必要性です。

したがって 4番までの観察を基準に、検証プロンプトは単なる API 名の一致ではなく次の点を併せて確認するよう強化しました。

  • 現在のコードが JSONL の変更前パターンを実際に含んでいるか
  • 同じ関数名でも呼び出し引数や戻り値の処理方法が変更前コードと合っているか
  • 検証対象コードがすでに変更後の形であれば、マイグレーションの必要性は いいえ
  • 無関係な変換 JSONL が単なる関連性だけで はい に上がっていないか

5/50 プレイヤーの最大速度制限

5番項目は Qwen がバージョン分離コードとしてラベリングしました。

ラベリング要約:

syntax_scope: separate
label: プレイヤーの最大速度制限
reason: Godot 3 の KinematicBody2D と Godot 4 の CharacterBody2D のクラス名変更、move_and_slide() メソッドのシグネチャおよび velocity の伝達方式の違いにより、別途コードが必要である。
godot3_focus: KinematicBody2D 継承、self.velocity に速度を代入した後 move_and_slide() を呼び出し、limit_length() で速度を制限
godot4_focus: CharacterBody2D 継承、velocity 変数に速度を代入した後 move_and_slide(velocity) で明示的に渡し、limit_length() を適用

生成されたコードフロー:

バージョン コアコードフロー
Godot 3 Input.get_action_strength()で入力ベクトルを作成し、velocity = move_and_slide()のように戻り値を再代入した後、velocity.length() > max_speedなら正規化して最大速度を制限する。
Godot 4 extends CharacterBody2D, Input.get_vector(), velocity = direction * max_speed, velocity = velocity.limit_length(max_speed), move_and_slide() フローで記述された。

検証結果:

項目
スロット数 12
検証数 24
合格 23
不一致 1

不一致:

スロット 検証対象 期待 応答 観察
godot3:docs_chunks:negative Godot 3 コード いいえ はい 別のコード説明用 docs_chunks 候補が Godot 3 コードに付いたときに はい が出た。 同じ Godot 3 系列、move_and_slide、速度/衝突処理などの手がかりが重なり、Qwen が検索候補を直接説明根拠として判断したと考えられる。

プロンプト観察:

5番はハイブリッド検索で実際に起こり得る状況に近い。後で DB から検索すると全く的外れな JSONL だけが上がってくるのではなく、同じ API や同じ移動/速度処理系の似た候補が一緒に上がってくることがある。このとき検証プロンプトは「似た検索候補か」ではなく「この JSONL が現在の SOURCE_CODE の実際の動作を直接説明しているか」を見る必要がある。

今回の 5番で api_mappinglabel_prototypes は Godot 3/4 両方の検証で期待通りに動作した。特に Godot 4 コードにすでに適用された形や no_changepattern_validation 性質の JSONL が付いたときに いいえ と判定された点は、以前の 3番/4番で見られたマイグレーション判定問題をある程度緩和したシグナルと見なせる。

逆に docs_chunks はまださらに検討が必要だ。docs_chunks はマイグレーション適用の有無ではなく説明根拠のマッチングなので、同じ API 名や同じバージョン手がかりだけで はい になるとハイブリッド検索候補検証段階でノイズが残る。そのため、今後の検証プロンプトでは docs_chunks について SOURCE_CODE の目的、対象オブジェクト、結果状態が JSONL の説明と実際に同じかをより強く確認すべきである。

6~10/50 追加検証記録

6番から10番まではまず結果を記録し、その後検証プロンプトを修正する順序で進める。今回の段階ではプロンプト修正なしで、現在のツールがどのスロットで正しく、どのスロットで誤っているかだけを残す。

全体概要:

範囲 スロット数 検証数 合格 不一致
6~10番 合計 54 102 97 5

項目別概要:

番号 項目 ラベル コード区分 検証結果
6 マウスクリック時に発射体生成および発射 マウスクリック 発射体生成および移動/衝突 バージョン分離 24/24 合格
7 発射体の移動および寿命(time‑to‑live)管理 発射体 移動および寿命管理 バージョン分離 22/24 合格、2 不一致
8 敵(Enemy)のプレイヤー追跡(AI)ロジック 敵のプレイヤー追跡 AI ロジック バージョン分離 21/24 合格、3 不一致
9 敵の移動速度および回転ロジック 敵 移動速度および回転ロジック バージョン分離 24/24 合格
10 プレイヤーが画面外に出たら消える 画面外脱出時 ノード除去/非表示 共通 6/6 合格

6番、9番、10番は現在の基準ですべて期待値通りに出た。6番は Godot 3 の PackedScene.instance()Input.is_mouse_button_pressed(1)get_viewport().get_mouse_position() の流れと Godot 4 の instantiate()InputEventMouseButtonget_global_mouse_position() の流れが分離され、正解/不正解候補もそれぞれうまく分かれた。9番も敵の移動と回転に関するバージョン分離候補がすべて期待値通りに判定された。10番は共通文法として分類され、get_viewport_rect().sizeglobal_positionhide() に基づく画面外処理で docs の説明根拠は「はい」、api_mapping/label_prototypes 性質のマイグレーション候補は「いいえ」と整理された。

不一致:

番号 スロット 検証対象 期待 応答 観察
7 godot3:api_mapping:positive Godot 4 コード いいえ はい Godot 3 基準の変換 JSONL をすでに Godot 4 コードに検証したのに「はい」と出た。まだ「現在のコードに適用すべき変換か」より「関連する変換か」と読む瞬間が残っている。
7 godot3:label_prototypes:positive Godot 4 コード いいえ はい Godot 3 の source‑side 使用パターンを説明するプロトタイプが Godot 4 コードにも「はい」と付いた。すでに変換済みコードならマイグレーション必要判定は「いいえ」になるはず。
8 godot4:docs_chunks:positive Godot 3 コード いいえ はい Godot 4 の説明根拠が Godot 3 コードにも「はい」と付いた。docs 候補が同じ追跡/移動テーマや似た API 手がかりのため、直接説明根拠として判定されたように見える。
8 godot4:docs_chunks:negative Godot 3 コード いいえ はい 別のコード説明用 docs 候補が Godot 3 コードにも「はい」になった。ハイブリッド検索で似た docs 候補が上がったとき、目的と結果が異なるかをより明確に判断する必要がある。
8 godot4:docs_chunks:negative Godot 4 コード いいえ はい 同じ Godot 4 系でも別のコード説明候補なら「いいえ」になるはずが「はい」と出た。docs_chunks の検証は API 名より SOURCE_CODE の実際の動作目的・対象・結果を強く見るべきである。

観察:

今回の 6~10番を見ると全体的に改善のシグナルがある。102回の検証中 97回が期待値と合致し、6番/9番/10番はすべて合格した。特に共通文法の 10番で api_mapping と label_prototypes がすべて「いいえ」に落ちたのは「共通コードにわざわざマイグレーション根拠を付けない」という方針がある程度機能した事例だ。

残った不一致は二つに分かれる。一つは 7番のように Godot 3 基準のマイグレーション根拠が Godot 4 コードにも「はい」と付くケースだ。この場合、現在のコードがすでに変更後の形か、まだ変更前の形かをより鮮明に問う必要がある。もう一つは 8番のように docs_chunks 候補が同じテーマや似た API のために「はい」と上がってくるケースだ。この場合、説明根拠が SOURCE_CODE の実際の動作を直接説明しているか、単に似た検索候補なのかをよりよく見分ける必要がある。

重要な点は、この問題を特定文字列や特定候補をブロックする方式で解決しないということだ。後で DB に JSONL を入れてハイブリッド検索で取得すると、似ているが異なる候補が一緒に上がってくるのが正常である。したがって、後続の修正は候補を人為的に除外する方式ではなく、検証プロンプトが現在の SOURCE_CODE と検索候補の関係をより正確に判定できるようにする方向で進める。

記録後に適用した検証プロンプトの強化:

  • docs_chunks では JSONL 作成基準バージョンと検証対象バージョンが異なるとき、JSONL が現在の検証対象バージョンのコード動作まで説明しているかをまず確認させた。
  • バージョンが違っても共通 API/共通動作を明示的に説明すれば「はい」になることもあるが、バージョン別のコード構造やノード/API の違いを説明する候補であれば、現在の SOURCE_CODE と同じ動作かどうか別途確認させた。
  • api_mappinglabel_prototypes ではまず現在の SOURCE_CODE が変更前コードか、すでに変更後コードか、無関係コードか、変換不要コードかを判定させた。
  • 「はい」は現在の SOURCE_CODE が変更前コードで、JSONL が示す変換を今適用すべきときだけ許可するよう文を明確にした。
  • この強化は特定文字列を処理する方式ではなく、ハイブリッド検索で上がってきた候補を現在のコード基準で判定する手順を強化したものです。

検証結果確認

検証結果は各スロットの下にバージョン別で別々に表示される。

検証結果画面

この方式で一つのスロット内で次のことをすぐに見ることができる。

Godot 3 コード検証 前 / 応答 / 期待 / 一致の有無  
Godot 4 コード検証 前 / 応答 / 期待 / 一致の有無

以前は「この JSONL が正しい/間違っている」だけが見えていました。今は「どのコードに付けたときに正しい/間違っている」が見えるようになりました。

現在のツールが解決した問題

以前の方式 現在の方式
Qwen チャットボットに直接コードと JSONL を要求 Web UI で項目別にラベル、コード、JSONL、検証結果を蓄積
正解/不正解 JSONL だけを区別 説明根拠、他のコード説明、変換必要、既に適用、共通/不要、無関係変換に分離
Godot 3 JSONL は Godot 3 コードにのみ検証 Godot 3/4 両方のコードに対して検証可能
結果を手作業でコピーして記憶 スロット別に raw response、prompt、検証結果を保存
失敗原因の追跡が困難 どのスロット、どの検証対象で間違っているかをすぐに確認
50 項目テストは事実上手作業 サンプルロード、項目追加/削除、全体生成/全体検証ボタンを提供

開発生産性の変化

ツールを作る前は、テストを一つ行うために次の作業を手作業で行っていました。

1. Qwenにテスト項目の説明  
2. Godot 3 のコードリクエスト  
3. Godot 4 のコードリクエスト  
4. docs_chunks 正解/不正解 JSONL のリクエスト  
5. api_mapping 正解/不正解 JSONL のリクエスト  
6. label_prototypes 正解/不正解 JSONL のリクエスト  
7. 各 JSONL を再度 SOURCE_CODE と結合して検証  
8. はい/いいえ の結果を手書きで記録  
9. 期待値が合っているか頭の中で比較

現在、同じ流れが画面内に固定されています。

1. 項目をクリック
2. AIラベルを作成
3. 共通または Godot 3/4 コードを生成
4. JSONL スロット別に生成
5. Godot 3 コード検証 / Godot 4 コード検証
6. 結果とプロンプト/応答を確認

特に生産性が向上した部分は「速くたくさん作る」よりも「混乱しない」ことに近いです。この作業は単なる生成量よりも判定基準が揺らがないことが重要です。ツールができたことで次のことが楽になりました。

  • 共通文法かバージョン分離かを先に固定
  • テーブル別の JSONL 用途を画面で常に確認
  • 生成基準の期待と実際の検証結果を分離
  • 同じ JSONL を Godot 3/4 のコードで相互検証
  • 失敗したスロットのプロンプトと raw response をすぐに確認
  • 50項目を繰り返すときに人が覚えておくべき状態を削減

まだ残っている問題

このツールはまだ最終評価器ではありません。現在はデバッグツールです。

残っている問題は次のとおりです。

  • docs_chunks の説明根拠がバージョンが違っても共通説明として認められる場合がある。
  • api_mapping で source/target 文字列がすべて JSONL に入ると、Qwen が target 文字列だけを見て「はい」と答えることができる。
  • label_prototypes は単純な文字列一致よりも before/after パターンの区別が重要になることがある。
  • 現在の期待応答計算はデバッグ基準なので、後で実際の score/F1 計算基準は別途整える必要がある。
  • 検索候補選定問題と検証プロンプト判定問題は結果だけ見てすぐに分離するのが難しい。

現在の結論

6月28日には「50件のテストを手作業でやってみよう」という感じでした。実際にやってみるとテストすべき軸が多すぎて、共通文法とバージョン分離、生成基準バージョンと検証対象バージョンが混ざるとすぐに混乱しました。

6月30日にツールを作成したことでこの問題はかなり整理されました。これで Qwen が作った JSONL を単に「正しい/間違い」だけで見るのではなく、どのコードで生成し、どのコードで検証したかまで確認できるようになりました。

このツールはその後 docs_chunksapi_mappinglabel_prototypes の実際の検索結果を付加したときにも同じ方式で使用できます。つまり、手動デモデータだけでなく DB 検索結果の検証にもつながる基盤ツールとなりました。