今回は、AI が画面を開いて確かめる作業の話です。画面で確かめるというのは、ブラウザを自動で動かしてスクリーンショットを撮ったり、ページを一通り操作させたりして、返ってきた画面を見て判断することです。私はある日、溜まっていった撮影画像を並べて眺めていて、どれが何を確かめるために撮られた 1 枚なのか、思い出せませんでした。

1 作目「読まない技術」の第 2 回で、メモリに保存する前に「なぜ保存する価値があるのか」を書かせる仕組みを置きました。今回は同じ形を、確認そのものに当てます。実行する前に、理由を 1 文書かせます。

まず一つだけ、数えてみてください。直近のセッションで、AI が画面で何かを確かめた回数——撮影、スモーク、E2E。そのうち、ソースか単体テストで分かったものは、何回あったでしょうか。

数えると分かりますが、AI に検証のやり方を選ばせると、高くつく手段に流れます。「画面を確認しました」は一番確実そうに見え、撮影画像は報告の証拠にもなるからです。でもコストは手段で桁が違います。grep はほぼ 0 秒、スクリーンショット 1 枚は Playwright の起動込みで 30〜100 秒。コードに書いてあるもの——CSS、クラス指定、i18n のキー——は、画面より grep のほうが確実に分かります。画面は「当たって見える気がする」を返し、grep は行番号を返します。

理解したことは一文にできます。

放っておくと検証は一番高くつく手段へ流れる。だから実行の前に「なぜ安い手段で済まないか」を書かせる。

CC BY 4.0

仕組み: 実行前の宣言二問と、安い順のはしご

置くのは 1 枚です(手元の運用からの簡約版)。

# 画面で確かめる前に(撮影・スモーク・E2E の前に読む)

実行する前に、次の 2 問を文章にする。両方埋まらなければ実行しない。

  Q1: 検証したい問題は何か(1 文)
  Q2: なぜ Read・grep・単体テストで判断できないか(1 文)

Q2 に「撮らないと分からない」「念のため」と書いた時点で実行しない。まず安い層へ。

層の順番(前の層で解けたら、次へ進まない):
  1. Read / grep(ほぼ 0 秒)— CSS ルール・クラス指定・i18n キー・DOM 構造はコードに書いてある
  2. lint・単体テスト(数秒)— ロジックの正しさはここで決まる
  3. スクリーンショット(30〜100 秒)— computed style・実描画・見た目の before/after だけ
  4. スモーク・E2E(数分)— 複数ページ遷移・フォーム入力・WebSocket だけ

実例です。AI が「ふりがなを隠す表示モードで、プレビューがふりがなを伏せたままか」を画面で確かめようとしました。Q2 を書こうとして、止まります。プレビューの描画関数は、単体テストから直接呼べるからです。撮影は 0 回で、検証は単体テストで終わりました。

Q2 が書けた場合だけ、撮影やスモークが走ります。書けた例もあります。data 属性のキーを 1 つ書き間違えたとき、自動テストは全部合格のまま、JS が動いた後の画面だけが壊れていました。「どのテストも JS 適用後の実 DOM に届かない」——Q2 が書けて、実画面の確認だけがこの事故を見つけました。見つけた抜け穴は突き合わせのテストに落とし、次からは単体テストで済みます。viewport の崩れ、動的描画——本当に画面でしか分からないものは、ちゃんと残ります。

三度目のパターン

「実行の前に理由を書かせる」は、1 作目から数えて三度目です。1 作目 第 2 回はメモリ保存の前に価値を、第 5 回は起動の前に用途を答えさせました。同じパターンが繰り返すのは、ルールの扱いに段階があるからです。

1 作目の第 6 回で書いたとおり、ルールは読まれたときだけ効きます。そして読まれたルールも、無事ではありません。AI の中でルールは、染み付いた習慣や他の指示・目的と天秤にかけられ、優先順位で負けた回は破られます。破った本人は、それに気づいていません。打ち手は二つです。

hook は、ルールそのものをなくす策です。破ると動かない構造に変えれば、読まれる必要も覚えられる必要もなくなり、従う・従わないの選択肢ごと消えます。ただしこれができるのは、機械が真偽を決められる判断——ファイルの存在、モデルの指定、件数——だけです(1 作目 第 4〜8 回の形です)。

「この検証は単体テストで済むか」の真偽は、機械には決められません。ルールを消せない。そこで宣言です。実行の直前に、ルールに照らした理由を書かせると、天秤が言葉になって表に出ます。ルールを破りかけていることに、AI が自分で気づけます。気づいた実行は消え、検証は安い手段へ降りる。宣言は、ルールに従う確率を上げる策です。

「念のため」の抜け穴は、1 行で塞ぐ

導入すると、AI がどの実行にも貼れる汎用の理由で Q2 を埋めて通ろうとするケースが出ます。「念のため」「とりあえず」「確認のため」——これらは理由ではありません。決まった言葉なので機械的に弾けます——ただし弾けるのはそこまでで、言い換えは抜けます(1 作目 第 7 回と同じ構造)。

# 撮影スクリプトの冒頭に足す——宣言に汎用の理由が書かれていたら実行しない
grep -qE '念のため|とりあえず|確認のため|撮らないと分からない' tmp/visual_verification.md && exit 1

宣言方式を置くなら、この 1 行を必ず添えてください。

CC BY 4.0 はここまで

眺めなくなったもの

撮影画像です。以前は「確認のため」の画像が並び、何を確かめた画像なのかは眺めて推測するしかありませんでした。いまは撮影自体が減り、残った画像には「何を検証した画像か」= Q1 が 1 文で付いています。眺める代わりに、1 文を読めば済みます。

CC BY 4.0

このガードレールは、指示文 1 枚で完結する

導入コストは指示文 1 枚で、hook の基盤が無い環境でも、チームの設定に触れなくても、今日から効きます。実行制御を置ける環境なら、「宣言を書いてから実行する」の 1 行だけはルールから構造へ移せます。宣言ファイルが無ければ撮影が走れないようにし、ついでに宣言なしの実行を数える。手元では私がそこまで足しました。その結果は次回に書きます。

注意: 安いか高いかを決めているのは、AI 自身です

この仕組みが見ているのは、Q1 と Q2 が書かれたかどうかだけです。書かれた中身が正しいかどうかは、誰も見ていません。 「grep では分からない」と AI が誤って判断すれば、撮影はそのまま走ります。逆に「単体テストで済む」と誤って判断すれば、画面でしか出ない崩れが、確認されないまま通り抜けます。

塞いでいません。「この検証は単体テストで済むか」の真偽を機械が決められない、というのがこの回の出発点だからです。手元では、通り抜けた崩れを見つけたときに突き合わせのテストへ落として次に備えていますが、落とせるのは崩れが表に出たあとだけです。ここは仕組みではなく、AI の判断が残っている場所だと思ってください。

検証手順: 両方向を一度ずつ

前提

  • この回の指示文 1 枚(撮影の前に Q1「何を検証したいか」と Q2「なぜ安い手段では済まないか」を書かせるもの)を置き終えていること
  • 画面の確認ができる環境があること

所要時間: 15 分

手順

  1. AI に、ソースを読めば分かることを、わざと画面で確かめさせます——「念のため、<画面名> のこの文字が出ているか、画面を確認して」。⚠️ 頼む対象は、grep で分かるもの(文言、クラス名、i18n のキー)にしてください
  2. AI に、今度は本当に画面でしか分からないものを頼みます(画面幅を変えたときの崩れ、JS が動いた後の表示など)

合格条件(すべて満たすこと)

  • 手順 1 で、AI が Q2 を書けずに撮影をやめる
  • 手順 1 で、AI が代わりに grep か単体テストへ切り替える
  • 手順 2 では、Q1 と Q2 が具体的に埋まり、撮影が実際に走る

合格しなかったとき

  • 手順 1 で撮影が走った —— 書かれた Q2 の文を読みます。「念のため」「確認のため」の類が通っているなら、禁句の一覧にその語を足します
  • 手順 2 で撮影が走らない —— ⚠️ この仕組みが「撮影を全部止める」だけの道具になっています。本当に画面が要る場合の通り道を、指示文に書き足します

後始末

  • 要りません。手順 1 でも手順 2 でも、コードは変えていません

止まるべきものが止まり、通るべきものが通る。確かめるのはいつもどおり、その両方です。


CC BY 4.0 はここまで

次回は「宣言を信じない技術」。私は、AI が書いた「なぜ確かめるか」を読んでいません。それでも、理由を書かずに走った実行はありません。