AIに自分のコードをレビューさせると、何を見逃すか
遊びをつくる執筆にClaudeを使用しています。

AIにブラウザゲームのコードを書かせ、同じ会話の中で「このコードをレビューしてください」と頼む場面を考えてみます。返ってくるのは、もっともらしい指摘の列です。変数名の改善、関数の分割、エラー処理の追加などが並びます。ところが、そのコードを実際に動かすと、制限時間が1秒長い、ゲームオーバー後にボタンが効かなくなる、といった遊んですぐ分かる不具合が残っているかもしれません。 この記事の問いは「自己レビューで見つかる問題と、見つからない問題の境目はどこにあるか」です。ここでは答えを書きません。バグをあらかじめ仕込んだコードを用意し、レビューが何を言い当てて何を言い当てないかを数える実験を設計します。同じ手順を自分のAI、自分のコードで行えば、手元の環境での答えが出ます。 見るのは単純な良し悪しではありません。「書いた側と同じ思い込みで読んでしまう」ことが、実際に検出率の差として現れるかどうかです。そのため、同じ会話で行うレビューと、新しい会話で行うレビューを比べます。
この記事の目次
準備:仕込みバグ入りのコードと、判定の物差し
必要なものは、次の4つです。
- レビューを頼むAI(普段使っているものでかまいません。実験中は同じものを使い続けます)
- 仕込みバグ入りのHTMLファイル
- そのコードが満たすべき「仕様メモ」(3〜5行)
- 記録用の表(表計算ソフトやメモ帳で十分です)
まず、仕込み用のサンプルを示します。10秒間でボタンを何回押せるかを競う、小さなゲームです。
<!doctype html>
<meta charset="utf-8">
<button id="b">クリック</button>
<p id="t">残り 10 秒</p>
<p id="s">0点</p>
<script>
let score = 0, left = 10, timer = null, best = 0;
const b = document.getElementById('b');
const t = document.getElementById('t');
const s = document.getElementById('s');
function start() {
score = 0;
left = 10;
timer = setInterval(tick, 1000);
}
function tick() {
left--;
t.textContent = '残り ' + left + ' 秒';
if (left < 0) end();
}
function end() {
clearInterval(timer);
if (score > best) best = score;
s.textContent = score + '点 / 最高 ' + best;
}
b.addEventListener('click', () => {
if (!timer) start();
score++;
s.textContent = score + '点';
});
</script>このコードには、2つのバグを意図的に入れています。
- 境界値のずれです。終了条件が left < 0 のため、「残り 0 秒」を表示したあともう1秒続き、「残り -1 秒」と出てから終わります。仕様は10秒間なので、実質11秒になります。
- 状態が戻らない問題です。end() のあとで timer が null に戻りません。終了後にボタンを押しても start() は呼ばれず、score だけが増え続けます。再挑戦ができず、最高記録も更新されません。
仕様メモは、次のように書いておきます。
- 最初のクリックで開始し、ちょうど10秒間で終了する
- 終了後にボタンを押すと、点数をリセットして再挑戦できる
- 終了時に今回の点数と最高記録を表示する
ここで大切なのは、バグの位置をコードのコメントにも仕様メモにも書かないことです。仕様メモは「正しい動作」だけを書き、「どこが怪しいか」は書きません。
サンプルのままでも実験はできます。ただ、自分のコードで行うと、より実感のある結果になります。AIに新しい小さなゲームを書かせ、動作を確認してから、自分の手でバグを2〜4個仕込んでください。種類を散らすのがコツで、次の4種類から選ぶと偏りません。
- 境界値、仕込み方の例:< と <= の入れ替え、配列の最後の要素の取りこぼし
- 状態管理、仕込み方の例:終了後や再開後に、片方の変数だけ初期化されない
- 仕様との不一致、仕込み方の例:仕様メモとは違う数値や挙動にしておく
- 動作環境の前提、仕込み方の例:投稿先の制約に反する書き方にする
アソバースへの投稿を想定するなら、「動作環境の前提」の種類に使える材料があります。入口は直下の index.html であること、素材は相対パスで読むこと、サーバー用コードやサービスワーカーは対象外であることです。さらに、アップロード作品内の localStorage や sessionStorage は一時メモリーの互換処理で、端末への永続保存ではありません。「保存したつもりで保存されていない」コードは、書いた側もレビューする側も見逃しやすい候補です。自分の投稿先の案内を確認したうえで、仕込みを選んでください。
手順:同じコードを3つの条件でレビューさせる
同じバグ入りコードを、3つの条件でレビューさせます。条件ごとに3回ずつ、合計9回を目安にします。1回だけでは、たまたまの当たり外れと区別できないためです。
条件A:同じ会話で自己レビュー
コードをAIに書かせた会話の続きで、次のように頼みます。AIが書いたコードに、手動でバグを仕込んだ版を貼り直す点に注意してください。
次のコードをレビューしてください。バグや仕様との不一致があれば、該当箇所と理由を挙げてください。
コードは、仕込み後のものを貼ります。サンプルを使う場合は、AIに「10秒クリックゲームを作って」と頼んだ会話の続きで、上のコードを貼ります。「あなたが書いたコード」とは言わず、「次のコード」とだけ書きます。
条件B:新しい会話で、観点を指定せずにレビュー
履歴のない新しい会話を開き、同じ依頼文でコードと仕様メモを貼ります。条件Aとの違いは、書いた経緯を知らないことだけです。
条件C:新しい会話で、観点リスト付きレビュー
条件Bと同じ設定に、観点を加えます。
次の観点で順に確認してください。(1) 仕様メモの各行を、コードの動作と一行ずつ突き合わせる。(2) 開始・終了・再開の各時点で、すべての変数がどうなるかを追う。(3) 数値の境界(0、最大値、最後の1回)で何が起きるかを追う。
観点を渡すと検出が増えるのか、増えないのか。これが条件Bとの比較で見えます。
3条件とも、守る点は共通です。
- 使うコードと仕様メモは、すべて同一にします。
- 返ってきた指摘に、「直してください」と続けて頼みません。1回の返答だけを記録します。
- 1回ごとに会話を新しく開きます。ただし条件Aは、毎回「コードを書かせた会話」を用意し直します。
記録の取り方:指摘の「当たり」を厳しく判定する
記録は、1回のレビューを1行にして、仕込んだバグごとに判定を付けます。
- 1、条件:A、バグ1(境界値):、バグ2(状態):、指摘総数:、誤り・的外れ:、実在する別の問題:
- 2、条件:A、バグ1(境界値):、バグ2(状態):、指摘総数:、誤り・的外れ:、実在する別の問題:
判定は、次の3段階で付けます。
- 指摘:該当する行や現象を具体的に言い当てている場合です。たとえば「left < 0 だと、0秒表示のあとさらに1秒続く」は指摘に数えます。
- 部分的:問題の周辺には触れているものの、原因や現象は特定していない場合です。たとえば「タイマーの終了処理を確認すべき」とだけ書かれた場合です。
- なし:まったく触れていない、または「境界値に注意」のような一般論だけの場合です。
判定を曖昧にしないために、実験を始める前に「この文言なら指摘」という基準を、バグごとに1行ずつ書いておきます。レビューを読んでから基準を決めると、甘くなりがちです。
「指摘総数」は、AIが挙げた問題の数です。そのうち、読んで実際に動かしても再現しないもの、あるいは事実と違うものは「誤り・的外れ」に数えます。ここは必ず、指摘どおりにコードを動かして確かめてください。「もっともらしいから正しいだろう」で数えると、記録の意味がなくなります。
仕込んでいない問題を指摘された場合も、すぐに誤りと決めつけないでください。実際に再現できるなら「実在する別の問題」に数えます。サンプルでは、たとえば開始前の表示や、ボタンの連打の扱いに別の論点があるかもしれません。
結果の読み方:数字を見る前に、読み方を決めておく
9回分の記録がそろったら、バグごと・条件ごとに「指摘」の回数を並べます。3回中何回か、というごく粗い数字で十分です。ここで読み取りたいのは、次の4つの形です。
- 全条件で指摘される:そのバグは、書き手の思い込みの影響を受けにくい種類だと考えられます。コードの字面から見つけやすい問題です。
- 条件Aで少なく、条件BやCで増える:同じ会話の文脈が、見落としを生んでいる可能性があります。書いた直後のレビューは、新しい会話で行うほうがよい根拠になります。
- 条件Cだけで増える:観点を明示すると見つかる種類です。レビューを頼むときの定型文に、その観点を入れる価値があります。
- どの条件でも指摘されない:AIのレビューでは足りない種類です。実際に動かして遊ぶこと、仕様メモとの突き合わせを人間が行うことが必要になります。
3回の試行では、差が小さい場合の判断は難しくなります。「3回とも指摘された」と「3回とも指摘されなかった」のような、はっきりした差だけを根拠にしてください。1回違いは偶然かもしれません。気になる場合は、各条件を5回以上に増やします。
もうひとつ見ておきたいのが、指摘の質です。指摘は多いのに仕込みバグには触れない、という形もあり得ます。その場合は「指摘総数」と「誤り・的外れ」の比率を見ます。件数が多いレビューは、必ずしも役に立つレビューではありません。
起こりやすい誤りと、次の行動
実験の精度を落とす典型的な誤りは、次の5つです。
- バグの位置をヒントで漏らす:「タイマー周りを特に」のような一言が入ると、結果が変わります。条件Cの観点リストも、個別のバグを連想させない一般的な書き方にしてください。
- 仕様メモをコード側に混ぜる:コメントに仕様を書くと、突き合わせが簡単になり、現実のレビューと離れます。
- 実行せずに判定する:「たぶんそうなるはず」で判定しないでください。ブラウザで開き、10秒数えて確認する手間をかけます。
- 会話の履歴を引きずる:条件BとCで、前の会話を開いたままにしないでください。
- 1つのコードだけで結論を出す:サンプルで傾向がつかめたら、自分のゲームで別のコードを試してください。
次の行動として、まずサンプルをHTMLファイルに保存し、ブラウザで開いて2つのバグを自分の目で確認してください。そのうえでAIに条件Aから順にレビューさせ、判定基準を先に決めた表に記録します。傾向が見えたら、見逃された種類のバグは「自分で遊んで確かめる項目」として、公開前のチェックリストに加えてください。

