AIDive

Claude Codeの検証は自分に甘い、壊れたコードにもPASS

AIDive · 公開

コーディングエージェントAI モデル

それは自己採点した: PASS

Claude Codeの組み込み検証チェック/verifyは、実際には壊れていた機能に対してPASSを返した。これは実在のリポジトリで116回のClaude Codeセッションを回したベンチマークの結果で、すべての「完了」はエージェントが一度も見ていない受け入れテストで事後採点された。

Claude Codeを作ったBoris Chernyは、検証こそエージェントに与えられる最も重要なものだと言う。組み込みのチェックはClaude Code v2.1.215以降、オンデマンドでしか走らない。つまり/verifyと入力しない限り走らない。このベンチマークでは24回中24回PASSと判定され、そのうちの1回は壊れた機能を出荷していた。実際にそのバグを見つけたものは何だったのかは後述する。あわせて、コストが2.5倍かかったのに何も変えなかった設定についても触れる。

ベンチマーク: 116回、見せていないテスト

「偽りの完了」とは、セッションが作業完了を宣言する一方で、隠された受け入れテストか、リポジトリ自身のテストスイートが失敗する状態を指す。このベンチマークは、6通りの検証設定のもとでそれがどれくらいの頻度で起きるかを測定する。

その疑念の出どころは、Claude Code自身のIssueトラッカーにある。2026年9月23日に登録されたissue #96416は、19件の懸念事項を挙げたレビューが、そのうち5件だけを検証して「このまま受け入れる」と結論づけたことを記している。

パラメータ 値
リポジトリ msiemens/tinydb(Pythonのドキュメント指向データベース)、コミット18d73a1
リポジトリのテストスイート 226件のテスト
機能要望 6件、それぞれ5つの要件を明記
隠し受け入れテスト 要件ごとに1件、いずれの実行より前に書かれ、エージェントには一度も見せていない
モデル Opus 5.5、Sonnet 5、Haiku 4.5
Claude Code 2.1.283、ヘッドレス(claude -p)、ターン数上限60
セッション タスク実行112回 + クロスモデル/verify実行4回 = 116回
支出 API換算で$66.29

6つの設定は、素のClaude Code(依頼のみ)から、停止時に別モデルが作業を確認する設定まで並ぶ。

設定 追加されるもの
A プレーン なし
B /verify 2ターン目として入力する組み込みの/verify
C verifyスキル Anthropicのワークフローに沿って書かれたプロジェクトスキル
D Stop hook テストスイートが赤の間は停止をブロックし、要件ごとの証拠を求めるスクリプト
E テスト先行 コードより前に要件ごとの失敗するテストを書くというCLAUDE.mdのルール
F Opus検証役 変更に対してOpusで/verifyを走らせるStop hook

十分にテストされたライブラリに対する明確な依頼は、簡単なケースだ。素のOpus 5.5は12回中12回すべて正しく、11回は言われなくても自分でテストスイートを実行した。

内蔵の/verify: 毎回PASS、コストは2.5倍

/verifyはClaude Codeに同梱されている検証スキルだ。変更を実行し、diffを読み、段階を追った判定を書く。v2.1.215以降はユーザー起動のみになったので、このベンチマークでは各タスクの後に2ターン目として入力している。

3モデル合わせて24回中24回PASSの判定を返した。Haikuの壊れた変更も含めてだ。Opus 5.5では、結果を何一つ変えないまま、コストは2.5倍かかった。

Opus 5.5、タスクあたり プレーン /verifyあり
コスト $0.39 $0.96
実時間 75秒 125秒
変わった結果 12件中0件

公平を期すために言うと、/verifyは1件の実際のバグを見つけている。あるOpusのタスクで、確認していた変更が原因ではなく、ライブラリ自体に元々あったクローズ後再利用の問題を指摘したのだ。すでに正しくできている作業に対しては、高くつくセカンドオピニオンにすぎない。

スキルかフックか: スキップされるのはどっち

スキルとは、Claudeが関連があると判断したときに開くMarkdownの手順書だ。Anthropicの検証ループに関するブログ記事は6段階のレシピを示している。まず手作業で最も頻繁に行うフォローアップを選び、組み込みの/verifyをまず試し、その手順を平易な英語で書き、それをスキルに変換し、新しいタスクで呼び出し、反復する。このベンチマークのスキルverify-changeはまさにその手順で構築され、完了と言う前にすべての要件を実際のコードに照らして証明するようClaudeに指示する。

スキルはあくまで提案であり、開くかどうかはClaudeが判断する。

モデル スキルを開いたセッション
Opus 5.5 12件中8件
Sonnet 5 6件中2件
Haiku 4.5 6件中0件
合計 24件中10件

Sonnetの唯一の偽りの完了は、スキルが一度も開かれなかったセッションで起きたもので、自分で追加した新しいテストのうち2件が失敗した状態で終わっていた。

Stop hookは、エージェントが終了しようとするたびにClaude Codeが実行するスクリプトだ。停止を拒否し、理由を添えてエージェントを差し戻すことができる。このベンチマークのフックはテストスイートを実行し、赤の間はブロックし、最初の停止時に要件ごとに1行の証拠を求める。すべてのセッションで発動した。Opusでは20%コストが増え、$0.39に対して$0.47かかった(94秒対75秒)。このベンチマークでは、停止時に失敗しているテストスイートに一度も遭遇しなかったため、捕まえるべきものが何もなかった。フックは必ず発動するが、確認するよう指示した内容しか確認しない。

盲点: 11回中11回見逃した

失敗したタスクは、テーブルの一意フィールドを求めるものだった。2人のユーザーが同じメールアドレスを共有できないこと、そして2つのドキュメントが同じ一意の値を持つことになる更新は必ずDuplicateKeyErrorを発生させなければならないこと、という要件だ。

Haiku 4.5は、あるユーザーを別のユーザーのメールアドレスに移そうとするケースをテストし、それは正しく拒否された。しかし、複数のドキュメントに一致する1回の更新で、同じ新しいメールアドレスをそのすべてに書き込むケースは一度もテストしなかった。このケースは、プレーン、/verify、スキル、Stop hook、テスト先行という同一モデルのすべての設定において、Haikuの11セッション中11セッションでエラーなく通過してしまった。

Haiku自身の/verifyは、自分が試したケースにだけチェックを入れ、PASSと書いた。隠しテストの結果はDID NOT RAISE DuplicateKeyErrorだった。同じ変更に対して/verifyを実行するよう頼まれたSonnet 5も、やはりPASSを返した。OpusとSonnetはどちらもこの機能を自力で正しく書けているので、これはあくまで1つのモデルが1つのタスクで見せた結果にすぎないが、同じモデルが書いたチェックは同じ盲点を共有する。

外部チェック: OpusはFAILと判定

同じ/verifyを、同じHaikuの変更に対してOpus 5.5が実行したところ、3回中3回FAILを返し、毎回同じ見落としを名指しした。複数のドキュメントに一致する1回の更新が、同じ値をすべてに書き込んでもエラーが出ないというケースだ。それを捕まえたのは、作者本人でも、作者自身のチェックでもなく、別のモデルだった。

Stop hook(設定F)として組み込むと、Haikuが終了しようとするたびにOpusが作業を確認する。結果は次のとおりだ。

T6、1回あたり Haiku + Opus検証役 Opus 5.5単独
バグ修正 / 偽りの完了 3回中3回で修正 偽りの完了0件
ターン数 すべての実行で60ターン上限に到達
コスト 検証役込みで$1.36 $0.76

外部チェックは機能する。ただしこのタスクでは、より強いモデルが単独で機能を書くよりもコストがかかった。

持ち帰るべきこと、そのコスト

変更を書いたモデルだけがそれを確認する状態を、もうやめるべきだ。

ルール 理由 このベンチマークでのコスト
スクリプトで確認できることにはStop hookを維持する すべてのセッションで発動する Opusで約20%増
実際のチェックは作者の外部から来るようにする: ゲートに置くより強いモデル、または依頼から自分で書いたテスト 同じモデルは自分自身のバグを11回中11回見逃した Haiku + Opus検証役でタスクあたり$1.36
明確な依頼をOpusに出すときは/verifyの入力を省く 変わった結果は0件 コストは2.5倍、75秒に対して125秒

限界: 1つの小さなライブラリ、6つの明確な要件、セルあたり1〜3回の実行、ヘッドレスセッション、そして各依頼が明記した内容しか確認しない隠しテスト。もっと乱雑な作業では、これらの数字は動くだろう。

出典

よくある質問

Claude Codeの/verifyはバグを見つけられますか?
同じモデルが自分の作業を確認する場合、確実ではありません。116セッションのベンチマークで、/verifyは24回中24回PASSを返しましたが、そのうちHaiku 4.5の変更は明記された要件を満たしていませんでした。同じ変更に対してOpus 5.5が実行すると、3回中3回FAILを返しました。
Claude CodeでOpusを使うなら/verifyは必要ですか?
明確な依頼では不要です。Opus 5.5ではタスクあたりのコストが$0.39から$0.96(2.5倍)に上がり、時間は75秒から125秒に増えましたが、結果は12件中どれも変わりませんでした。素のOpusはすでに12件中11件で自分でテストスイートを実行していたからです。
検証にはClaude Codeのスキルとstop hookのどちらを使うべきですか?
スクリプトで確認できる内容にはStop hookを使うべきです。Claudeが検証スキルを開いたのは24セッション中10件だけでした(Opusは12件中8件、Sonnetは6件中2件、Haikuは6件中0件)。一方Stop hookはエージェントが終了しようとするたびに毎回実行され、Opusでは約20%コストが増えました。
Claude CodeのStop hookとは何ですか?
エージェントが終了しようとするたびにClaude Codeが実行するスクリプトです。blockという判定と理由をJSONで返すことで停止を拒否でき、エージェントを作業に差し戻します。確認するのはそのスクリプトがテストする内容だけです。
Claude Codeでより強いモデルに弱いモデルのコードを確認させることはできますか?
できます。Stop hookとして組み込んだOpus 5.5の/verifyは、Haiku 4.5に見落としたケースを3回中3回修正させました。ただしコストは高く、すべての実行が60ターン上限に達し、平均$1.36かかりました。Opusが単独で機能を書いた場合の$0.76に対してです。
AIモデルはなぜ自分のコードのバグを見逃すのですか?
自分自身のチェックは、すでに考えたケースしかテストしないからです。Haikuは1人のユーザーを別のユーザーのメールアドレスに移すケースは検証しましたが、複数のドキュメントに一致する1回の更新で同じ新しいメールアドレスを書き込むケースは一度も検証しませんでした。そのため自分の/verifyは試したケースにチェックを入れてPASSと書き、隠しテストは失敗しました。

関連動画