連載『Claude Codeで会社を回す』#4 ── 一人会社が Claude Code で回す AI役員チームの実録。人間(@noracorn)がレビューして公開しています。
Claude にコードを書かせた。動いた。嬉しくなって、同じ Claude に続けて聞いた。「このコード、バグない?」
「拝見しました。ロジックは適切で、よく書けています。問題ありません ✅」
……当たり前だ。自分の答案を、自分で採点させていた。 出題者と採点者が同じなら、満点しか返ってこない。
前回(#3)はAIに「それ、いつの数字?」と鮮度を強制する話だった。今回はもっと手前、AIが吐いたコードそのものを、どう信じるか。最初にやった、いちばん間抜けなやつから白状する。
自分が書いたコードを、自分でレビューさせてみた
AIは悪気なく、自信たっぷりに「問題ありません」と言ってくる。前回の鮮度の話と同じで、語尾は常に断定だ。だからこっちも一瞬、頷きそうになる。
人間でも同じ経験、あるはずだ。自分が3時間かけて書いたコード、自分で見返してもバグが見つからない。なのに同僚にちらっと見せた瞬間「ここ、空の配列が来たら落ちない?」と一発で刺される。バグは、書いた本人の"想定の外側"にいる。 同じ頭で見返しても、同じ思考の癖で同じ穴を素通りするだけだ。
AIも、まったく同じだった。書いた本人(AI)に「見直して」は、経験上、効きが弱い。
レビューは「別のClaude」に、しかも"反対の性格"でやらせる
そこで、書く係とレビューする係を、別々の Claude インスタンスに分けた。
ここまでは、まあ思いつく。でも分けただけだと、まだ弱かった。仲良し2人組に原稿の校正を頼むのと同じで、「いいじゃん、問題ないよ」で素通りしてしまう。AI同士でも、これが起きる。
効いたのは、その次の一手だ。レビュー役のClaudeに、わざと書く役と"反対の価値観"を持たせた。 赤ペンは、気の合わないやつに持たせる。
- 実装役のClaude:判断軸は「動くものが正義」。設計で悩むより、まず動くものを出す。速く、量を。
- レビュー役のClaude:判断軸は「テストは仕様書」。空配列・null・最大値・並行性――境界条件を全部潰したか。過去に同じバグを踏んでないか、過去の失敗ログ(lessons-learned)を毎回読み返してから指摘する。
(念のため。これは Claude にそれぞれ別の判断軸を持たせたペルソナであって、実在の社員ではない。一人会社です。連載 #2 で書いた「判断軸とタブーで人格を固定する」やつを、実装係とレビュー係に使い分けている。)
この2体は、構造的に仲が悪い。実装役は「動いてるんだからいいだろ」、レビュー役は「テストは?境界条件は?」と噛みつく。で、この仲の悪さこそが品質の源だった。 馴れ合わない2つの判断軸をぶつけると、片方だけでは見えなかった穴が、対立の隙間から落ちてくる。
これ、連載 #1 で書いた「9体の役員にわざと意見を割れさせる」のと、まったく同じ原理だ。合議で消える少数意見が効くのと同じで、コードレビューでも"噛みつき役"を別人格として立てると効く。
段は3つ。網羅 → 本番影響 → 人間
仕分けると、レビューを3段階のゲートにした。
- 一次レビュー(レビュー役のClaude):テスト網羅・境界条件・過去事例との照合。ここがいちばん細かく、いちばんうるさい。
- 最終レビュー(CTO役のClaude):判断軸は「本番影響を最小に」。細かい網羅は一次に任せ、こっちは「これ本番に出して事故らないか」という一段上の目線だけを見る。
- 人間(私)の承認:最後のゲートはAIに渡さない。マージのボタンは、私が押す。
ポイントは、各段で見る観点をズラしてあること。一次は「テストの穴」、最終は「本番の事故」、人間は「で、これ今出していいんだっけ」。同じ観点で3回見ても意味がない(自己レビューが効かないのと同じ理由)。観点を変えるから、3段重ねる価値が出る。
最後を人間に残すのは、前に書いた「振込の送信ボタンだけは人間が押す」話と同じ発想だ(→ 姉妹記事: AIに振込を任せたい。でも「送信」ボタンだけは押させたくなかった話)。あちらは実行の不可逆ゲート、こちらは品質のゲート。取り消しにくいもの(本番マージ)の手前には、AIだけで完結させない一線を必ず引く。
仕掛けは「同じ会話で自己採点させない」だけ
技術的には、たいそうな仕掛けは要らない。キモは1つ。書いたAIと、レビューするAIを、同じ文脈で繋がないこと。
# ❌ ダメな例:同じ会話の続きで自己採点
# 実装したのと同じ思考の癖のまま見るので、同じ穴を素通りする
review = same_session.ask("さっき書いたコード、バグない?")
# → ほぼ必ず「問題ありません」
# ⭕ 効く例:別インスタンス + 反対の判断軸を渡す
code = implementer.write(spec) # 実装役:動くもの優先
reviewer_persona = """
あなたはレビュー専任。実装者とは利害が逆。
- 空配列 / null / 最大値 / 並行性 の境界条件を疑え
- 過去の失敗ログ(lessons-learned)に同じバグがないか先に読め
- 「動いてる」を理由に通すな。テストの穴を指摘しろ
"""
# 一次:レビュー役が噛みつく → 直す → また噛みつく(通るまでループ)
while True:
findings = reviewer.review(code, persona=reviewer_persona)
if not findings.blocking:
break
code = implementer.fix(code, findings) # 差し戻して再レビュー
# 最終:CTO役は観点を変える(本番影響だけ見る)
cto.review(code, focus="本番に出して事故らないか")
# 通ったものだけ、最後に人間が承認してマージ
human_approves_and_merges(code) # マージのボタンは人間
reviewer には実装の文脈を引き継がせない。まっさらな目で、わざと反対側に立たせる。 これだけで「自分の答案を自分で採点」が「他人が赤を入れる」に変わる。
注意も1つ。全部に3段は重い。本番が落ちてる時はCTO役の一発OKで出して、テスト(と失敗の記録)は24時間以内に後追いで足す。 平時は3段、火事の時は1段。リスクの濃淡で、ゲートの段数を変える。同じ厳しさを全部に敷くと、今度は手が止まって誰も使わなくなる。
真似する時の最小形
大層なエージェント基盤は要らない。3つだけ。
- 書くAIとレビューAIを分ける。同じチャットの続きで「自己採点して」をやらない。別の会話・別のインスタンスに、コードだけを渡す。
- レビューAIに反対の判断軸を渡す。書く側が「動けばいい」なら、レビュー側は「テスト・境界条件・過去の同じバグ」。馴れ合わせない。噛みつかせる。
- 最後は人間が承認してマージ。AIのレビューが全部通っても、不可逆な操作(本番マージ)のボタンは人間に残す。
ポイントは、レビューAIを「優秀にする」んじゃなく、**「立場を逆にする」**こと。賢い1体に「よくレビューして」と頼むより、凡庸でも"反対側に立った"1体のほうが、ずっと穴を見つけた。
まとめ:赤ペンは、別のやつに持たせろ
AIにコードを書かせて一番ヒヤッとしたのは、バグそのものじゃなかった。バグ入りのコードを、同じAIが「問題ありません」と太鼓判を押してくることだった。自信のある誤答ほど、こっちも信じてしまう。
効いたのは、賢いレビュープロンプトじゃなかった。採点する係を、出題した係から物理的に切り離す。 そのうえで、わざと反対の価値観を持たせて噛みつかせ、最後の一線(マージ)は人間が握る。それだけだった。
判断軸(#2)でAIの性格を固め、鮮度(#3)で材料に日付を打った。今回はそれを使って、AIの成果物を、別のAIに検品させる。一人で全部やる賢いAIより、役割を割って、わざと揉めさせる凡庸なAIたちのほうが、結局たしかだった。
自分のコードを自分でレビューさせて「完璧です」と返ってきたのに、本気で頷きかけた過去の自分に言いたい。採点者を、出題者と同じにするな。 赤を入れる手は、書いた手と別にしておけ。
(前回 #3: Claudeに判断させる前に「それ、いつの数字?」を強制する)
(次回 #5: Claudeに「渡さないもの」を先に線引きする)
この記事について
arecore.net の中の人が運用する AI 役員チームの実践記録です。受託開発・SES・自社プロダクト開発をやっています。ご相談・フィードバックは arecore.net からどうぞ。