code-reviewスキルの中身を調べてみる
はじめに
claude codeのv2.1.147にて、claude code組み込みのsimplifyスキルがcode-reviewスキルという名前に変更されました
リリースノートには、以下のように書かれています
Renamed /simplify to /code-review. It now reports correctness bugs at a chosen effort level (e.g., /code-review high); pass —comment to post findings as inline GitHub PR comments. The old cleanup-and-fix behavior has been removed
simplifyスキルは、直近の変更をレビューし、修正まで一貫して行ってくれるスキルです
これが、code-reviewという名前に変更され、--commentでの動作が変更されたり、--effortを受け取れるようになりました
また、v2.1.152では--fixで以前のsimplify相当の動作をするようになっています
code-reviewスキルはclaude codeの組み込みスキルであり、jsによって、動的にコンテキストが生成される仕組みになっているようです
そのため、直接markdownファイルを読むことはできません。 しかし、claude codeがスキルをロードした後、その内容を出力してもらうことでスキルの内容をうかがい知ることができます
この記事では、code-reviewスキルの内容を読み解き、自作スキルのヒントやAIレビューで利用するプロンプトの参考にできる要素を探していきます
前提条件
今回の検証はClaude Code v2.1.163を利用しています
code-reviewスキルは組み込みのスキルであり、ロード時にjsが動的にプロンプトを生成する仕組みのようです
ロードするまで内容が読めないため、ロード結果をclaude-opus-4-8[1m]に出力させることでスキルの内容を調査しています
全体のフロー
code-reivewスキルの全体のフローを確認してみます
effortレベルによってフローが変化します
lowでは、単一のエージェントで差分だけを確認します
以下は、xhighのパターに沿って解説します
詳しいeffortレベルごとの違いはのちの章で解説します
フェーズ0: diffの収集
git diff @{upstream}...HEADを実行して、直近のcommitを調べます
ただし、upstreamがなければ
git diff main...HEADgit diff HEAD~1
などフォールバックされるようです また、未コミットの変更がある場合にはその差分もレビュー対象に含まれます
ここで確定したdiffが、レビューのスコープになるようです
引数でPR番号やブランチ名が指定された場合には、そちらが対象になりますが、主にpush前やcommit前のセルフレビューに利用する意図で作成されているように見えます
フェーズ1: 指摘候補の発見
複数の観点をサブエージェントを使って並列に調査させ、指摘の候補を作ります
effortの設定によって、ここで上げることのできる指摘の数が決まっているようです
例えば、xhighでは観点ごとに8つまでの指摘を上げることができますが、mediumやhighは6つまでです
見ている観点は最大で以下の5種類ですが、DとEはeffortがxhigh以上の時のみ確認されます
観点A: 行単位のdiffスキャン
- 各差分を1行ずつ読み、更に差分を含むメソッド全体を読む
- 変更されていない行であっても、差分を含むメソッド内であればレビュー対象とする
- 各行に対して、「どんな入力・状態・タイミング・プラットフォームであればこの行は不具合を生むか」という視点でレビューを行う
観点B: 削除された振る舞いの監査
- 削除された差分に対して、それが守っていた普遍条件や振る舞いを言語化する
- 不変条件が新しいコードでも担保されているかを検証し、担保されていなければ指摘候補とする
観点C: ファイル横断検査
- 差分が発生した各メソッドについて、呼び出し元をGrepで探して、不具合が生まれていないかを検証する
- 新たに生まれた暗黙的な条件、戻り値の型の変化、例外、呼び出しタイミングなどを検証する
- 呼び出し元だけでなく、呼び出し先も同様の確認を行う
観点D: 言語特有の不具合の調査
- 差分のある言語やフレームワーク固有の不具合について調査する
- その他、SQLインジェクションやタイムゾーンのズレ、浮動小数点の等値比較など、典型的な不具合の種を調査
- effortレベルが
xhigh以上でのみこの観点での調査を行う
観点E: ラッパーやプロキシの正しさを検証
- 別のオブジェクトを包んで機能を足す実装パターン(proxy、decorator、adapter、delegate など)を追加・変更したPRで調査する
- 各メソッドがその中身へきちんと処理を渡せているかを確認する(うっかり自分自身を呼び出してしまうと、無限ループや二重処理を引き起こすため)
- 中身が持つメソッドのうち、呼び出し元が使うものをラッパー側でも漏れなく用意できているか(渡し忘れがないか)を確認する
- effortレベルが
xhigh以上でのみこの観点での調査を行う
フェーズ2: 検証
フェーズ1で挙げられた全ての指摘候補を検証します
まず、同じ行で、同じ根本原因による指摘は、重複排除します。 残った各指摘候補に対して、検証用のサブエージェントを起動し、3つの状態のいずれかに分類します
REFUTEDであったものは、候補から削除します
- CONFIRMED: トリガーとなる入力や状態を特定でき、再現可能なもの
- PLAUSIBLE: タイミングや環境に依存し、再現方法が確立できないもの
- REFUTED: 誤検出や、発生し得ない不具合であったもの
フェーズ3: 取りこぼしの確認
差分やそれが含まれるメソッドを新しいレビュアーとして再読し、まだ挙げられていない指摘がないかを探します
フェーズ1で見切れていない副作用やテストの setup/teardownの非対称などを検証します
最大8件まであげ、なければから配列を返します
出力
ここまでで指摘候補となっているものを深刻度の高い上位15件までに絞って出力します 出力時には、該当ファイルと該当行、1文で内容を説明したサマリを返します
effortごとの動作の違い
effortごとに、フローや件数の制限に違いがあるため、表にまとめます
lowではサブエージェントを使ったレビューはそもそも行われません
それ以外のeffortでは、レビュー観点の数や指摘できる上限数が異なります
| effort | レビューする観点数 | 観点あたり候補上限 | 検証 | 取りこぼし確認 | 合計指摘数上限 |
|---|---|---|---|---|---|
low | メインエージェントで差分を確認するのみ | 指定なし | なし | なし | 4つまで |
medium | A,B,Cの3観点 | 6 | あり | なし | 8つまで |
high | A,B,Cの3観点 | 6 | あり | なし | 10つまで |
xhigh | A〜Eの5観点 | 8 | あり | あり | 15つまで |
max / ultra | A〜Eの5観点 | 8 | あり | あり | 15つまで |
code-reviewスキルから学べること
effortの違い
effortレベルの違いは、単にレビューエージェントのeffortレベルを変化させるだけでなく、差分の確認方法や検証フローにまで違いがありました。 effortレベルの差が明確なコストとレビューの深さのトレードオフを反映しており、利用側の設定への期待を反映しやすい構造になっているように感じます
サブエージェントを使った並列でのレビュー
low以外では、サブエージェントを利用した並列レビューが行われています。
これは、自分の書いたコードに対するレビューが甘くなる、既知のLLMの挙動を避けるために役立っていると感じました
特に面白いと感じたのは、サブエージェントの観点です。 よくあるパターンだと、命名規則、アーキテクチャ遵守などでサブエージェントを分ける方法が取られていると思います
しかし、このスキルでは
- 行単位の差分検証
- 削除された振る舞いの検証
- ファイル横断での検証
- 言語特有の不具合 のような、レビューの仕方によって観点を切り分けています
これは、実際にシニア以上のエンジニアがレビューを行う際の方法そのものだと感じました
人間のレビューでは、まず全ファイルから命名規則だけを見るではなく、まずは全体の流れを追い、その後、各ファイルの差分を細かく見ていくようなフローが多いと感じます
より人間のやり方に近い方法で観点を切り分けていることが、出力の質が良いと感じる理由なのではないかと感じました
事後の検証や重複排除
code-reviewスキルでは、レビュー結果を、何度も再検証していました
サブエージェントで並列に指摘を生成した場合、重複や誤認識を0にすることは難しいと感じていたので、これはとても納得できる方法でした
また、指摘の数に上限を設けていたのも印象的です
effortが高い場合には、細かな指摘までたくさん出ることを期待しますが、mediumのような低めのeffortで重箱の隅をつつくような指摘が多く出ると重要な指摘が埋もれてしまいます
数に上限を設けて、重要な指摘のみを行うことで、大量のnit pickで埋もれてしまう現象をシンプルに防げていると感じました
まとめ
新しいcode-reviewスキルでは、LLMに、effortレベルに沿った期待にあう粒度のレビューを実施するための細かな工夫が詰まっているように感じました
実際に、私が普段利用しているレビュー用スキルをcode-reviewスキルに習って修正することで
- 不要なnit pickの減少
- 総トークン消費の削減
- 重要な指摘の見落とし量減少
などの効果を、
skill-creatorを利用して定量的に確認することができました