AIが出した根拠は、正しいものと誤ったものが同じ形で並ぶ

AIが出した根拠は、正しいものと誤ったものが同じ形で並ぶ

AIにUIを生成させたところ、既存コンポーネントが使われませんでした。その理由としてAIが挙げた記述を実装と突き合わせたところ、一部は正確で、一部は事実と違っていました。両者が同じ形で並ぶこと、そしてどちらかを事後に判別できなかった経緯を記録しています。
2026.09.09

この記事について

前回の記事で、AIにUI画面を自律的に生成させるためのコンテキストファイルの設計について書きました。何を書き、何を書かなかったかの記録です。末尾で、立てた規則がどこまで通用するかは分からない、当たり外れも記録として残す、と書きました。

その続きです。生成を実行し、結果を見て、コンテキストの指示を書き換えました。改善した部分があります。そのうえで、改善しなかった部分について、なぜ改善しなかったのかを特定できないという状態に行き当たりました。

本記事の主題は最後のものです。前回はコンテキストに何を書くかを扱いました。今回はその一段外側、書いたものが実際に参照されたのかどうかを確かめられない、という問題を扱います。

条件は前回と同じです。入力はコードとコンテキストファイル。デザインデータは生成時にAIへ渡していません。役割分担も同じで、検証は実装コードと実測値、記事化はLLM、事実確認と判断は筆者です。

先に、前回末尾で置いた予測について触れておきます。効くはずだと書いたものと、不安だと書いたものがありました。結論から言うと、そのどれもが今回のテストでは測る対象になりませんでした。外れたのではなく、測っていません。検証の焦点が別の層に移ったためです。以下はその移った先の話になります。


明示すれば直る、ただしその先がある

生成を実行したところ、画面の一部が意図と違う形で組まれました。ある領域を表形式で組ませたかったのですが、画面幅の広い環境でもカード形式のコンポーネントが使われていました。

原因を追うと、コンポーネントの名前が、こちらの書いた指示より強く効いているという状況が見えました。参照先の名前が特定の形式を想起させると、そちらに引かれる。

前回の記事は「明示的に書けば伝わる」という前提の上に立っています。書くべきことを選別し、規則として宣言すれば従う、という前提です。それ自体は間違っていませんでしたが、書いていない領域はコンポーネント名に引かれて埋まる、という補足が必要でした。

そこでコンテキストファイル側に、画面幅の広い環境では表形式を使う、という記述を明示的に追加しました。

結果は改善です。その後の生成では、意図した構造が出力されるようになりました。ここまでは、前回の設計方針がそのまま通用した形です。

問題はその先で出ました。

構造は表形式で組まれた。しかし、そのために用意されている既存のコンポーネントが、1つも使われていませんでした。


コンポーネントが使われなかった、その理由を確かめる

使われなかったのは見出しもセルも同じで、すべて素の要素にトークンを当てる形で組まれていました。

人手で作った版では、その領域の見出しすべてに同じコンポーネントを1つ使っています。同じ画面を、同じライブラリを参照して組んでいるはずなのに、片方はコンポーネントを使い、片方は使わなかった。

まず、比較の限界を書いておきます

先に断っておくと、この2つは同じ条件で作られたものではありません。

人手版はデザインデータを見ながら組みました。前回書いたとおり、サンプル画面は規則を導くための材料なので、そういう作り方になります。一方のAI版には、デザインデータを渡していません。渡したのは要件記述とコンテキストファイルだけです。

つまりAI版には、視覚的な正解が与えられていない状態でした。この違いがある以上、「人手版は使えたのにAI版は使えなかった」を優劣として読むことはできません。

以下で扱うのは、そこではありません。AIが不採用の理由として書いた記述が、コードの事実と一致しているかどうかです。これはコードを読めば判定できるので、条件の違いの影響を受けません。

実行ログに書かれていた理由

ログを読むと、同じ系統に属する4つのコンポーネントが、まとめて1つの理由で外されていました。要約すると、個々には使えなくはないが、複数の要素を一体的に揃えるための寸法指定と、これらの持つ固定幅が噛み合わない、というものです。固定幅については具体的な数値も併記されていました。

そこで、まず1つを実装で確認しました。結果は記述と違いました。ルート要素は親から渡された幅に従う指定になっていて、固定幅ではありません。人手版が見出しすべてに使っているのは、まさにこのコンポーネントでした。

ここで一度、こう考えました。ひとつの誤った前提が、コンポーネント群をまとめて排除したのではないか。読み物としては分かりやすい話です。

残り3つを確認したら、予想は外れた

確認結果はこうでした。

ルート要素の幅指定 ログの記述との一致
A(前述) 親の幅に従う 不一致
B 指定なし 不一致
C 固定値 一致
D 固定値 一致

4つのうち2つは、実際に固定幅でした。しかもログに併記されていた数値は、この2つの実装値と一致しています。

誤りではなかった。少なくともこの2つについては、コードを読んで正確に書いています。


正しい根拠と誤った根拠は、同じ形をしている

この結果のほうが、当初の予想より厄介だと考えています。

4つは、ログの上では1つの記述にまとめて括られています。文面は均一で、しかも具体的な数値が添えられている。数値が実装と一致している以上、少なくとも一部は実際にコードを読んでいます。

にもかかわらず、その記述は残り2つには当てはまりません。

そして出力を読む限り、4つのうちどれが確認に基づいていて、どれが推定なのかは判別できません。数値の裏付けがあることで、むしろ全体が確認済みに見える。根拠が書かれていない場合より、こちらのほうが検出しにくい。

同じことは、別の生成でも観測しています。判断を委ねた3箇所について後から根拠を尋ねたところ、根拠があったのは1箇所だけでした。残り2箇所は「根拠なく判断した」と申告されています。ただしそれは、こちらが尋ねたから分かったことです。尋ねなければ、ビルドは通り、見た目も破綻せず、ログ上は成功として記録されていました。

追えたものと、追えなかったもの

ここで、自分が何を確かめられたのかを整理しておきます。

確かめられたのは、コードの事実です。4つのコンポーネントがそれぞれどう実装されているか。これは読めば確定します。実際、確認そのものは数分で終わりました。

確かめられなかったのは、AIが4つのうちどれを実際に参照したかです。

数値が一致していることから、2つは読んだと推定できます。しかし推定です。残る2つについて、読んだうえで誤ったのか、読まずに群の特徴として広げたのかは分かりません。

ここで、実行時の操作記録を探しました。使っているツールは、ファイルを読む操作をツール呼び出しとして記録します。人手で作業したセッションを開くと、実際にどのコンポーネントを開いたかが1件ずつ残っていました。

しかし、生成を実行したときの記録は手元にありませんでした。残っていたのは、AIに書かせた実行ログのほうだけです。

つまり照合できる材料が、検証したい当の対象、すなわちAIの自己申告しかない状態でした。そしてその自己申告は、今回の確認で一部が事実と違うと分かったものです。

これは仕組みの問題ではなく、こちらの設計の抜けです。操作記録を保全しておけば追えたはずでした。ただ、保全すべきだと分かったのは、追う必要が出たあとです。実行の時点では、自己申告と実装結果を突き合わせれば足りると考えていました。実際その方法で、4つのうち2つが事実と違うところまでは確定しています。足りないと分かったのは、その先の「どれを読んだのか」を問うた時点でした。

残ったものにも偏りがあります。AIに書かせた記録は残り、実際の操作の記録は消えました。前者のほうが用意するコストが低いからです。安いほうだけが残った、ということになります。

前回、AIが生成した記述は裏取りするまで判断材料にしない、という原則を書きました。その裏取りに使うはずの材料が、同じ性質のものしか手元になかった、という形です。

だから、失敗を分類できない

前回、再現できなかった差分を台帳に残す話を書きました。失敗を成果物にする、という発想です。

今回ぶつかったのは、その台帳に書けない種類の失敗でした。何が起きたかは分かる。既存コンポーネントが使われず、その理由の一部は事実と違っていた。ここまでは記録できます。

しかし、それが「読んだうえでの誤読」なのか「参照せずに埋めた推定」なのかが決まらない。この2つは対処が違います。前者ならコンポーネント側の定義を整備する話になり、後者なら参照させる仕組みの話になる。区別がつかないまま打ち手を選ぶことになります。

台帳に残せるのは結果です。その結果がどちらの経路で生まれたかは、生成が終わったあとに実装だけを見ても決まりません。


仮説:照合できる記録をどう残すか

失敗を分類するには、出力とは別に、参照の側の記録が要ります。今回それを取りこぼしたので、まずは保全することです。それは設計の話で、難しいことではありません。

ただ、保全すれば済むかというと、そこは疑っています。

ファイルを読ませる形式では、必要な箇所も、念のため開いただけの箇所も、同じ読み取り操作として並びます。何を開いたかは分かりますが、どの判断のために開いたのかは分かりません。今回のように「4つのうちどれを根拠にしたのか」を問うと、記録があっても答えが出ない可能性があります。

もう一つ厄介なのは、記録がないときの解釈です。読まなかったのか、記録が取れていなかったのかが区別できない。今回まさにその状態に陥りました。

そう考えると、必要なのは記録の量ではなく、取得が何のための取得だったかが読める形だと思っています。取得を明示的な要求として発生させる仕組み、たとえば MCP のような形式は、その候補になり得ます。ただ、これは仮説です。今回試したわけではありません。

期待の置きどころも限定しておきます。仮に取得の記録が完全に残ったとしても、なぜ2つに当てはまらない記述を4つに広げたのかは分かりません。判断そのものの過程は、依然として出力から推定するしかない。

それでも、「読んだうえで誤った」と「読まずに埋めた」の区別はつきます。今回それができなかったために打ち手が選べませんでした。誤りを減らす仕組みではなく、誤りを分類する仕組みとして期待している、という位置づけです。


現時点の所感

前回は「明示的に書けば伝わる」という前提に立っていました。それは半分は正しくて、書けば改善します。今回もそうでした。

崩れたのは残り半分です。書いたものが参照されたかどうかを、こちらから確かめられない。参照せずに埋められた箇所と、参照したうえで誤った箇所が、同じ顔をして並ぶ。しかも後者は、数値の裏付けまで伴っていることがある。

確かめられることも、はっきりはしました。AIが根拠として書いた記述がコードの事実と一致するかどうかは、読めば数分で判定できます。今回もそれで確定させました。問題は、その判定を全部の記述に対して回すわけにいかないことです。どこを抜き取るべきかを決める手がかりが、いまのところありません。

前回は台帳の話を書きました。再現できなかった差分を1件ずつ記録して、デザインシステム側の不備の所在を示す。今回見つかったのは、その台帳に書けない失敗でした。起きたことは書けるのに、それがどの種類の失敗なのかが決まらない。

そして決めるための材料は、生成の実行中にしか手に入りません。終わってから探しても遅い、というのが今回いちばん高くついた学びです。

仮説の当否はまだ分かりません。ただ、次に何を測ればいいかは決まりました。出力ではなく、その手前を見ることです。


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

この記事をシェアする

AI白書

関連記事