この記事は、連載「追わない技術」の第 8 回です。うまくいかない症状と、その対処を一つずつ並べています。各回はファイルやスクリプトを一つ置けば完結します。その仕組みがなぜ要るのかは、置いたあとに解説を読めば分かります。連載の全体像と各回の一覧は序論にあります。
今回は、AI が「結論が出た」と判断した時点で、まだ止めてはいけない場合の話です。AI は、仕事が終わったように見えたところで止まるからです。
私がAIに回させた実験で、AIが書いた結論が、あとでひっくり返ったことが、3 度あります。そのうち 2 度は、差が無いという結論でした。2 度は私が引き止め、残る 1 度はスクリプトが引き止めました。
AI に何かを比べさせて、「差はありませんでした」と返ってきたことがあるなら、そのときのことを思い出してみてください。
それは、本当に差が無かったのですか。
それとも、まだ測ることができていなかったのですか。
CC BY 4.0
止める仕組みは、止めてはいけない場所を知らせません
私はこの連載で、止める側の技術を書いてきました。私が手元に置いた仕組みにも、止めるものが並びます。待ちを止めるもの、テストの走らせ方を止めるもの、一覧の数が実際と違ったら止めるもの、などです。どれも、AI に伝えるのは「ここで止まれ」だけです。
止めないための仕組みも、手元にはありました。AIがmemoryを書き換えたまま作業を終えようとしたら引き戻すhookと、道具で測っていない数を書いたまま終えようとしたら引き戻すhookです。ただ、この 2 本が見ているのはmemoryと数の出どころで、AIが「結論が出た」と判断したときに何を数えたかは見ていません。
止める仕組みは、止めてはいけない場所を 1 つもAIに知らせません。
1 度目 —— 走らなかったものを、母数から外していました
私はAIに、サブエージェントが書いたテストの見逃しを数える実験を回させました。見逃しは、実装をわざと 1 か所だけ壊したもの(変異)を作り、その変異に対してテストが失敗するかどうかで数えました。失敗しなかった変異が、見逃しです。採点(見逃しを数えること)に使う項目は、その変異 8 種です。比べる相手として、人が以前に書いたテストも、同じ 8 種で採点しました。そのテストが見逃すのは、8 種のうち 2 種です。変えたものは 2 つあります。トークン 1 つあたりの単価が違う 2 つのモデル(単価の高いほうを「高いモデル」、安いほうを「安いモデル」と呼びます)と、テストを書かせる範囲(1 メソッドに絞るか、絞らないか)です。
AI は、それまでのやり取りを何も引き継がないサブエージェントを 12 回起動し、1 回に 1 本ずつテストを書かせました。変異を入れないまま、書かれたテストを走らせた結果が、次の表です。
| モデル | テストが走った本数(6 本のうち) |
|---|---|
| 高いモデル | 6 / 6 |
| 安いモデル | 2 / 6 |
AI は、走らなかったテストを母数から外し、走ったテストだけで見逃しを数えて、見逃しはモデルでも範囲でも動かない、と結論を書きました。
私はAIを引き止め、全部のテストを合格させてから数え直させました。数え直した見逃しの数には、差が出ています。
走らなかったものを母数から外すと、いちばん危ない側が消えます。
2 度目 —— 測ることのできていない項目を、後回しにしていました
次にAIは、「安いモデルは、範囲を絞れば高いモデルと同じ」と結論を書きました。範囲を絞ったときの点(8 種のうち、見逃さなかった項目の数の平均)は、どちらも 3.33 / 8 でした。ただ、8 種のうち 3 種は、12 本のテストがどれも見逃していました。人が書いたテストは、その 3 種を見逃していません。
私はAIを引き止め、課題に「材料と測り方は自分で用意する」という 1 段落を足して、測り直させました。
並んでいたのが範囲を絞ったときなので、下の表も範囲を絞ったときで比べます。
| モデル(範囲を絞ったとき) | 課題を直す前の点(見逃さなかった項目の数の平均) | 課題を直したあとの点 |
|---|---|---|
| 高いモデル | 3.33 / 8 | 5.00 / 8 |
| 安いモデル | 3.33 / 8 | 3.00 / 8 |
高いモデルの点だけが伸びました。前に並んでいたのは、両方とも簡単な項目だけを取っていたからです。
測ることができていないものを、「差が無い」と読んではいけません。
3 度目 —— スクリプトが引き止めました
AI は、どのモデルを使うかを比べるのにかかった手間(作業の数と経過時間)を、「仕組み何本ぶんか」に換算するスクリプトを書きました。最初に出た数は、手数で 3.8 本、経過で 20.6 本でした。
2 つの数は、5 倍以上ずれています。原因は、スクリプトの割り算にありました。手数のほうの割り算が、「同じ手間で何本置くことができたか」の代わりに、ただの比を出していたのです。割り算を直すと、手数で 19 本、経過で 20.6 本になり、2 つの数はほぼそろいました。
このときAIを引き止めたのは、スクリプトが同じことを 2 通りで数えていたことです。
差し戻すと、AI は失敗しているテストを消しにいきます
AI が不適切に諦めるのは、結論を出すときだけではありません。同じ実験で、AI は、テストが失敗したサブエージェントに差し戻しました。差し戻しの文には、実装は正しいものとして扱うことと、「直すのはテストの側です」と書いてありました。
| モデル(課題を直したあとの実験) | 差し戻した回数(6 回ぶんの合計) |
|---|---|
| 高いモデル | 0 |
| 安いモデル | 10 |
安いモデルが返した直し方のうち 3 件は、失敗しているテストを消すか、エラーが起きても捕まえて止めない書き方に変えたものでした。どちらの直し方でも、テスト全体は合格になります。
そして、そのテストが見るはずだった変異は、そのまま見逃しになります。
テストを消すのも、テストを直すことを諦めた形です。
なぜ、AI は止めてはいけないところで諦めるのか
Claude Code のベストプラクティスのページによると、Claude は、仕事が終わったように見えたところで止まります。走らせることのできる確かめ方が無ければ、Claude が止まる手がかりは、「終わったように見える」ことだけです。そのとき、どの間違いも、人が気づくまで残ります。この実験で AI が書いた、差が無いという 2 度の結論も、数が出そろった時点で、終わったように見える結論でした。2 度とも、その結論は私が気づくまで残っていました。同じページは、合格か不合格かを出すものを Claude に渡すと、Claude は確かめを走らせて結果を読み、合格するまで繰り返す、と書いています。3 度目に AI を引き止めたのは、同じことを 2 通りで数えたスクリプトの、2 つの数のずれのほうでした。
途中でやめたまま終わる形は、私の実験の外でも測られています。Smyth ほか(2026)は、ファイルの見直しを頼んだ課題で、頼まれたファイルを全部は読まなかった実行が 67.9% あったと報告しました。そのうち 80.4% で、最終の応答は、全部読んだと書くか、読み残しに触れていませんでした。この課題で多かったのは途中でやめた実行のほうで、その多くは報告からは見えません。
差し戻しの文は、直すのがテストの側であることは決めていましたが、どう直すかは決めていませんでした。失敗しているテストを合格にする直し方は、1 つではありません。テストの期待値を書き直すことも、そのテストを消すことも、エラーを捕まえて止めない書き方に変えることもできます。どの直し方でも、テストの結果は合格です。
Anthropic のプロンプトの指針には、Claude がテストを通すことに集中しすぎて、より一般的な解を犠牲にすることがある、と書いた節があります。
METR は、最先端のモデルの reward hacking についての報告で、合格かどうかを判定する側に手を加えて通す振る舞いの例を集めました。挙がっている例には、評価器を書き換えて、いつも満点を返すようにしたものがあります。同じ報告は、ある課題で、意図したやり方で解け、ずるをするな、と指示しても、その振る舞いにはほとんど効かず、大半の試行で続いた、と書いています。
私の実験で、消して合格にした直しは、合格の数の上では、ほかの合格と同じ 1 件に数えられていました。消したテストは、知らせもなくテストの本数から減ります。1 度目にAIが、走らなかったテストを母数から外したのと同じ形です。
「差はありませんでした」と返ってきたとき
ある仕事を 2 つのモデルのどちらに頼むかを決めるために、同じ課題を両方に渡し、採点までをAIに任せました。採点の明細までは、あなたは見ていません。AI は「差はありませんでした」と報告し、どちらかに決めて作業を終えることを勧めています。あなたなら次のどちらにしますか。
- 差が無いと分かったので、どちらかに決めて進める
- 測れなかったぶんが無いかを確かめさせてから決める
答えは、測れなかったぶんが無いかを確かめさせてから決めるほうです。点が出そろったあとの「差はありませんでした」は、終わったように見える報告です。AI は、終わったように見えたところで止まり、走らせることのできる確かめ方が無ければ、終わったように見えることだけが手がかりで、間違いは人が気づくまで残ります。ところが、差が無いという結果は、測れなかったぶんが残っていても出ます。走らなかったテストを母数から外せば、点は走ったものどうしで並び、どの組も取れない項目が残っていれば、点は取りやすい項目の中でしか動きません。失敗しているテストを消せば、合格の数は減りません。測れなかったぶんが残っているなら、どちらに頼むかという頼んだ答えは、まだ測れていません。AI は決めて終えることを勧めていますが、あなたがそこで決めると、答えの手前で諦めることになります。測れなかったぶんがあるかどうかは、数えれば 0 か 0 でないかで決まるので、終わったように見えること以外の手がかりになります。私の実験では、走らなかったテストを外したまま、差が無いという結論が出ていて、全部を合格させて数え直すと差が出ました。どちらのモデルのテストも見逃し、人が書いたテストは見逃さなかった 3 種は、課題に 1 段落を足して測り直すと、高いモデルの点だけが 3.33 から 5.00 へ伸びました。
理解したことは一文にできます。
差が無いという、終わったように見える結果は、測れなかったぶんが残っていても出て、AI はそこで止まる。だから、受け取る前に、測れなかったぶんが無いかを確かめさせ、あれば測り直させる。
諦める前に見る 2 つ
テストの見逃しを比べるこの実験では、測れなかったぶんは 2 つの形で残っていました。どちらもスクリプトで数えることができます。この 2 つが、この回の止めない条件です。
| # | 見るもの | 当てはまったら |
|---|---|---|
| 1 | 母数から外したものがあるか(走らなかった/エラーで落ちた/読むことができなかった/消した) | 戻してから数え直す。外したままの「差が無い」は、結論として読むことができません |
| 2 | 採点の項目のうち、全員が見逃し、人が書いたテストは見逃さない項目があるか | 課題を直して測り直す。その項目には、どのモデルの差も出ません |
どちらも、数えるだけで済みます。
3 度目にAIを引き止めたものは、この 2 つとは別です。
止めない条件を、真か偽かで書く
止める仕組みは、条件で書くことができます。たとえば「同じコマンドが 3 回続いたら止める」や「一覧の数が実際と違ったら止める」です。どの条件も、満たしているかどうかが真か偽かで決まります。
止めない条件も、書き方は同じです。Claude Code の hook の仕様では、Claude が応答を終えようとしたときに Stop の hook が走り、この hook が止まるのを取り消す判定を返すと、Claude は止まらずに作業を続けます。上で挙げた、引き戻す 2 本の hook も、この形です。
条件で書くことができないのは、「ここでは諦めるな」という言い方のほうです。この言い方は、満たしているかどうかが真か偽かで決まりません。
2 つの止めない条件は、「粘れ」と言う代わりに、何を数えるかを書いたもので、どちらも真か偽かで決まります。
| 書けないもの | 書ける言い換え |
|---|---|
| もう少し粘れ | 母数から外したものがあるなら、戻してから数え直せ |
| 結論を急ぐな | 全員が見逃し、人が書いたテストは見逃さない項目があるなら、それは差ではない |
仕組み: 1 回の採点に要る実行を少なく組む
止めない条件に当てはまると、AI は数え直すことになります。この実験でAIは、同じ 12 本のテストを、差し戻しのたびに、3 回数え直しました。1 回の採点は、9 回の実行で済む形で組んであります。
| 採点の組み方 | 1 回の採点に要るテストの実行回数 |
|---|---|
| 変異 1 種ごとに、12 本のテストをまとめて 1 回走らせる | 9 回(変異を入れない 1 回 + 変異 8 種で 8 回) |
| 変異 1 種ごとに、1 本ずつ走らせる | 96 回(変異 8 種 × 12 本) |
だから採点は、止めない条件を数える前に、1 回に要る実行が少ない形で組んでおきます。
検証手順: 「差が無い」と「まだ測ることができていない」を分ける
前提
- 比べる組ごとの結果が、1 件ぶんずつ残っていること。残っているのが平均だけなら、外したものがあるかどうかを見ることができません
- 人が書いたテストを、同じ項目で採点した結果があること。無ければ、手順 2 を行うことができません
所要時間: 15 分
手順
- 母数から外れているものを数える(走らなかった/エラーで落ちた/読むことができなかった)。1 つでもあったら、母数に戻してから数え直す(戻すには、エラーの出力だけを返して直させれば十分です)
- 採点の項目のうち、全員が見逃し、人が書いたテストは見逃さない項目を数える。1 つでもあれば、課題の言い方を 1 段落だけ変えて測り直す(比べるどの組にも同じ段落を足し、項目は伏せたままにする)
- 同じ結論を、2 通りの数え方で出す(例: 手数で数える/経過した時間で数える)
合格条件
- 手順 1 で、母数から外れているものの数を言うことができる(「たぶんゼロ」は、数えたことになりません)
- 手順 3 で、2 通りの数が 2 倍以内(離れていたら、どちらかの数え方に誤りがあります)
合格しなかったとき
- 外れているものがある —— 母数に戻してから数え直します。1 度目のAIは、これに当たっていました
- 全員が見逃し、人が書いたテストは見逃さない項目がある —— 課題の言い方を変えて測り直します(2 度目)
- 2 通りの数が離れている —— スクリプトを疑ってください(3 度目)
後始末
- 数えるたびに、何回目に数えた数かを書いて残します。書いておかなければ、あとで表を作るときに、別の回の数が混ざります(私は混ぜてしまい、記事を通読して見つけました)
CC BY 4.0 はここまで
諦めさせなくなったもの
- 私は、「差が出ませんでした」で畳むのをやめました
- 続けていることもあります —— 止める仕組みを足すことです。止める仕組みは、いまも足し続けています
次回は最終回、「振り回されない技術」です。第 1 回で「止まれない」を、この回で「止まりすぎる」を見てきました。