公開日
2 つの AI モデルで相互にレビューし、Issue で回す
claude-slack-channel のコードを 2 つの AI モデルにレビューさせ、指摘を Epic・Task・調査の 3 階層の Issue に積んで回した。優先度の付け方、調査 Issue で裏を取ってから直す流れ、AI の指摘を鵜呑みにしないための型を書く。
はじめに
claude-slack-channel のコードは、ほとんど AI(Claude Code)が書いている。書いた本人に「問題は無いか」と聞いても、見落としは見落としのまま。別の目が要る。
そこで、2 つの AI モデルに同じコードをレビューさせ、出てきた指摘を GitHub の Issue に積んで、1 件ずつ潰す形にした。この記事は、その回し方を書く。以前、ポートフォリオの設計で「AI に判断材料を集めてもらい、決めるのは自分」と書いた。レビューも同じで、指摘を集めるのは AI、直すかどうかを決めるのは自分。
最初のレビューは、ブランチの中で回した
公開 2 日目の 9 月 30 日に、最初のレビューをした。このときは Issue を使っていない。指摘ごとに作業用の worktree でサブエージェントに修正させ、レビュー用のブランチにマージしていった。期限切れの実行許可の自動 deny や、ログの伏せ字の漏れは、このとき直した。
この方法は速いが、何を指摘され、何を見送ったかが残らない。コミットメッセージに理由は書いたが、指摘の一覧はどこにも無い。翌日から自分のチェックリストで直した分も含めると、どこまで見たのか後から追えなかったんだよな。
Issue の型を先に決める
10 月 1 日に、Issue テンプレートを 4 種類入れた。
- Epic。レビュー 1 回につき 1 件。Task への参照を並べ、Issue にしなかった指摘を「見送り」として理由付きで残す
- バグ報告。1 件に 1 つの不具合。再現手順、期待と実際の挙動、該当箇所の根拠を書く
- 機能・改善。1 件に 1 つの観点。「A と B を直す」は 2 件に分ける
- 調査。実機や仕様で確かめないと判断できないこと。1 件に 1 つの問いと、何が分かれば閉じるかを書く
重要度はタイトルの先頭に [高] [中] [低] で付ける。ラベルを増やすより、一覧で目に入るほうが使いやすい。
型を先に決めたのは、AI の指摘をそのまま Issue にしないため。AI は「要確認」の指摘をマジで自信ありげに書く。それをバグとして積むと、確かめていないことが確定事項として残る。確かめないと分からないものは調査にしかならない、という線をテンプレートで引いておく。
2 つのモデルでレビューし、Epic #32 に積む
レビューは、Opus と Sonnet の 2 つのモデルに同じコードを見せた。片方だけだと、そのモデルの癖で同じ種類の見落としが残る。2 つの結果を突き合わせ、Epic #32 の下に Task と調査を積んだ。
バグは #5 から #14、整理の改善は #15 から #24、CI の整備が #25、調査が #26 から #31 という並び。1 件に 1 つの観点なので、件数は多い。ただ 1 件ずつが小さいので、1 つの PR で 1 件を閉じられる。10 月 3 日に、この並びを上から順に PR で閉じていった。
調査 Issue で裏を取る
調査 Issue は、AI の指摘のうち「本当にそうなるか分からない」ものを置く場所。4 件の結果を書く。
- #27。Claude Code は応答中も入力欄を描くので、
!restartが応答中に/exitを打ち込むおそれがある、という指摘。実機で画面を見ると、応答中は末尾に「esc to interrupt」が出る。これがあるときは入力待ちとみなさないように直した - #28。警告ダイアログの自動応答が、前のセッションの発言に同じ文字列があると誤爆する、という指摘。選択肢の文言も画面にあるときだけ答え、起動し直す前に画面を消すようにした。文言は、手元の版で実際に表示された文字列で確かめた
- #26。応答の失敗を知らせる hook の
error_detailsがオブジェクトのことがあり、文字列しか写していなかった、という指摘。オブジェクトなら message を写すように直した。ただし、手元の記録にはまだこの形の例が無い。直したのは予防策で、効いたかは確かめていない - #30。PowerShell が Constrained Language Mode だとスクリプトが動かない、という指摘。手元は FullLanguage だったので、コードは変えず、トラブルシューティングに確認方法を書いた
4 件とも、指摘の内容そのものは正しかった。それでも調査を挟んだのは、「直した」と「直したつもり」を分けたいから。#26 のように、まだ再現していないものは予防策だと書いておく。
見送ったもの
直さないと決めたものもある。縮退モードで起動したブリッジを、後から通常モードに昇格させる案は見送った。MCP の初期化をやり直すことになり、直す範囲に対して手が大きすぎる。代わりに、起動時にロックの取り直しを 10 秒試す形にした(#7)。
見送りの理由は、コミットメッセージと Epic に残す。AI は見送りを提案しない。全部直すのが正しいと言ってくる。どこで止めるかは、自分で決める。
今のところの回し方
- レビューは 2 つのモデルで行い、突き合わせてから積む
- 1 件に 1 つの観点。「要確認」は調査にする
- 調査の結果は、予防策か、再現して直したかを分けて書く
- 見送りは理由付きで Epic に残す
次回は、Claude Code の hook で状態を Slack に知らせ、!restart で会話を引き継ぐ話。