AIレビューに「存在しない」と書かせる前に検索語と件数を出させる

「テストが無い」「ロックが無い」という形の指摘は、受け取った側が自分で全文検索して確かめることになる。どの語で検索すればよいかは出力に書かれていないので、語を当てるところから始まる。10ファイルの題材で不在の主張を5件立てて検索で振り分けると、3件が誤りだった。同じ主張を試す語を変えると件数は1件から3件まで動く。不在の主張は、検索した語と件数を同じ行に書かせたときだけ人が追試できる。

この記事の提案を使うのは、「〜が無い」という形の指摘を受け取って、それを直しに回すかどうかを決めるときである。

不在の主張5件を振り分ける

題材は在庫と明細金額を扱う Python のパッケージで、10ファイル・120行である(道具の許可を段で書く記事で定義したものと同じ)。割引率の単位を変え、Store に reserve を足した差分をレビュー対象にしている。

不在を指す主張を5件立て、それぞれに検索語と「件数がどうなっていれば不在が成り立つか」を先に決めた。決めてから検索した結果である(2026-10-12、Python 3.12.3 で走らせた。モデルは走らせていない。検索は手元で実行した)。この記事が設計するのは、検索をレビュー出力のどの欄に残すかである。人が全文検索して自分で差を取る作業そのものは扱わない。

主張 検索語 件数 判定
A reserve にテストが無い def test_reserve 1 誤り
B 在庫を減らす前に残数を確認する箇所が無い if qty > self\.available 1 誤り
C 割引率の単位変更に追随していない箇所は無い bulk_rate[}%]|bulk_rate=\d+\) 2 誤り
D reserve が残数不足のときの挙動を試すテストが無い assertRaises\(OutOfStock\) の近傍に reserve 0 成立
E 割引率が比率の範囲内かを検査する箇所が無い bulk_rate\s*[<>] 0 成立

5件のうち3件が、検索で誤りと分かった。内訳を見ると誤りの性質が違う。

主張Aは単純に外れている。test_store.py:17 に def test_reserve_holds_stock があるので、テストは存在する。ただし存在するテストが試しているのは在庫5から2を予約して残数3になることだけで、残数不足の場合は試していない。主張Aを主張Dの形に言い直すと成立する。

主張Bも外れている。確認は inventory/store.py:13 にある。ただしそれは ship の中の確認で、同じ差分が足した reserve には無い。主張Bは場所を絞っていないので、確認がどこかにあるという事実で反証される。

主張Cは向きが逆である。「追随していない箇所は無い」という不在の主張に対して、検索は2件を返した。

bulk_rate の旧単位の使い方を探す
inventory/report.py:13   return f"{item.bulk_threshold}個以上で{item.bulk_rate}%引き"
test_report.py:6         CATALOG = {"widget": Item(..., bulk_rate=20)}

2件とも差分に入っていないファイルである。件数0を期待した検索が2件を返したので、不在の主張はここで倒れる。

件数だけでは追試できない

同じ主張Aを試すときに選びうる検索語を5通り並べて、件数を数えた。

検索語 件数 一致した場所
テスト 1 README.md:10
test_reserve 1 test_store.py:17
reserve 3 inventory/store.py:17、test_store.py:17、test_store.py:19
reserve( 2 inventory/store.py:17、test_store.py:19
def reserve 1 inventory/store.py:17

件数は1件、1件、3件、2件、1件と動く。注意が要るのは1行目と5行目である。どちらも件数1だが、テスト が指しているのは README の文で、def reserve が指しているのは実装の定義であって、どちらもテストの有無を判定していない。件数が同じでも、判定の向きは語によって逆になる。 件数だけを出力に書かせても、どの語で数えた件数かが分からないかぎり、読んだ側は判定を再現できない。

追試の手間を3通りで比べる。

出力に書かれているもの 1件の追試にかかる操作
検索語と件数の両方 1 コマンド
件数だけ 語を当てるまで候補を試す(この題材では5通り)
どちらも無い 10ファイル・120行を読む

成果物

検索語と件数の欄

不在を指す指摘1件につき1欄を足す。欄の中身は「検索語」と「一致した件数」を同じ行に書いたものである。

レビュー指示に足す「不在の主張」の節
## 不在の主張の扱い

「〜が無い」「〜されていない」という形の指摘を書くときは、次の1欄を足す。
この欄が書けない指摘は、不在の形で書かずに「確認できなかった」と書く。

- 検索: `<検索した語>` → <一致した件数> 件(一致があれば <ファイル:行> を最大3件)

検索語は次の3つの順に作る。
1. 差分に現れる識別子をそのまま使う(関数名、変数名、設定の鍵の名前)
2. 不在を判定する側の語を足す(テストなら `def test_<識別子>`、
   例外なら `assertRaises(<例外名>)`、設定なら `<鍵の名前>:`)
3. 1と2で件数が0になったとき、識別子の綴りを変えた候補(単数と複数、
   省略形、大文字小文字)でもう1回数える

一致が1件以上あった場合は、不在の主張を次のどちらかに書き直す。
- 場所を絞る: 「<ファイル:行> には有るが、<ファイル:行> には無い」
- 条件を絞る: 「<条件>の場合を試すものが無い」
一致があったのに不在の主張をそのまま残さない。

3番目の規則が無いと、綴りを外した検索で件数0が出て、不在の主張が成立したように見える。この題材で主張Aを def test_reserve ではなく def testReserve で検索すると0件になり、判定が逆になる。

見つかった場合に書かせること

一致があったときの書き直し先を2つに限ると、受け取った側が次にすることが決まる。場所を絞った指摘は差分の該当箇所へ回せる。条件を絞った指摘は、その条件のテストを足す作業になる。この題材では、主張Aが「reserve にテストが無い」から「残数不足の場合を試すものが無い」(主張D)へ移り、検索の件数0で成立した。

6欄を超えるときの入れ替え

指摘1件あたりの欄は6つを上限にする。検索の欄を足して7つ目になる場合、外すのは機構の一文である。不在の主張は「何が起きるか」ではなく「何が無いか」を言っているので、機構の説明が指す対象がない。機構の一文を外して検索の欄を入れる。

検索の欄を外していい条件は、その差分で不在を指す指摘が1件も出ないときである。差分の中の値が間違っているという形の指摘だけなら、検索する対象が無い。出力を受け取ってから不在の形の指摘が0件だったなら、次の差分ではこの欄を外せる。

欄を1つ足すと何を使うか

出力項目は1欄増える。増えるのは不在を指す指摘についてだけなので、総量は不在の指摘の件数ぶんである。この題材で立てた5件のうち、検索の欄が要るのは5件すべてだった。1件あたり1行なので5行増える。

人の確認時間は減る。追試が1コマンドになるので、1件あたり数秒である。10ファイル・120行を読んで確かめる形と比べると、題材の規模が大きくなるほど差が開く。差が付くのは、検索語が出力に書かれている場合に限る。欄を足しても突き合わせをしないなら、増えた1行は読む量だけを増やす。

この欄を落としていい条件は、差分の外を見ない約束でレビューさせるときである。 渡した差分だけを材料にして、差分の中で判定できる指摘だけを出させる形なら、不在の主張そのものを禁じられる。禁じた場合は「確認できなかった」と書かせる形へ寄せて、検索の欄は使わない。

指示文の点検

不在の指摘を受け取るときに確かめる項目
  • 不在を指す指摘に、検索語と件数を同じ行に書かせているか
  • 検索語の作り方を3規則で指定したか
  • 綴りを変えた候補でもう1回数える規則を入れたか
  • 一致が1件以上あったときの書き直し先を2つに限ったか
  • 一致があったのに不在の主張が残っていないかを見たか
  • 検索の欄が書けない指摘を「確認できなかった」へ回す形にしたか
  • 件数が0の指摘について、手元で同じ語を打って0を再現したか
  • 件数が同じでも語が違えば判定が変わることを前提に、語を読んでいるか
  • 欄が7つ目になる場合に外す欄(機構の一文)を決めたか
  • 不在の指摘が0件だった差分で、この欄を外す判断をしたか

おわりに

10ファイル・120行の題材で不在を指す主張を5件立てて検索で振り分けると、3件が誤りだった。1件は存在するテストを見落とし、1件は場所を絞っていないために別の箇所の確認で反証され、1件は件数0を期待した検索が2件を返した。

同じ主張を試す検索語を5通り変えると件数は1件から3件まで動き、件数が同じ1件でも指している対象が README の文と実装の定義に分かれた。件数だけでは判定を再現できないので、語と件数を同じ行に置く。

次に取る行動を1つ挙げる。手元のレビュー出力から「〜が無い」という形の指摘を1件選び、自分で検索語を決めて数える。件数が0でなかったなら、その指摘は場所か条件を絞った形に書き直せる。書き直せた1件が、検索の欄を足す理由になる。