Claudeに「概ね妥当です」を禁止したら、盲点が出てきた

Kimiのkimi-for-codingで執筆しました

とあるSaaSの事業を立ち上げようとしていて、そのセッションの成果物は「コード」じゃなかった。 実行計画と、品質ゲートの設計。 要するに「これからどう作るか」と「作ったものをどう検査するか」を、後で別のセッション(実装担当)が読んで動けるドキュメントに落とす仕事です。

品質ゲートの一部として、レビュー用のサブエージェントをいくつか定義しました。 そのうちの1体が、名前からしてやばい。 skeptic(懐疑論者)。 仕事は「設計書の主張を、論破しに行くこと」。

普通のレビューアは、検証するのが仕事です。 こいつは違う。定義にこう書いた。

  • 承認するな。反証しろ。
  • 「概ね妥当です」で締めるのを禁止する。
  • 指摘が0件なら、代わりに「反証を試みたが失敗した観点のリスト」を出せ。

我ながら、感じの悪いエージェントを作ったなと思った。

定義を書き終えた瞬間、いちばん自然な次の一手が浮かんでしまう

skepticの定義ファイルを保存した。 その瞬間、当たり前のように思ったんです。

こいつを、いま自分が書いたばかりの設計書に向けたらどうなる?

自分で「論破するのが仕事」と定義したエージェントに、自分の書いた実行計画を渡す。 マゾかな、と思いつつ実行した。

結果、MAJOR(重め)が4件。 自分の書いたばかりの、乾いてすらいない設計書から。

何が刺さったか

いちばん効いたのがこれ。

自分で決めたルールに、自分で矛盾する記述を書いていた。

このプロジェクトには「外向きの通信を全部塞ぐ」という強めのルールがある。 そしてそのルールには「抜け穴はここ1箇所だけ」という不変条件がついている(唯一の穴、と自分で定義していた) なのに設計書の別の場所で、しれっと「新しい抜け穴を、既存の手順を流用して足す」と書いていた。 唯一のはずの穴を、手順の使い回しで二つ目を開ける、と。 自分で書いた不変条件を、自分で踏み抜いていたわけです。

残り3件も、性質は同じ穴でした。

  • 法律の専門家に確認しないと確定できない話を、一次調査の所見でしかないのに「〜で確定」と断定調で書いていた(専門家待ち、と別の場所には書いてあるのに)
  • ある作業フェーズの「完了条件」に「台帳に記録する」と書いたのに、その台帳がどこにも定義されていない。記録先が無いので、完了したかどうか誰も判定できない
  • 先に走らせるフェーズが、後で走るフェーズの成果物に依存していた。順番が、こっそり循環していた

どれも、他人のPRだったら10秒で気づくやつです。 自分が15分前に書いた文章だと、まったく見えない。

なぜ効いたか(「概ね妥当です」を禁止したから)

普通に「この設計、レビューして」と頼むと、AIはだいたい優等生の顔をします。 「よくできています。いくつか小さな改善点が…」 その「小さな改善点」に、さっきの4件は混ざってこない。

効いたのは、成功条件をひっくり返したことだと思う。 「問題を見つけられない=成功」のレビューアと、 「論破できない=敗北」のレビューアは、 同じドキュメントを読んでも、まったく違う動きをする。

後者は、粗を探しにこないと自分が負けるので、必死で穴を探す。 「概ね妥当です」で逃げる道を、定義であらかじめ塞いでおいたのが効いた。

学び

ドキュメント駆動で開発を回していると、正本(=真実の置き場)をどれだけ整えても、 その正本を書いた本人が、いちばんその正本をレビューできない、という壁に必ずぶつかる。 書いた直後は、脳内の「言いたかったこと」が文字を上書きしてしまって、書いてない前提まで見えてしまうから。

だから雇うべきは、承認してくれるレビューアじゃない。 論破してくるレビューアを、成果物を書いた自分自身に向けて放つ。

しかも今回いちばん皮肉だったのは、その論破エージェント自体が、今回の設計の成果物だったこと。 作ったばかりの検査器で、作ったばかりの設計を撃った。 検査器の価値は、自分に向けた瞬間にいちばん濃く出る。

直したあと、同じskepticをもう一周かけるかは迷った。 無限に殴られ続ける気もするので。