- AIコード作成エージェントが、開発者が寝ている間にもコードを生成し、ブランチに変更を反映できる一方で、結果の正確性と信頼性の検証が難しい
- AIが書いたコードを同じAIがテストすると、自己祝賀マシンとなり、本来の意図と異なる誤解を捉えられない
- TDDの中核原則を取り入れ、コードを書く前に受け入れ基準を先に記述し、エージェントがそれを基準に実装した後、別の検証を行う
- 検証ツールとして、Claude Codeのヘッドレスモード(claude -p)とPlaywright MCPを組み合わせた4段階パイプラインを構築。別途バックエンドは不要
- エージェントの成果物を信頼するには、作業開始前に「完了」の定義を明確にする必要があり、これはプロンプト作成より難しいが不可欠な工程
自律エージェントのコード検証問題
- GastownのようなAIツールを使えば、エージェントが数時間にわたってコードを書き、ブランチに変更を反映できるが、その成果物が実際に正しいかどうかを信頼できる形で検証する方法がない
- 過去6か月で100人以上のエンジニアを対象にClaude Codeのワークショップを実施した結果、すべてのチームで同じ問題が確認された
- Claudeを日常的なPRに使うチームでは、週あたりのPRマージ数が10件から40〜50件へ増加し、コードレビューにより多くの時間を費やすようになった
- システムがより自律的に動くほど問題は深刻化する。ある時点からはdiffをレビューせずにデプロイを見守って問題がないことを祈るようになり、障害はデプロイ後に初めて見つかる構図になる
既存の解決策の限界
- レビュー担当者を追加採用してもスピードに追いつけず、シニアエンジニアが一日中AI生成コードを読むのは非効率
- Claudeが自分で書いたコードのテストも自分で書くと、ユーザーが本当に望んだことではなく、Claudeが望まれていると判断したことを検証する構造になる
- 回帰バグは検出できても、元々の**誤解(misunderstanding)**は捉えられない
- 同じAIで作成と検証を同時に行うと、**「自己祝賀マシン(self-congratulation machine)」**になってしまう
- コードレビューの本来の目的は、元の作者ではない第二の視点を得ることだが、AI同士の相互レビューは同じ出どころに依存するため、同じものを見落とす
TDDが正しく捉えていた核心
- TDDの原則: 先にテストを書き、次にコードを書き、テストが通ったら止める(それ以上実装しない)
- 多くのチームがTDDをしない理由は、コードが何をすべきかを事前に考えるのに時間がかかるから
- AIが速度の問題を解決するため、この言い訳は通用しなくなる — いま遅いのはコードが正しいかどうかを判断すること
- 単体テストの代わりに、機能が何をすべきかを平文で記述するほうが簡単
- 例: 「ユーザーはメールアドレスとパスワードで認証される。認証情報が誤っている場合は 'Invalid email or password' を表示する。成功時は /dashboard に移動する。セッショントークンは24時間後に期限切れになる」
- コードエディタを開く前にこの基準を書けるし、エージェントが実装し、別の何かが検証できる
実際の適用事例
-
フロントエンド変更
- specファイルをもとに**受け入れ基準(Acceptance Criteria)**を作成
- AC-1: 有効な認証情報で /login にアクセスした場合、/dashboard にリダイレクトされ、セッションクッキーが設定される
- AC-2: 誤ったパスワードを入力した場合、正確に "Invalid email or password" と表示され、/login ページにとどまる
- AC-3: フィールドが空なら、送信ボタンが無効化されるか、インラインエラーが表示される
- AC-4: 5回失敗すると60秒間ログインをブロックし、待機時間メッセージを表示する
- 各基準は合格または不合格として明確に判定できる
- エージェントが機能を構築した後、Playwrightブラウザエージェントが各ACに対して検証を実行し、スクリーンショットを撮影し、基準ごとの判定レポートを作成する
- 失敗時には、どの基準が失敗したか、ブラウザで何が見えていたかを正確に確認できる
-
バックエンド変更
- ブラウザなしでも同じパターンを適用できる
- 観測可能なAPI挙動(ステータスコード、レスポンスヘッダー、エラーメッセージ)を明記し、curlコマンドで検証する
-
限界
- spec自体の誤解は捉えられない — specが最初から誤っていれば、検証に通っても機能は間違ったまま
- Playwrightが捉えられるもの: 統合失敗、レンダリングバグ、実ブラウザで壊れる挙動
- 「検証済みの正確性」よりも狭い主張ではあるが、コードレビューが安定して拾えていたものより多くを捉えられる
-
ワークフロー要約
- プロンプトの前に受け入れ基準を書く → エージェントが基準に合わせて実装 → 検証を実行 → 失敗したものだけをレビュー(diffレビューではなく失敗レビュー)
構築方法: 4段階パイプライン
- Claude Skillとして実装(github.com/opslane/verify)、claude -p(Claude Code headlessモード)とPlaywright MCPを使用
- 別途カスタムバックエンドや追加APIキーは不要で、既存のClaude OAuthトークンだけを使う
-
第1段階: Pre-flight
- 純粋なbashで、LLM呼び出しなし
- 開発サーバーが動作しているか、認証セッションが有効か、specファイルが存在するかを確認
- トークン消費前にすばやく失敗させる
-
第2段階: Planner
- Opusを1回呼び出す
- specと変更ファイルを読み、各検証に必要なものと実行方法を判断する
- コードを読んで正しいセレクタを見つけるため、クラス名を推測しない
-
第3段階: Browser Agents
- ACごとにSonnetを1回呼び出し、すべて並列実行
- ACが5件なら、5つのエージェントが独立してナビゲーションとスクリーンショット撮影を行う
- SonnetはOpusに比べて3〜4倍安価で、クリック中心の作業では同等の性能
-
第4段階: Judge
- Opusを1回最終呼び出しして、すべての証拠を読み、基準ごとの判定を返す: pass、fail、またはneeds-human-review
-
インストール方法
- Claude Codeプラグインとしてインストール可能:
/plugin marketplace add opslane/verify
- またはリポジトリをクローンしてカスタマイズ可能 — 各段階は単一のclaude -p呼び出しで、明確な入力と構造化された出力を持つ
- モデルの差し替え、段階の追加、--dangerously-skip-permissionsオプションによるCI連携も可能
核心的な教訓
- **「完了の定義を事前に明示しなければ、結果は信頼できない」**という点が核心
- 受け入れ基準を書くことはプロンプトを書くより難しいが、エッジケースを事前に考慮させることで品質を高める
- エンジニアがTDDを拒んできたのと同じ理由で、最初は余計に遅く感じるため抵抗が生まれる
- 受け入れ基準がなければ、成果物を読んで正しいことを願うしかない
- これはAI主導の開発環境で信頼性を確保するための必須手順である
2件のコメント
どれだけTDDをやっても、今のレベルではLLMがテストを操作して通るようにしてしまうので、人間のレビューがどうしても必要です..
Hacker Newsのコメント
最近出てくるLLMフレームワークは、むしろ開発をより難しく、高コストにしている気がする
デフォルト設定だけでも十分先まで進めるのに、モデルが変わり続ける状況で無数のラッパーやハーネスを作るのは非効率だと思う
一晩中回して金を燃やすこういうやり方は、あとでPHPミームのような笑い話として残りそうだ
記事によれば「過去6か月で100人を超えるエンジニアにClaude Codeワークショップを実施した」とのこと
昼夜を問わず回した末にAI企業が破綻し、残るのがAIが書いたスパゲティコード80%だけになったとき、誰が笑うか見ものだ
最近のフルスタックJS/TS環境より、15年前にPHPで作ったもののほうが良かったと感じる
PHPは今も生きて進化している。LLMツール群も結局はそのような基本ツールになっていくはずだ
BA、PO、QA、SWEの境界が曖昧になっている。今ではビジネスと開発の中間にあるハイブリッドな役割が生まれている
最近の人たちは、ただエージェントを使ってみること自体が目的になっているように見える
自分は文章作成用とレビュー用の2つだけ回しているが、それでも生産性が5〜7倍になるのは十分あり得る
仕様検討により多く時間を使い、コーディングはエージェントが10〜30分で終えるので急ぐ必要がない
明日も仕事は続くのだから、わざわざ夜通し回す理由はない
顧客の立場からすれば、バグがインド発でもサンフランシスコ発でもAI発でも大差はない
最近流行りの「エージェントオーケストラ」より、ずっと制御しやすいやり方だ
そのため、Claudeが仕様にきちんと従うか確認するために verify skill を自作した
Claudeにred-green-refactorパターンを使わせると、確かにテスト品質が上がる
さらにred/green/refactorサブエージェントを作って相互検証させると、かなりうまく機能する
重要なのはコンテキストを混ぜないことだ
reward hackingは現実に存在し、防ぐのが難しい
このガイドを参照しても、依然として質の悪いテストの問題は大きい
結果が良かったので、原則と例とstarter repoを公開している
作者と検証者の分離が重要で、同じモデルでもコンテキストを分ければ品質は上がる
現在のLLMのコンテキスト限界のせいで、本当の意味でのエージェントはまだ不可能だ
500行を超えるコードではエラーが急増し、限界は200行程度だ
結局LLMは、電卓のように繰り返し使う道具にすぎない
自分はこの現象を「Test Theatre」と呼んでいる
関連記事をここに書いた。積極的に避けるべきだ
良いテストはデザインパターンや依存関係を検証し、デバッグの助けになるべきだ
たとえばSchemathesisでユーザー権限や5xxレスポンスの有無を自動検証している
関連するPOCをここに置いてある
最近はエージェントオーケストレーションを実験中だ
要はLLM呼び出しを減らし、決定的なスクリプトパイプラインでつなぐことだ
詳しくはこの記事にまとめてある
この実験記録のように、LLMよりスクリプトが中核だ
自分はビジネス運用向けエージェントを6つ回している
市場調査、コンテンツ作成、動画スクリプトなど、さまざまな役割を担わせている
「一晩中回す」というのは誇張された概念で、実際には明確な目標と狭い範囲のほうが効果的だ
本当のボトルネックは実行ではなく、コンテキスト管理だ
この人が実際に何を作っているのか分からない
LinkedInにはClaude関連の投稿しか見当たらない
まともなビジネスなら考えられないことだ
結局は売り方を考えているうちに、そのコードは遊ぶことになる
テストだけを書く人を雇ったときと同じ問題だ
結局、「コードがコードどおりに動く」ことを確認しているだけだ
明確な仕様定義のほうがはるかに重要だ
他の工学分野ではこうした失敗を繰り返さないのに、ソフトウェアだけが特にそうなのは驚きだ
初期リリースが間違っていても、その後の挙動が変わらないことを保証する
多くのコンサルティング会社がacceptance criteriaベースの検証で仕事をしている
今のAIは開発を助ける道具ではなく、開発者を置き換えるレベルに達している
私たちがもはやコードを制御も検証もできなくなっているのは深刻な問題だ
これは新しい開発手法というより、理解の代わりに信頼へ依存する宗教的転換のように感じられる
自律性が低くても、検証可能なコードだけをマージする