| name | review-learn |
| description | PRレビューで受けた指摘をCLAUDE.mdのルールとして蓄積するスキル。`/review-learn` または `/review-learn #123` で使用。レビュアーの知見をチーム全体の資産に変換し、同じ指摘を繰り返さないコードベースを実現する。 |
Review Feedback Learner
PRレビューで受けた指摘をCLAUDE.mdのルールとして蓄積するスキル。レビュアーの知見をチーム全体の資産に変換する。
目的
Boris Cherny氏のTip #3「CLAUDE.mdへの投資」の拡張版:
- PRレビューで指摘されたパターンをCLAUDE.mdに自動蓄積
- 同じ指摘を繰り返し受けることを防止
- レビュアーの暗黙知をチーム全体で共有
lessons-md-managerとの補完関係
| スキル | 学びの源泉 | タイミング |
|---|
/lessons | 自分で気づいた失敗・修正 | セッション終了時 |
/review-learn | 他者からの指摘 | PRマージ後 |
両方使うと、個人の気づき+チームの知見が蓄積される。
トリガー
/review-learn - 直近のマージ済みPRから学ぶ
/review-learn #123 - 指定PRのレビューコメントから学ぶ
/review-learn --my-prs - 自分が作成したPRのレビューから学ぶ(直近5件)
- 「PRレビューから学んで」「レビュー指摘をまとめて」等の自然言語
System Instructions
ステップ1: 対象PRの特定
引数がある場合(PR番号指定)
gh pr view {PR番号} --json number,title,author,reviewDecision,reviews,comments
引数がない場合(直近のマージ済みPR)
gh pr list --author @me --state merged --limit 5 --json number,title,mergedAt
ユーザーに対象PRを確認する:
直近のマージ済みPR:
1. #123 - Fix animation flickering (2日前)
2. #120 - Add user authentication (5日前)
3. #118 - Refactor API client (1週間前)
どのPRのレビューから学びますか?(番号 or 全て)
ステップ2: レビューデータの取得(GraphQL + REST ハイブリッド)
変更理由: isResolved / isOutdated は REST API では取得できず、GraphQL でのみ取得可能。
対応済み判定に必須のため、GraphQL をメインのデータ取得手段として使用する。
gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
author { login }
commits(last: 100) {
nodes {
commit {
committedDate
message
additions
deletions
}
}
}
reviewThreads(first: 100) {
nodes {
isResolved
isOutdated
path
comments(first: 10) {
nodes {
author { login }
body
createdAt
}
}
}
}
reviews(first: 50) {
nodes {
author { login }
state
body
}
}
}
}
}
' -f owner='{owner}' -f repo='{repo}' -F pr={pr_number}
取得データの用途:
reviewThreads: 各スレッドの isResolved / isOutdated で対応済み判定
commits: コメント後の同一ファイルへのコミット有無を確認
reviews: APPROVED レビューの body から具体的指摘を抽出
author: PR作者の特定(返信の判別に使用)
ステップ2.5: 対応済みフィルタリング
目的: 「対応した指摘のみをナレッジ化する」ためのフィルタ。
Bot の的外れな指摘や、未対応のコメントをノイズとして除外する。
2a. コメント著者の分類
| 著者種別 | 判定方法 | デフォルト扱い |
|---|
| Bot | login が [bot] で終わる or GitHub API の is_bot | 蓄積対象外 |
| 人間 | 上記以外 | 蓄積候補 |
2b. 「対応済み」判定ロジック(信頼度順)
以下の順で判定し、最初にマッチした条件を採用する:
対応済み判定(thread):
1. thread.isResolved == true → 対応済み(確定)
2. thread.isOutdated == true かつ
thread.comments[0].createdAt 以降に同一ファイル(thread.path)へのコミットあり
→ 対応済み(高確度)
3. PR作者からの返信に対応キーワードあり
("対応しました", "修正しました", "fixed", "done", "updated")
→ 対応済み(中確度)
4. いずれにも該当しない → 未対応
2c. 著者種別 × 対応状況のマトリクス
| 対応済み | 未対応 |
|---|
| Bot | 蓄積候補に昇格 | 除外(デフォルト) |
| 人間 | 蓄積候補(高優先) | 除外 |
- Bot でも対応した指摘は有用なため蓄積候補に含める
- 人間でも未対応(放置)の指摘は的外れだった可能性があるため除外
2d. APPROVED レビュー body の特別処理
レビュー state: APPROVED の body に具体的な指摘(番号付きリスト等)が含まれる場合:
- APPROVED = レビュアーが対応を確認済みという強いシグナル
- body 内の各ポイントを個別の蓄積候補として扱う
- これらは「対応済み(確定)」として扱う
例: APPROVED レビューの body が以下の場合
LGTMです。以下の修正ありがとうございました:
1. LifecycleResumeEffectの追加
2. トリガーイベントの送信タイミング修正
→ 2つの個別の蓄積候補として抽出
ステップ3: コメントの分類
レビューコメントを以下のカテゴリに分類:
| カテゴリ | 判定基準 | 例 |
|---|
| 命名規則 | 変数名、関数名、クラス名への指摘 | 「fetchではなくgetを使う」 |
| アーキテクチャ | レイヤー構造、依存方向への指摘 | 「ViewModelからRepositoryを直接呼ばない」 |
| エラーハンドリング | 例外処理、Resultパターンへの指摘 | 「Resultでラップして呼び出し元で処理」 |
| テスト | テストコード、カバレッジへの指摘 | 「エッジケースのテストを追加」 |
| パフォーマンス | 効率、最適化への指摘 | 「N+1クエリに注意」 |
| セキュリティ | 脆弱性、認証への指摘 | 「入力値のサニタイズ」 |
| コードスタイル | フォーマット、可読性への指摘 | 「早期リターンを使う」 |
| ドキュメント | コメント、READMEへの指摘 | 「公開APIにはdocstringを」 |
ステップ4: ルール化可能な指摘の抽出
以下の基準で「ルール化すべき指摘」を抽出:
抽出対象:
- 繰り返し適用できる一般的なパターン
- プロジェクト固有の規約・慣習
- 「〜すべき」「〜しないこと」という形式化できる指摘
除外対象:
- タイポの指摘(1回限り)
- 特定のバグ修正(再現性なし)
- 好みの問題(「私なら〜する」)
- 曖昧なコメント(「ここ気になる」)
- 未対応のコメント(ステップ2.5のフィルタで除外済みだが、明示的に除外)
- Bot コメントで対応していないもの
- resolve せずに放置されたスレッドで対応コミットもないもの
ステップ5: 既存ルールとの重複チェック
- CLAUDE.mdを読み込む
- 既存の Lessons Learned / Review Learnings セクションを確認
- 意味的に重複する指摘は除外
- 既存ルールを補強・具体化する指摘は更新案として提示
ステップ6: ルール案の生成
以下のフォーマットでルール案を生成:
### {カテゴリ名}
- {具体的なルール}。{理由や背景}
- 📝 PR #{PR番号} で @{レビュアー} さんが指摘
記述の品質基準:
- 肯定形で記述(「〜しないこと」より「〜を使うこと」)
- 具体的なコード例やパターンを含める
- なぜそうすべきかの理由を添える
- 元の指摘者をクレジット
良い例:
### 命名規則
- Repository層のメソッドは `fetchXxx` ではなく `getXxx` を使う。fetchは非同期を暗示するが、Repositoryは同期/非同期を抽象化するため
- 📝 PR #123 で @tanaka さんが指摘
### エラーハンドリング
- API呼び出しでは `Result<T, E>` でラップし、呼び出し元で処理する。例外を投げると呼び出し側でtry-catchが必要になり、漏れやすい
- 📝 PR #120 で @suzuki さんが指摘
ステップ7: ユーザー確認と追記
蓄積候補を対応確度別にグループ化して表示する:
## 蓄積候補(対応済み指摘から抽出)
### 確実に対応した指摘(resolved / APPROVED body)
1. {指摘の要約} → {対応内容}
- 📝 PR #{PR番号} で @{レビュアー} さんが指摘
→ ルール案: 「{具体的なルール文}」
### おそらく対応した指摘(outdated + コミットあり)
2. ...(該当があれば表示)
---
除外した指摘: Bot未対応 {N}件 / 人間未対応 {N}件
(詳細を見たい場合は「除外した指摘を見せて」と伝えてください)
- 上記の形式で蓄積候補を提示
- ユーザーに追記するか確認(個別に選択可能)
- 承認されたらCLAUDE.mdに追記
- 「除外した指摘を見せて」と言われた場合は除外理由付きで一覧表示
追記先セクション:
## Review Learnings セクションがあればそこに追記
- なければ
## Lessons Learned の後に作成
- どちらもなければCLAUDE.md末尾に新規作成
ステップ8: CLAUDE.mdへの書き込み
## Review Learnings
このセクションはPRレビューで受けた指摘から自動生成されました。
`/review-learn` コマンドで更新できます。
### 命名規則
- Repository層のメソッドは `fetchXxx` ではなく `getXxx` を使う
- 📝 PR #123 で @tanaka さんが指摘
### エラーハンドリング
- API呼び出しでは `Result<T, E>` でラップする
- 📝 PR #120 で @suzuki さんが指摘
エラーハンドリング
エラー1: GitHubリポジトリではない
- gitルートを確認し、GitHub remoteがあるかチェック
- ない場合はエラーメッセージを表示
エラー2: gh CLIが未認証
GitHub CLIが認証されていません。
以下のコマンドで認証してください:
$ gh auth login
エラー3: PRにレビューコメントがない
- 「このPRにはレビューコメントがありませんでした」と表示
- 別のPRを選択するよう促す
エラー4: 自分のPRがない
- 「マージ済みのPRが見つかりませんでした」と表示
- PR番号を直接指定するよう促す
複数人リポジトリでの価値
| シナリオ | 効果 |
|---|
| 新メンバー参加 | 過去のレビュー指摘が蓄積済み。同じミスをしない |
| レビュアー | 同じ指摘を繰り返す手間が減る |
| チーム全体 | 暗黙知が形式知化され、コード品質が均一に |
| オンボーディング | 「なぜこのルール?」の背景(PR番号)が追跡可能 |
重要事項
- CLAUDE.mdはプロジェクト全体で共有されるファイル。慎重に編集すること
- 既存の内容は変更しない(追記のみ)
- レビュアーへのクレジットを必ず残す(敬意+追跡可能性)
- 追記・変更は必ずユーザーの承認を得てから実行する
- プラットフォーム非依存: あらゆるGitHubリポジトリで使用可能
バージョン
v1.1 - 対応済みフィルタリング (2026-02-16)
- Bot vs 人間のコメント自動分類
- GraphQL API で isResolved / isOutdated を取得
- 「対応した指摘のみ蓄積」フィルタ導入
- APPROVED レビュー body の解析対応
- 確度別グループ表示
v1.0 - 初回リリース (2026-02-07)
- PRレビューコメントからルールを抽出
- カテゴリ自動分類
- 重複チェック
- レビュアークレジット付きでCLAUDE.mdに追記
- lessons-md-managerとの補完設計