Argano の鈴木です。本記事では Claude Code を用いて GitHub に作成された PR に対するコードレビューをする環境を構築し、実際にGitHub上でコードレビューをもらうまでを実践していきます。 社内では AI での PR レビューを取り入れているプロジェクトはありますが、個人ではいままで AI でのPRレビューに触れてこなかったので、今後取り入れていきたいと思い、それに向けて実施したことを記事にまとめました。

検証環境

  • Claude Code: 2.1.220
  • 使用モデル: claude-sonnet-5

環境構築

検証用に TypeScript + Express でのシンプルなタスク管理 REST API リポジトリを作成します。 以下のプロンプトを Claude Code のチャットに入力するとベースとなるサンプルコードが生成されます。

TypeScript + Express で、シンプルなタスク管理REST APIのリポジトリを新規作成してください。
このリポジトリは「Claude CodeによるPRレビューを検証する」ための実験用サンプルなので、
機能は最小限で構いません。実装が完了したらgit initしてmainブランチに初回コミットしてください。
## 要件
- 言語/フレームワーク: TypeScript, Express
- データストア: SQLite
- エンドポイント:
  - POST /tasks (タスク作成: title, description, dueDate)
  - GET /tasks (一覧取得)
  - GET /tasks/:id (単一取得)
  - PUT /tasks/:id (更新)
  - DELETE /tasks/:id (削除)
- 各エンドポイントには基本的な入力値検証、エラーハンドリング、簡単なユニットテストを含めてください
  (このベース実装は「お手本」の状態にしたいので、丁寧に書いてください)
- README.mdに簡単なセットアップ手順を書いてください
- この時点ではCLAUDE.mdやレビュー用の設定ファイルは作成しないでください

PRレビューを実行する環境の構築

Claude Code GitHub Actions 経由でレビューが実行される仕組みを構築します。

手順1 install-github-appコマンドを実行する

サンプルリポジトリのディレクトリに移動して claude コマンドで Claude Code のセッションを開始し、セッション内で以下のスラッシュコマンドを実行します。

/install-github-app

このコマンドが、GitHub App の導入からワークフローファイルの作成までを対話形式で進めてくれます。対話の中で、レビューをしたいリポジトリを選択します。今回はサンプルとして作成したタスク管理 API のリポジトリを選びます。

手順2 認証方法を選択する

認証方法の選択肢が表示されるので、契約している Claude サブスクリプションを使う方を選びます。 選択後、長期利用可能な OAuth トークンが発行され、リポジトリのシークレットとして自動的に登録されます。

手順3 ワークフローを選択する

インストールするワークフローの選択肢が表示されます。今回は両方とも選択します。

  • Claude Code タグでのメンションに反応するワークフロー
  • 新しい PR で自動的にレビューが実行されるワークフロー

前者は動作確認や再実行の際に手動でメンションして使うため、後者は自動レビューの本番として使うためです。

手順4 生成されたPRをマージする

ここまでの設定が終わると、ワークフローファイルを追加する PR が自動的に作成され、ブラウザで開かれます。 内容を確認し、問題なければマージします。 マージが完了すると、リポジトリにワークフローファイルが追加された状態になり、PR の作成や更新に応じてレビュー実行の準備が整います。

手順5 生成されたワークフローファイルを修正する

本記事の執筆中に、生成されたままの ワークフロー ファイルでは PR レビューが投稿されないというエラーに遭遇しました。 生成時点のワークフローは既製のレビュー用プラグイン(code-review@claude-code-plugins)を使っており、レビュー自体は完了するものの、投稿処理まで届かないという不具合がありました。 またコメント投稿系のツールが許可リストに含まれていなかったことも重なっていました。プロンプトを直書きに切り替え、投稿系ツールを明示的に許可することで解消しました。

・・・
- name: Run Claude Code Review
  id: claude-review
  uses: anthropics/claude-code-action@v1
  with:
    claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
    claude_args: |
      --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*)"
    prompt: |
      このPRの差分をレビューしてください。
      問題を見つけた場合は該当行にインラインコメントを付けてください。
      問題が見つからなかった場合も、レビューを実施したことが
      分かるように「重大な問題は見つかりませんでした」という
      趣旨のコメントを必ずPRに投稿してください。

Claude CodeからのPRレビューを受ける

タスクに「優先度(priority)」フィールドを追加する機能を実装します。その中で、わざと次の問題を仕込み、 Claude Code にレビューされるかを検証してみます。

  1. 入力値検証の欠如: req.body.priorityの値を検証せずにそのままDBへ保存する
// POST /tasks — タスク作成
router.post('/', (req: Request, res: Response, next: NextFunction) => {
  try {
    const body = createTaskSchema.parse(req.body);
    // priority は任意項目なので、指定されたときだけそのまま渡す
    const task = createTask(db, { ...body, priority: req.body.priority });
    res.status(201).json(task);
  } catch (err) {
    if (handleZodError(err, res)) return;
    next(err);
  }
});
  1. エラーハンドリングの握りつぶし: try/catchでcatchした例外を何もせず無視する
// GET /tasks/stats/priority — 優先度別のタスク件数を集計
router.get('/stats/priority', (_req: Request, res: Response) => {
  try {
    const tasks = getAllTasks(db);
    const summary = { low: 0, medium: 0, high: 0 };
    for (const task of tasks) {
      summary[task.priority]++;
    }
    res.json(summary);
  } catch (err) {
    // 集計処理は補助的な機能のため失敗しても本体機能に影響させない
  }
});
  1. 境界値/ロジックのズレ: 優先度でのソートや絞り込みで、オフバイワン等の軽微なロジックミス
// 指定した優先度以上のタスクを、優先度の高い順に返す
export function getTasksByMinPriority(db: Db, minPriority: TaskPriority): Task[] {
  const all = getAllTasks(db);
  const minWeight = PRIORITY_WEIGHT[minPriority];
  return all
    .filter((t) => PRIORITY_WEIGHT[t.priority] > minWeight)
    .sort((a, b) => PRIORITY_WEIGHT[b.priority] - PRIORITY_WEIGHT[a.priority]);
}
  1. テスト未追加: 新規に追加した関数やエンドポイントに対するユニットテストを書かない

PR を作成して、GitHub 上で PR レビューが実行されていることを確認します。

Claude Code が英語で投稿した PR レビューコメント

Claude Code から PR レビューを受けることに成功しました。 画像に表示されている箇所以外にもレビューをしてくれていますが、仕込んだ4つの問題のうち、実際にコメントされたのは「入力値検証の欠如」「エラーハンドリングの握りつぶし」「境界値のズレ」の3点のみで、「テスト未追加」についてのレビューは受けられませんでした。 また、英語でコメントが書かれているので、次に日本語で出力するようプロンプトを調整します。

プロンプトの調整

レビューコメントを日本語で表示することと、「テスト未追加」へのレビューをするために、以下2点を main ブランチに反映します。

  • .github/workflows/claude-code-review.ymlRun Claude Code Review > prompt に「リポジトリ直下に .github/REVIEW.md が存在する場合は、その内容の指示に従ってください。」と追記
  • .github/REVIEW.md を作成

REVIEW.md には以下の指示を記載しました。

# レビュー方針
- レビューコメントはすべて日本語で書いてください
- 新規に追加された関数やエンドポイントに対応するテストコードが存在しない場合は、その旨を指摘してください

ファイルの変更を origin の main ブランチに push した後、再度 PR レビューを動かします。

  1. 入力値検証の欠如: req.body.priorityの値を検証せずにそのままDBへ保存する REVIEW.md 適用後に Claude Code が日本語で投稿した PR レビューコメント1
  2. エラーハンドリングの握りつぶし: try/catchでcatchした例外を何もせず無視する REVIEW.md 適用後に Claude Code が日本語で投稿した PR レビューコメント3
  3. 境界値/ロジックのズレ: 優先度でのソートや絞り込みで、オフバイワン等の軽微なロジックミス REVIEW.md 適用後に Claude Code が日本語で投稿した PR レビューコメント2

Claude Code が REVIEW.md のプロンプトを読み取り、日本語でレビューコメントをするようになりました。 また、テストの不足についてもレビューをするようになりました。

導入してみての感想・まとめ

今回の REVIEW.md なしの状態でのレビューで拾えた問題のうち、入力値検証の欠如と境界値のズレには共通点があります。それは、コードの中に矛盾の手がかりがあるという点です。

  • 入力値検証の欠如: スキーマ定義(createTaskSchema)が存在するのに、それを経由しない書き方になっている、という定義と実装の不一致
  • 境界値のズレ: doc comment の「以上」という記述と、実装の > という条件が矛盾している、というコメントと実装の不一致

このように、コードの中の矛盾を検出するのは得意な領域だと感じました。人間のレビュアーでも見つけられますが、機械的に全箇所をチェックできる点は強みだと感じています。

人の目でのレビューの前に AI を使ったレビューを挟めれば人間のレビューコストがだいぶ減りますので、誤字脱字や修正漏れなど機械的に判断できそうなところから、ロジックに関わるところもレビューをまずは任せていきたいと思いました。

REVIEW.md なしでも、仕込んでいた不具合のうち3項目はレビューできており、期待通りの結果を出していました。残りの1件に対しても REVIEW.md を作成して読み込ませることで意図した PR レビューに近づけることができました。 REVIEW.md に日本語出力するよう記載することで日本語化できましたが、 ワークフローファイル内の prompt を日本語で書いてもPRコメントの内容が英語で表示されているところが気になりました。