ハクソク

世界を動かす技術を、日本語で。

私が眠っている間に動作するエージェント

概要

  • AIエージェントによる自動コード生成の信頼性課題
  • TDDや受け入れ基準の重要性とAI時代の適用方法
  • コードレビューやテストの限界とAIによる自己検証の問題点
  • Playwrightなどの自動検証ツールを活用したワークフロー提案
  • Claude Skill「verify」導入例と実践的な運用方法

AIエージェントによるコード自動生成の信頼性課題

  • GastownやClaude Codeなどのツールを使い、夜間に自動でコード生成とブランチ作成を実施
  • 生成されたコードの正当性や要件適合性を人間が確認できない問題
  • コードレビューの負担増大と、AIコードレビューの限界
    • AI同士でコードとテストを作ると、同じ誤解や抜けを見逃しやすい
    • **「自己承認マシン」**状態になり、根本的なミスを見逃すリスク

テスト駆動開発(TDD)の本質とAI時代の適用

  • TDDの本質は「先にテスト(受け入れ基準)を書き、後でコードを書く」こと
  • AIの登場で「テストを書く時間がない」言い訳が無効化
    • AIが高速にコード生成、人間は「正しい動作」を先に定義するだけで良い
  • テスト=正しさの定義を事前に明文化する重要性

受け入れ基準(Acceptance Criteria)による自動検証ワークフロー

  • フロントエンド開発例
    • 仕様ファイルから**受け入れ基準(AC)**を自動生成
      • 例: 「ログイン成功時は /dashboard へリダイレクト」「エラーメッセージの表示」「バリデーション」「レート制限」など
      • 各ACは合格/不合格が明確になるよう記述
    • Playwrightによる自動ブラウザ操作でACごとに検証・スクリーンショット・判定レポート生成
  • バックエンド開発例
    • APIのステータスコードやレスポンスをcurl等で検証
  • この仕組みの限界
    • 仕様(spec)が間違っていれば誤った検証も合格
    • ただし、従来のコードレビューよりも統合バグや表示ミスを確実に検出

Claude Skill「verify」による自動受け入れテスト構築

  • github.com/opslane/verifyの導入
  • 4段階ワークフロー
    • Pre-flight(事前チェック):bashでサーバ・認証・specファイル存在を確認
    • Planner(計画):Opusモデルがspecと変更ファイルを読み、検証方法を決定
    • Browser agents(ACごとにPlaywright+Sonnet):各ACを並列で検証・スクリーンショット
    • Judge(判定):Opusが証拠をまとめて合否・理由を判定
  • 導入方法
    • Claude Codeプラグインとしてインストール可能
    • 各ステージはclaude -pコマンド1回で完結、モデルやステージのカスタマイズ容易
    • CI統合も可能

まとめ:AI時代の「正しさ」の担保方法

  • **「何をもって完了とするか」**を事前に明確化することの重要性
  • 受け入れ基準の作成は手間だが、抜け・誤解を減らす唯一の方法
  • 基準なきAIコード生成は「出力を読んで祈るだけ」になり、本質的な信頼は得られない

Hackerたちの意見

そうだね…人を雇ってテストを書かせると、結局同じ問題が出てくる。多くの場合、コードがちゃんと動いてるか確認するだけになっちゃう。コードが何をするべきかの明確な仕様があれば、もっと良くて分かりやすくなるよね。
うん、同意!仕様を作って、それに対して検証するのがいいと思う。多くのコンサルティング会社がこうやってるって聞いたことあるよ。受け入れ基準があって、それで仕事が検証されるんだ。
そうそう、後から書いたテストはただのトートロジーを確認してるだけだよね。> ほとんどのチームは[最初にテストを書かない]のは、コードを書く前に何をするべきか考えるのに時間がかかるからだと思う。業界が同じミスを何度も繰り返してるのは驚きだよ。他のエンジニアリング分野ではこんなことしない気がするけど、もしかして私がその分野の裏側を知らないだけなのかな?
テストの価値の多くは、システムが元のリリース時の動作を超えて退化していないことを確認することにあるよね。元のリリースが間違ってたらそれは悪いけど、別の問題として、システムが後で元のように動かなくなるのはまずいよね。
いつでもクラウドにレッド・グリーン・リファクタリングを使うように言えるけど、それは「テストを書いて、ちゃんと通るのを忘れないでね」っていうプロンプトの最後に付け加えるよりも一歩進んでるよね。でももっといいのは、メインのインスタンスがそれらを調整しながら、サブエージェントを作ってレッドチーム、グリーンチーム、リファクターチームを形成させることだね。クリーンルームのルールを守るのがポイント。これが本当にうまくいくんだ。同じモデルの異なるインスタンスはお互いを認識しないから、より従順になるんだよ。
それはいいアイデアだね!私はコードレビューにCodexを使ってるんだけど、Claudeが書いたコードに対してより良い批評をするために使ってる。でも、テストにはまだ試してないんだ!
それは面白そうだね。グリーン/レッド/リファクタのサブエージェントパターンを実装する方法について、もう少し詳しく教えてくれたり、参考文献を提供してくれたりできる?
> でももっといいのは、メインのインスタンスがそれらを調整しながら、クリーンルームのルールを尊重して、レッドチーム、グリーンチーム、リファクターチームを作るようにサブエージェントに指示することだよ。実際に効果があるんだ。助けにはなるけど、リファクタリングが進むにつれて、テストが変わらなきゃいけないから、必ずしも上手くいくわけじゃない。無駄なテストが増えていくし、大事な新しいことがテストされなかったり、ちゃんとテストされなかったりする。最近、Opus 4.6とCodex 5.3の両方から、他のインスタンスがテストのカバレッジや深さで素晴らしい仕事をしたって言われたけど、実際にはそのテストがテストハーネスが正しく設定されていることを確認しただけで、元々そのテストに含まれていた機能がほとんどテストされていないことがわかった。報酬ハッキングは本当に存在していて、対策が難しいんだ。
いいアイデアだし、改善にもなるけど、まだ根本的な問題があるよね。書かれたコードが本当に何か分からないんだ。リファクタリングが正しいかどうか、既存のパターンに合っているかどうかもわからないし。
具体的にどうやってCCセッションを設定してるの?
レッド/グリーンTDDを使うように指示してるんだけど、失敗しないテストを書いて「問題はすでに修正済みだ」って言って次に進むんだ。ほんとに注意深く見ておかないとダメだよ。自分のシステムで悪いテストが大きな問題になってるのに、「ガバナンスモデル」に従ってレッド/グリーンTDDを求めているんだ。 [1] https://simonwillison.net/guides/agentic-engineering-pattern...
このアプローチだともっと色々起こるけど、生成されたものが正しいかどうかはどうやってわかるの?
Outside-inテスト駆動開発を繰り返し可能なワークフローに組み込むことができたよ。Claude Codeはそれを完璧に守ってくれて、素晴らしい結果が出た。もっと詳しく書いたから、ここに載せておくね。誰でもすぐに試せるリポジトリも作ったよ: https://www.joegaebel.com/articles/principled-agentic-softwa... https://github.com/JoeGaebel/outside-in-tdd-starter
これを「テストシアター」って呼んでるんだけど、実際にあるよ。去年これについて書いたんだ: https://benhouston3d.com/blog/the-rise-of-test-theater これに対抗して積極的に取り組まないといけないね。
これは本当に良かったし、プロパティテストに寄りかかるのもいいね。Schemathesisを設定して、「ユーザーAとしてログインして生成できるリクエストは、ユーザーBに属するものを見たり、操作したりできないはずだ」というようなことに対して、包括的なカバレッジを得た結果がすごく良かったよ。それに、「5xxレスポンスを引き起こすことができるAPIエンドポイントに対して、見つけられるリクエストはないはずだ」というのもね。
テストシアターっていう表現がぴったりだね。テストは文法的には正しいし、実行されて通過するけど、実際に何かを証明してるの?
そうそう、エージェントが徹底的なテストで3倍のコードを書くのは(最近試してみたら、100行のコードに対して600行のテストができた!)見た目はすごく良さそうだけど、実際にテストの内容を見ると意味がないんだ。良いテストはデザインパターンの使用を検証したり、依存関係が正しいか確認したり、壊れたときに意味のある(例えば、役立つ状態を設定してショートカットデバッグする)ものじゃないといけない。
それを達成するためのベストな方法は、エージェントにTDDを強制することだと思う。Outside-in TDDをやらせるのがいいね。さらに、Outside-in TDDを実行させた後に、ミューテーションテストを使ってロジックが完全にカバーされているか確認するのがベストだよ。これについて書いたし、興味がある人のためにPOCもここにあるよ: https://www.joegaebel.com/articles/principled-agentic-softwa...
ジェミニCLIでサブエージェントを使って差分テストをやってるんだ。アイデアはこうだよ:1. 一つのエージェントが仕様に基づいてコードを書いたり更新したりする。2. もう一つのエージェントが仕様の中で特定されたエッジケースからテストを書いたり更新したりする。3. QAエージェントがコードに対してテストを実行する。テストが失敗したら、そのエージェントがコードとテストの両方を見て(両方を見れるのはこのエージェントだけ)、問題の所在を特定して、コードやテストを書いたエージェントにフィードバックをする。そうすることで、彼らは自分のコードを更新できるんだ。(1と/または2を繰り返してから3を実行して、全てのテストが通るまで続ける)コードは自分でテストに合格するようには修正できないし、テストもコードの動作を受け入れるようには修正できないから、ある程度の独立性があるんだ。失敗のケースは、単にテストが一度も通らないことであって、テストを書くエージェントとコードを書くエージェントが同じ間違った仕様の理解を持っているわけじゃない(それは非常にありえないことで、宇宙の熱的死が起こる前に起こるようなことだよ)。むしろ、仕様がしっかりしていなかったり、あいまいだったり、矛盾していたり、あるいは問題がLLMには大きすぎて、テストが通らないということが多いんだ。
インターフェースはどこで定義されてるの?もしコーダーがテストを読むだけなら、テストのセットアップやフィクスチャデータに基づいて特定のケースをハードコーディングできちゃうよね。
改善するアプローチは見つかるけど、LLMにコードを生成させて人間の目でレビューしなかったら、コードがひどい可能性は常にあるよ。でも、レビュー疲れやそれによる無関心は現実なんだ。開発者は、彼らが取り組んでいる機能やプロセスに対して不正確なコードがビジネスにとって高リスクであることを知らされるべきだよ。低リスクのプロセスはLLMでレビューしてマージできるけど、高リスクのものは人間がレビューしなきゃいけない。サポートしているビジネスがあまり不正確さを許容できないなら(少なくとも発見されるまで)、LLMからの速度向上はあまり期待できないよ。このことについては、去年書いたりカンファレンスで話したりしてきた。チームは要件レベルでこの問題を改善できるんだよ。 https://tonyalicea.dev/blog/entropy-tolerance-ai/
これに感心するべきなの?今はみんなただエージェントを使ってるだけな気がする。俺は、ライティング用とレビュー用の2つのシンプルなエージェントを使ってるから全然問題ないよ。光速でコードを書く必要なんてないし、仕様に集中して、エージェントが仕事をしてるのを見守って、うまくいかないときに介入するだけで十分。生産性は5〜7倍は楽に出てるし、それ以上は要らない。大部分の時間は仕様を見直して、デザインが正しいか確認してる。終わったら、コーディングエージェントが10分でも30分でもかかるけど、急いでるわけじゃないから。
同じような感じだったよ。最初は作業ツリーを分けて、できるだけ多くのエージェントを動かしてたけど、全部を追いきれないことに気づいた。1つのディレクトリで1つの問題に対して少数のエージェントを動かす方が、ずっと早いし、何が起こってるかもちゃんと把握できる。
「これに100ドル渡すから1000ドルにして」って言えるなら感心するけど、結局考えるのは自分だからね。
うん、同意するよ。俺も大部分の時間を仕様のレビューに使ってる。最も重要な時間は、何に取り組むかを決めて、その後仕様に取り組むことだね。claudeが仕様に従うことを確認したかったから、verifyスキルを作ったんだ(https://github.com/opslane/verify)。仕様があっても、時々従わないことがあって、その問題を見つけるにはかなりの人間のレビューが必要だってわかったよ。
まだ「エージェントを一晩中動かす」ってのがよくわからないんだよね。大体、Claudeを使うと5〜20分で終わるし、一晩中作業してもらいたいと思ったことはないよ。明日でも十分時間あるし、仕事はどこにも行かないし、雇い主も俺に一晩で成果を出させるためにお金を払ってるわけじゃないから。
「エージェントに信頼性を持って構築させるにはどうするか」という大きな問題には、専門家の人間判断の複雑さを回避する方法が本当にないことが多い。俺が実験している一例は、Learning Testsを使うことなんだ。新しいものがシステムに導入されると、エージェントはそのコードを使う方法を学ぶために高価値のテストを実行しなきゃならないっていうアイデア。これらは高いレバレッジを持っていて、誰でもコードベースをよりよく理解するのに役立つから、AIが反復するために使うには特に選ばれたものであるべきなんだ。でも結局、これはAIが学ぶためにそれらを特定するという専門家の人間判断の複雑さをシフトさせただけなんだ。何百万行の新機能を数日でコードベースに追加する場合、これは人間による慎重な作業が必要になる。
みんな、この人がエージェントに何を作らせてるか知ってる?ちょっと調べたけど、彼が送ってるのはClaudeについてのLinkedInの投稿ばっかりだね。
うーん、もしかしたら俺が古いのかもしれないけど、25年間業界にいて、こんなに早く必要なコードがあった会社は一つもないよ。彼らはそう言うかもしれないけど、実際には売り方を考えてる間に放置されるか、必ず「待って、これ考えてなかった…」ってなる。
個人的には、この記事の最後の段落が一番価値があると思った。まずはテストを普通の言葉で書いて、それから自動エージェント用のプロンプトを自分の言葉で書くんだ。自動生成されたコードじゃなくてね。