「変更点だけ出して」と頼むと、差分は正しく出るか
遊びをつくる執筆にClaudeを使用しています。

150行ほどのクリックゲームで、制限時間を30秒から45秒に変えたいだけの場面を考えてみます。ファイル全体をAIに書き直させると、変えたくなかった箇所まで少しずつ変わっていないか、不安になります。そこで「変更点だけ出して」と一行添えると、出力は短くなり、読む量も減ります。 ただし短くなった分、別の確認が必要になります。示された変更が正しい行に当たるのか、取りこぼしはないのか、頼んでいない行が混ざっていないのかです。全文を出させる場合は、貼り替えれば場所の問題は起きません。変更点だけの場合は、場所の特定を人が引き受けることになります。 この記事では、その正確さを感覚ではなく、実際の差分で測る実験を設計します。比べるのはプロンプトの一行の違いです。結果は書きません。以下の準備と手順で、読者自身の環境で答えを出せる形にしてあります。
変更点だけの出力で、どこが壊れうるか
測る前に、失敗の種類を先に並べておきます。何を記録するかが決まるからです。
- 取りこぼし:3か所の修正が必要なのに、2か所しか示されません。
- 余計な変更:頼んでいない行の修正や、変数名の改名、整形が混ざります。
- 場所のあいまいさ:score++ のように、ファイル内に似た行が複数ある場合に、どれを直すのか読み取れません。
- 省略記号の解釈:「// ...既存のコード」のような省略表記の前後が、どこまでを指すのか分かりません。
- 存在しない参照:基準にない関数名や変数名を前提にした断片が出てきます。
- 空白の差:インデントや末尾の空白が違い、内容は同じでも行としては別物になります。
これらを一度に見るために、「基準」と「正解」と「適用後」の3つのファイルを用意し、差分どうしを比べます。
準備:基準ファイル、3つの依頼、一行だけ違う3つの指示
基準ファイル
単独で動くHTMLのゲームを1本用意します。既存の自作ゲームがあればそれを使えます。次の条件を満たすものにしてください。
- 100〜150行程度で、JavaScriptまで1ファイルに収まっています。
- 制限時間や得点などの定数が、冒頭近くにまとまっています。
- 関数が5つ前後あります。
- 似た行が複数あります(score++ と miss++ のような近い書き方)。
最後の条件が重要です。似た行がまったくないファイルでは、場所のあいまいさが起きにくく、この実験の目的が薄れます。
3つの依頼
変更の大きさが違う依頼を3つ決めます。例を挙げます。
- 小:制限時間の定数を30秒から45秒にします(1か所)。
- 中:ハイスコアを画面に表示します(HTML要素の追加と、JavaScriptの2か所程度)。
- 大:難易度ボタンを追加し、難易度によって的の出現間隔を変えます(複数の関数にまたがります)。
一行だけ違う3つの指示
依頼文は同一にして、末尾の指示だけを変えます。
- A:「ファイル全体を出力してください。」
- B:「変更点だけ出してください。」
- C:「変更点だけ出してください。各変更について、直前にある既存の1行をそのまま引用して場所を示し、置き換え前と置き換え後を分けて書いてください。」
AとBの差は「全文か、変更点だけか」です。BとCの差は「場所の示し方を指定するか」です。それぞれが何に効いているかを切り分けられます。
正解ファイル
AIの出力を見る前に、3つの依頼それぞれを、自分の手で基準ファイルに反映して保存します。これが正解です。同じ挙動でも書き方は複数あるので、依頼文に「変数名は limit のまま」のように制約を足しておくと、行の比較がしやすくなります。
手順と記録:差分を機械で測る
実施の手順
- 基準ファイルの全文と依頼文、指示(A/B/C)を貼って送ります。毎回、新しい会話で始めます。会話の履歴が残ると、基準が途中で更新されたような状態になり、比較できなくなります。
- 3依頼×3指示を1回ずつで9通りになります。これを各3回、合計27回行います。負担が大きければ各2回の18回まで減らせます。実施順は、くじなどでばらします。
- Aは出力をそのまま保存します。B・Cは、出力された断片を基準ファイルに手で適用して保存します。
- 適用には次の規則を守ります。出力に書かれたことだけを適用します。推測で補ったら、後から直さず、「迷い」に1回と数えます。「// ...既存のコード」などの省略記号の行は、書き換えずに残します。
差分を測る道具
適用後のファイルを正解と比べるために、行単位の差分を取る小さなページを用意します。次のコードを diff.html として保存し、ブラウザで開いてください。基準・正解・適用後の3つの欄に貼って「比べる」を押すと、正解が求める変更行のうち適用後に欠けているものを「欠落」、正解にない余計な変更を「余計」として表示します。
<!doctype html>
<meta charset="utf-8">
<title>差分チェック</title>
<textarea id="base" rows="8" cols="30" placeholder="基準"></textarea>
<textarea id="ans" rows="8" cols="30" placeholder="正解"></textarea>
<textarea id="app" rows="8" cols="30" placeholder="適用後"></textarea>
<p><button id="go">比べる</button></p>
<pre id="out"></pre>
<script>
const split = s => s.replace(/\r\n/g, "\n").split("\n");
function diff(a, b) {
const n = a.length, m = b.length;
const t = Array.from({length: n + 1}, () => new Array(m + 1).fill(0));
for (let i = n - 1; i >= 0; i--)
for (let j = m - 1; j >= 0; j--)
t[i][j] = a[i] === b[j] ? t[i+1][j+1] + 1 : Math.max(t[i+1][j], t[i][j+1]);
const out = [];
let i = 0, j = 0;
while (i < n && j < m) {
if (a[i] === b[j]) { i++; j++; }
else if (t[i+1][j] >= t[i][j+1]) out.push("- " + a[i++]);
else out.push("+ " + b[j++]);
}
while (i < n) out.push("- " + a[i++]);
while (j < m) out.push("+ " + b[j++]);
return out;
}
function minus(x, y) {
const c = new Map();
y.forEach(l => c.set(l, (c.get(l) || 0) + 1));
return x.filter(l => {
const k = c.get(l) || 0;
if (k > 0) { c.set(l, k - 1); return false; }
return true;
});
}
document.getElementById("go").onclick = () => {
const val = id => split(document.getElementById(id).value.trimEnd());
const base = val("base");
const dAns = diff(base, val("ans"));
const dApp = diff(base, val("app"));
const missing = minus(dAns, dApp), extra = minus(dApp, dAns);
document.getElementById("out").textContent =
"正解の変更行: " + dAns.length + "\n適用後の変更行: " + dApp.length +
"\n欠落: " + missing.length + "\n余計: " + extra.length +
"\n--- 欠落 ---\n" + missing.join("\n") +
"\n--- 余計 ---\n" + extra.join("\n");
};
</script>差分の取り方には、最長共通部分列(LCS)という考え方を使っています。2つのファイルで順序を保ったまま共通する行を最大限見つけ、残りを削除(-)と追加(+)とみなします。行が移動した場合は、削除と追加の組として表示されます。
この道具には限界があります。比べるのは行の内容だけなので、正しい行が違う場所に入っていても一致とみなします。位置のずれは、次の動作確認で拾います。
記録の単位
1回の試行につき、表の1行を記録します。
- 依頼・指示・回、記録すること:小/中/大、A/B/C、1〜3回目
- 出力文字数、記録すること:出力全体を文字数カウンターで数えた値
- 迷い、記録すること:適用時に補った回数
- 欠落、記録すること:道具の表示行数
- 余計、記録すること:道具の表示行数
- 動作、記録すること:依頼ごとに決めたチェック項目(3つ程度)を全部満たせば○、一部なら△、起動しないなら×
- メモ、記録すること:欠落・余計の中身(改名か整形か、など)
動作のチェック項目は、結果を見る前に決めます。たとえば依頼「小」なら、「45秒から始まる」「0秒で終わる」「再開しても45秒に戻る」といった項目です。
結果の読み方
27回の記録がそろったら、依頼×指示の9マスごとに、3回の並びを見ます。判定の目安を事前に決めておくと、結果に引きずられません。たとえば「3回とも欠落0・余計0・動作○なら、その大きさの依頼では運用に使える」と決めます。
数字の組み合わせから、疑うことを分けます。
- 欠落あり、余計なし、まず疑うこと:複数箇所の変更の取りこぼしです。「大」の依頼に多いかを確かめます。
- 余計あり、まず疑うこと:範囲外の改変か、空白・整形の違いです。メモの中身を読み、空白を無視して再比較します。
- 欠落と余計が同数で対応している、まず疑うこと:同じ変更が別の書き方で出ています。動作が○なら、挙動としては合っている可能性があります。
- 欠落・余計なしで動作が×か△、まず疑うこと:行は合っていても場所がずれているか、行の順序の問題です。
- 迷いが多い、まず疑うこと:場所の示し方が不足しています。BとCの迷いの差を見ます。
比べる軸は3つあります。
- AとBの差:欠落・余計が増えるかどうか。
- BとCの差:場所の指定が、迷いや動作の安定に効くかどうか。
- 出力文字数の差:正確さと引き換えに、どれだけ出力量が減るか。
出力が短くなる利点と、取りこぼしの危険を同じ表で見て、依頼の大きさごとに「全文を出させる」「Cで頼む」「Bで十分」を選びます。27回という数は、傾向を知るための最小限です。差が小さい場合は、「差がない」と決めつけず、回数を増やすか、基準ファイルや依頼を変えてもう一度確かめてください。
起こりやすい誤り
- 基準ファイルの食い違い:AIに貼った内容と、手元の基準が違うことがあります。エディタの自動整形や改行コードの違いが原因です。貼る前に基準を保存し、差分を取る際にも同じファイルを使います。
- 正解が唯一だと思い込む:行の比較では、別の書き方が「余計」と「欠落」に見えます。動作の確認と併用してください。
- 会話を引き継ぐ:同じ会話で続けると、先の出力が基準として扱われます。毎回新しい会話にします。
- 指示を同時にいくつも変える:Cで場所の引用を求めた上に、依頼文も言い換えると、何が効いたのか分かりません。変えるのは末尾の指示だけです。
- 適用時の補正:出力の間違いに気づいて黙って直すと、迷いが記録に残りません。補ったら必ず数えます。
- 1回で判断する:同じ条件でも、出力は毎回同じとは限りません。3回の並びで見ます。
- 似た行のない基準で測る:場所のあいまいさが起きにくくなり、BとCの差が見えません。
次の行動
まず、手元の小さなゲームを基準ファイルにして、「小」の依頼だけをA・B・Cで各1回試し、diff.html に貼って欠落と余計の表示を見てください。道具の使い方に慣れてから、依頼を「中」「大」に広げ、27回の表を埋めていきます。
実験に使ったゲームは、完成したら単独の index.html としてアソバースに投稿できます。公開前に下書き保存で表示を確かめ、自分の記録表と照らして動作を見直すと、実験が作品づくりにもつながります。

