atama plus techblog
🔀

コードレビューのボトルネックを"する側"と"される側"の両面から解消する

に公開

こんにちは、yubonです。

AIによるコードレビュー自動化の話はもうあちこちで書かれていて、自分も読んでいて「また同じやつか」と感じることが増えてきました。その上で、自チームならではの工夫もそれなりに溜まったので、整理がてら記録します。

はじめに

最近、こんな状況に心当たりはないでしょうか。

AIエージェントがどんどんPRを作ってくれる。けれど、人間のレビューがそのスピードに追いつかない。レビュー待ちのPRが目に見えて溜まっていく。

私が所属するチームでも、まさにこの状態に直面していました。この記事ではここ約2ヶ月で取り組んだ、コードレビューのボトルネックを「する側」と「される側」の両面から解消する仕組みづくりを紹介します。

想定読者

  • AIコーディングエージェントをチームで導入したら、レビューが追いつかなくなってきた方
  • コードレビューの自動化に興味がある方
  • レビュアー側だけでなく、レビュイー側の体験も含めて改善したい方

チームの前提

具体的な仕組みの話に入る前に、自チームの状況を簡単に共有させてください。似た前提を持つチームには、特に当てはまる話だと思います。

  • 規模:開発メンバーは10名弱。スキル的にはミドル〜シニアが中心
  • フェーズ:プロジェクトの立ち上げ段階で、開発量がとにかく多い(2026年4月にプロダクトローンチ)
  • ドメイン:会社としてこれまで扱ってこなかったドメイン領域。業務知識のキャッチアップが必要
  • 技術スタック:会社の中でも新しめのスタックや、世の中的に良いとされている開発手法を取り入れていて、メンバーにとっての学習要素が多い
  • AIエージェント活用:Claude Code・Codex・Devin などを本格的に併用

要するに、ドメインも技術スタックも新しく、キャッチアップすべき知識量に対して開発スループットが求められるフェーズでした。AIエージェントでスループットを上げつつ、習熟が追いつくまでも品質を守れる仕組みにしたい。そんなニーズが強い状況でした。

先に結果から:何が変わったか

具体的な仕組みの話に入る前に、ざっくりとした効果を先に出しておきます。チームのメンバーが揃いきった2025年11月から2026年4月中旬までの、main へのマージリードタイムの月次推移です。
PRのマージ件数やリードタイムの中央値は開発フローの健全性を測る指標のひとつでしかありませんが、誰でも同じ条件で計測できて、変化が直感的に伝わるので、本記事ではこれをわかりやすい代理指標として掲示しています。

マージPR数 リードタイム中央値 この月の状況
2025-11 201件 14.2h(約0.6日) メンバーが揃う
2025-12 214件 12.7h(約0.5日) 通常運転
2026-01 126件 31.9h(約1.3日) 年末年始の影響で滞留が長め
2026-02 273件 21.7h(約0.9日) 試行錯誤期間。PRの件数が増えてつらみが増していく
2026-03 535件 4.3h(約0.18日) 月初にこの記事の施策を本格投入。第2週から中央値が急減して定着
2026-04(中旬まで) 367件 3.6h(約0.15日) 仕組みが定着。ローンチ後も順調に継続

メンバーが揃った2025年11月と、この記事で紹介する仕組み一式が出揃った2026年3月を比較すると、マージPR数は約2.7倍に増えながら、リードタイムの中央値は約1/3にまで短縮できました(後述のとおり、施策以外の要因も含む数字です)。冒頭で挙げた「PRがどんどん作られるのにレビューが追いつかない」が、件数を増やす方向と滞留を減らす方向の両方で改善できた状態と言えると思います。

いくつか留保があります。

  • スピードと引き換えに品質を犠牲にしているわけではありません。定性的ではありますが、チームのQAメンバーからは「社内の他プロジェクトと比べて、開発量・規模が大きいにも関わらず、検知される不具合は少ない」というフィードバックを得ています。4月のプロダクトローンチ後も今のところインシデントは発生していません。
  • 4月のプロダクトローンチを控えた駆け込み開発で、3月以降は全体的にPR量とマージスピードが上がっていた側面もあります。平常運転ではここまで極端な差にはならない可能性が高いです。とはいえ、4月(中旬まで)も中央値3.6h・週次では中央値2h前後で安定しており、仕組み自体の効果は継続して確認できています。

ここから先は、この結果に至るまでに何を考えて何を作ったかの話です。

取り組みの全体像

ボトルネックは「する側」だけの問題じゃなかった

「PRレビューが追いつかない」と聞くと、まずレビュアー側の問題に目が行きがちです。でも振り返ってみると、自チームではボトルネックの原因が両側にありました。

  • レビュアー側:レビュー待ちPRが増え、お見合い状態で誰も着手しない時間が長い
  • レビュイー側:レビュー依頼時点でのPR品質にばらつきがあり、指摘事項が多く手戻りが発生する

とくにレビュイー側は、AIコーディングエージェントの急速な導入と無関係ではありませんでした。プロジェクト固有のルールやコンテキストをAIにうまく伝えきれていなかったり、AIの出力を十分にセルフチェックせずそのままPRにしてしまったり。前提に書いた「キャッチアップが多くて品質担保が必要」なフェーズだったことも拍車をかけていました。品質が不十分なPRはレビュアー側の負荷を上げ、結果としてレビュー着手のハードルも上がる。両者は悪循環になっていたのです。

この両面を同時に解決するために、レビュアー側・レビュイー側・マージ後のフォローという3つの観点からレビューフローを再設計しました。

出発点はPRガイドラインの整備

ただし、最初から「AI自動化のための基準づくり」を狙っていたわけではありません。時系列で先に着手していたのはPRガイドラインの整備で、当初の動機は 人間どうしのレビューでPRの滞留を減らすこと でした。レビュイー側(PRの粒度・説明に書くべき情報・セルフレビュー)とレビュアー側(全体感を早く把握する・MustとNitsを区別する・完璧を求めすぎない)の両面で期待値を明文化したものです。

そのすり合わせの際に、先輩メンバーから「人間どうしのレビューでは限界があるので、AIによるレビューの仕組みもつくっていけるとよさそう」というコメントがあり、AIレビューの仕組み化に動き始めました。結果的にこの順序が効きました。AIは「チームが定めた基準」に沿ってレビューするので、基準が曖昧だと出力もぶれます。人間の認識合わせがあったうえでAIが乗っかったことで、後述するAIレビューのルールやセルフレビューの基準が安定して機能しています。ガイドライン自体は今も生きたドキュメントとして、AI自動化の導入後も継続的にアップデートしています。

3つの観点で再設計

PRガイドラインで人間の認識を揃えた上で、以下の3つの観点から仕組みを整備していきました。

  • レビュイー側(PR品質を上げる)
    • AGENTS.md やルール・スキル整備で、AIエージェントの出力品質を底上げ(Appendix)
    • AIセルフレビューで、依頼時点の品質をさらに引き上げ(セクション1)
  • レビュアー側(レビュー負荷を下げる)
    • AIコードレビュー+自動Approveで、人間が見るべきPRを絞る(セクション1)
    • 日次担当アサインで「お見合い」をなくす(セクション2)
  • フォロー(マージ後の安全網)
    • 定期巡回で不具合懸念を検出し、修正PRまで自動作成(セクション3)

AGENTS.md 自体の話は各所で語られていて目新しさが薄いので、本編はセクション1〜3、土台の話はAppendixに置いています。

1. AIコードレビュー 〜レビュアー側にもレビュイー側にも効く自動レビュー基盤〜

課題

チームではAIエージェントが作成するPRが増えてきたことに加え、人間が作成するPRも含めると、レビュー待ちの数が右肩上がりになっていました。すべてのPRに人間がレビューコメントをつける従来のフローでは明らかにスケールしません。

「影響範囲が小さく、品質面でも問題ないPR」であれば、人間のレビューを待たずにマージまで進められるはず。そう考えてAIによるコードレビューの自動化に取り組みました。

ベースとなるアプローチ

この仕組みは、以下の記事のアプローチをほぼそのままお手本にさせていただきました(超絶感謝)。

https://zenn.dev/pepabo/articles/ai-pr-review-bottleneck

要点だけ簡単に紹介すると、以下のステップをGitHub Actions上で実行する構成です。

  1. PRサイズの自動ラベリング:変更規模をAIが判定し、size/XSsize/XL のラベルを付与
  2. AIによるコードレビュー:Claude Code Action がレビューを行い、問題がなければそのままApproveまで実施
  3. 条件付き auto merge:「size/XS ラベルが付いている」「AIレビューでApprove済み」「CIが通っている」の3条件を満たすPRに限り auto merge を有効化

「人間レビューを必須にするPR」と「AIだけで通してよいPR」をサイズ × AI評価で切り分けることで、レビュアーの認知負荷を構造的に下げるのがポイントです。最もリスクの低い XS から始め、運用の信頼が積み上がってから対象を広げていく、という段階的な設計思想も印象的でした。

自チームでもこの構造をベースに、Claude Code Action(GitHub Actions上でClaude Codeを動かす仕組み)を使って同様のワークフローを構築しました。ただし、auto mergeまでは自動化せず、自動Approveまでにとどめている点が大きな違いです(理由は後述の工夫⑤で触れます)。

骨格となる「サイズ判定 → AIレビュー → 条件付き自動マージ/Approve」の流れは元記事のままなので、以下では自チームで追加した工夫だけを紹介します。少し長めなので、興味のあるところだけ拾ってもらってもOKです。

  • 工夫① ジョブを分割し、サイズ判定をHaikuに寄せてコスト最適化(軽量タスクは軽量モデルへ)
  • 工夫② HTMLコメントの隠しマーカーで、サマリーコメントを上書き運用(PR画面が縦長になる問題への対処)
  • 工夫③ 確信度スコアで偽陽性を抑制する(「とりあえず指摘」を減らす)
  • 工夫④ 初回/再レビューでスキル自体を切り替える(状況に応じて精度とコストを切り替え)
  • 工夫⑤ 結論を3段階に拡張し、auto Approve に留める(「Approveは覆さないが見直してほしい」を扱う)

工夫① ジョブを分割し、サイズ判定をHaikuに寄せてコスト最適化

元記事は単一ジョブ構成ですが、自チームでは size-label / ai-review / auto-approve の3ジョブに分割しています。ジョブごとにモデルや許可ツールを切り替えたい、というのが分割の理由です。

その上で、サイズラベル付与は「変更内容の影響範囲を判断する」という比較的単純なタスクなので、レビュー本体と同じモデルを使う必要はありません。そこで、サイズ判定のジョブだけ Haiku(claude-haiku-4-5)を明示指定しています。

# .github/workflows/auto-review.yml(抜粋)
- name: Run Claude Code for PR size labeling
  uses: anthropics/claude-code-action@v1
  with:
    claude_args: |
      --model claude-haiku-4-5-20251001
      --allowedTools Read,Grep,Glob,Bash,mcp__github__get_pull_request_diff,...

サイズ判定はPRの作成・更新(push)のたびに走るので、ここを軽量モデルに寄せるとコスト面の効果が安定して出ます。

ちなみにこの設定、当初は入れていませんでした。最初はレビュー本体と同じデフォルトモデルで動かしていたのですが、運用開始から数日で Claudeの利用量が普段の10〜20倍に膨れ上がる という事故が起きました。原因はサイズ判定が synchronize のたびに走り続けるところです。慌てて Haiku に切り替え、サンプルを手動で比較して「精度はほぼ落ちない」と確認した段階で急ぎ反映しました。「軽量タスクは軽量モデルに」という判断は事前にできたはずで、最初から分けておけばよかった工夫です。

なお、自チームでは「サイズの判定基準」自体もスキル化しています(.agent-skills/pr-size-label/SKILL.md)。リスク・波及範囲・既存の振る舞いへの影響の観点で評価し、初期値を XS から始めて根拠があるときだけ段階的に上げるルールです。リネームやフォーマットなど機械的に波及範囲だけ押し上がるケースは1段階下げる調整も入れています。ここで「実質リスクの低いPR」だけを XS / S に絞れていることが、後述の自動Approveの安全性を支えています。

PRサイズ判定コメントの例
実際にPRに投稿されるサイズ判定コメントの例

工夫② HTMLコメントの隠しマーカーで、サマリーコメントを上書き運用

これも当初は何も考えずコメント追記方式で動かしていたのですが、運用してみると PRの Conversation タブがレビューコメントで縦に伸びていく のが想像以上に厳しく、最新のレビュー結果まで頑張ってスクロールする必要が出てきました。ひどいときには、GitHub側が途中のコメントを「N hidden items Load more...」として省略表示してしまい、最新コメントを探すのにかなり手間がかかる、ということも起きていました。

そこで、サイズラベル付与もAIレビューも、毎回同じコメントを上書きする運用に切り替えました。

実装は素朴で、HTMLコメントの隠しマーカーを本文先頭に埋め込んでおき、次回実行時に gh api でそのマーカー付きコメントを検索 → 見つかれば PATCH、なければ POST するだけです。

# サマリーコメントの本文先頭にマーカーを入れておく
<!-- claude-review-summary -->
## PRレビュー: ...
(本文)

# 次回実行時に同マーカー付きコメントを検索して上書き
COMMENT_ID=$(gh api "repos/${OWNER_REPO}/issues/${PR_NUMBER}/comments?per_page=100" --paginate \
  | jq -rs 'add | map(select(.body | contains("<!-- claude-review-summary -->"))) | last | .id // ""')

if [[ -n "$COMMENT_ID" ]]; then
  gh api -X PATCH "repos/${OWNER_REPO}/issues/comments/${COMMENT_ID}" -f body="${BODY}"
else
  gh api -X POST  "repos/${OWNER_REPO}/issues/${PR_NUMBER}/comments"   -f body="${BODY}"
fi

サイズラベル側も同じパターンで <!-- pr-size-label --> のような別マーカーを使っています。地味ですが、synchronize で何度走ってもPRが汚れず、過去の判定との差分も追いやすくなります。

ちなみに、AIに本文を生成させる以上、マーカーを誤ってエスケープして出力してしまう事故が起こりえます(例: &lt;!-- ... --&gt;)。これを防ぐため、スキル側で「投稿前に本文先頭にマーカーが完全一致で入っているか」を検証してジョブを失敗させる仕組みも入れています。

工夫③ 確信度スコアで偽陽性を抑制する

AIレビューで一番怖いのは、指摘の量が多くなりすぎて誰も読まなくなることです。観点を広く見るほど確証の薄い指摘が混じり、信号が薄まっていきます。

これを抑えるために、各レビュアーエージェントには 自分の指摘に確信度スコア(0〜100)を内部で付け、閾値以上の問題だけを報告する ルールを入れています。閾値は観点ごとに微調整していて、各観点の「見落としコスト」と「偽陽性コスト」のバランスで決めています。

現時点の運用値の一例です。

観点 確信度の閾値
コード品質 80
セキュリティ 76
パフォーマンス 76
破壊的変更 70

破壊的変更だけ閾値を下げているのは、見落としたときの事後修正コストが極めて高く、偽陽性を多少許容してでも早期に注意喚起する価値が大きいためです。

副次的な効果として、AIに確信度を出させること自体が内省のプロセスとして働き、報告内容の論理的な一貫性も改善する手応えがあります。「とりあえず指摘してみる」が減り、本当に伝えるべき指摘だけが残るようになりました。なお、この工夫はチームの先輩が設計・実装してくださったものです。

工夫④ 初回/再レビューでスキル自体を切り替える

PR作成直後の初回レビューと、その後の push による再レビューは、求められるものが違います。初回は精度重視で網羅的に見たい。再レビューは差分が小さいことが多く、毎回全観点をフルでまわすとコストも嵩むし、確信度の低い指摘が増えて逆にうるさくなります。

これも工夫①と似た経緯で、当初は再レビューも初回と同じサブエージェント分業のスキルで動かしていました。synchronize のたびに複数エージェントが起動するため、push が続くPRではコストが嵩みます。さらに、再レビューでフル観点をかけると「初回で指摘済みの観点を確信度の低いまま蒸し返す」ノイズも出ていました。

そこで、初回と再レビューで使うスキル自体を分けました。

初回レビュー(過去のサマリーコメントなし)
  → .agent-skills/review-pr/SKILL.md を使う
  → 9つのサブエージェント分業(observability, security, performance, types, comments,
     tests, errors, breaking-change, simplify)
  → 変更ファイルの種類で起動エージェントを動的に判定
     (例: テストファイル変更時のみ pr-test-analyzer、
       DBマイグレーション・スキーマ定義・サービス間プロトコル変更時のみ breaking-change-reviewer)

再レビュー(過去のサマリーコメントあり)
  → .agent-skills/review-pr-recheck/SKILL.md を使う
  → シングルエージェント、観点を絞る
  → 「確信度80以上の問題のみ報告」ルールで偽陽性を抑制

切り替えはシンプルで、Claude が過去に投稿したサマリーコメント(前述のマーカー付き)が存在するかどうかで workflow が判定します。

- name: Select review prompt
  id: review_prompt
  run: |
    if [[ -n "${{ steps.existing_summary.outputs.comment_id }}" ]]; then
      echo "prompt_file=.github/prompts/claude-review-recheck.md" >> "$GITHUB_OUTPUT"
    else
      echo "prompt_file=.github/prompts/claude-review.md" >> "$GITHUB_OUTPUT"
    fi

「初回かどうか」のフラグを別管理しなくて済むので、何度 close & reopen されてもコメントが残っているかぎり再レビュー扱いになる、という整合的な挙動になります。

スキル化したことで得られたもの

ここで強調したいのが、この2つは workflow 上のプロンプトではなく、SKILL.md として切り出してあるという点です。ハーネスエンジニアリングの観点で見ると、人間とAIが同じ基準書を共有できる形にしておくのは、地味だけど効果が大きい工夫だと思います。

スキル化の目的は、人間がローカルで(自然言語や /review-pr などのスラッシュコマンドで)AIに呼び出させるときと、GitHub Actions が呼ぶときで、同じレビュー基準を使うことでした。

この3層構造のメリットは大きく3つあります。

  • 基準の二重メンテが不要:ローカルで良い指摘が出るように改善すれば、GitHub Actions のレビュー品質も同時に上がる(逆も然り)
  • 環境依存をブートストラップ層に閉じ込められる:「ローカルでは git diff、Actions では MCP の get_pull_request_diff」といった差分をスキル本体は意識せずに済む
  • 観点ごとに独立してチューニング可能:9つのサブエージェントは1ファイル100〜250行ずつに分けてある

workflow yaml にプロンプトを直書きするアプローチだと、ローカルから基準を呼びたいときに毎回 yaml と仕様書の二重メンテが発生します。スキルとして切り出すことで、人間とAIで同じ基準書を共有できます。

工夫⑤ 結論を3段階に拡張し、auto Approve に留める

元記事ではAIが Approve / 非Approve の二値で結論を出す設計になっています。自チームでは、これに加えて「Approveまではしないが軽微な修正で済む」ケースも明示的に扱いたかったので、🟢 マージ可能 / 🟡 軽微な修正後マージ可能 / 🔴 要修正 の3段階にしました。後述する「再レビュー依頼コメント」の判定にもこの3段階を使っています。

また、元記事ではApprove後に auto merge まで進める設計ですが、自チームでは段階的に範囲を広げたかったこともあり、いったん auto Approve までを自動化の範囲にしています。一方で自動Approveの対象は size/XS に加えて size/S まで含めており、自チームの運用に合わせてバランスを取っています。

ただ、ここで一つ問題がありました。GitHubのAPI仕様上、Approveの自動取り消しはできません。一度Approveが付いたPRに後続で push が走り、品質が下がった場合でも、Approveは残ります。

これに対する安全弁として、「以前にAIが自動Approveしたあとで、再レビューの結論が 🟡 🔴 に変わった場合」に限り、AIが「再レビューしてください」コメントを自動投稿する仕組みを入れています。3段階結論があるからこそ、「Approveを覆すほどではないが、人間に見直してほしい」という中間状態を扱えるようになっています。

この3段階結論はAIが出力し、workflow 側はサマリーコメントの「### 結論」セクション直後の2行だけを抽出して 🟢 マージ可能 を grep する、という素朴な方法で mergeable フラグに変換しています。サマリー全文を grep していないのは、本文の他箇所に偶発的に「🟢 マージ可能」と書かれてもフラグを誤って立てないためのインジェクション対策です。

AIレビューサマリーコメントの例
実際のAIレビューサマリーコメントの出力例

そして、🟢 マージ可能 かつサイズが XS / S のPRは、github-actions[bot] による自動Approveが付きます。

自動Approve済みPRのReviewersパネル
github-actions[bot] による自動Approveが付いたPRのReviewersパネル

運用してみての効果

レビュイー側(PR作成者)への効果: PR作成者が「人間にレビュー依頼を出す前に、自分でAIレビューをかけて 🟢 マージ可能 まで持っていく」運用が定着しました。AIレビューのスキルはローカルからも呼べるので、PR作成 → セルフレビュー → 指摘の修正、を回しきってから依頼を出せます。依頼時点のPR品質がだいぶ高まりました。AIエージェント(Devin等)がPRを作成する場合も同じスキルを使えるので、AIが作るPRの品質も連動して底上げされています。

レビュアー側への効果: セルフレビューが定着したことで、品質の高い状態でレビュー依頼が飛んでくるようになり、指摘→修正の往復回数が大きく減りました。さらに size/XSsize/S のPRはレビュイー自身でマージできるようになったため、AIエージェントの活用で作成PR数は増えているのに、人間が依頼されるPR数は変わらない(むしろ減っている)状態を作れています。

冒頭で触れた「レビュアー側とレビュイー側の悪循環」が、好循環に変わりました。一方で、AIレビューには当然抜け漏れがあります。それは前提として、後述する定期巡回(セクション3)でセーフティネットを張っています。

2. PRレビューの日次担当アサイン 〜レビュアー側の「お見合い」をなくす〜

課題

セクション1のAIコードレビューにより、小さいPRの自動Approveが実現しました。しかし、AIが自動Approveしなかった中〜大規模なPRは依然として人間がレビューする必要があります。

ここで発生していたのが、レビュアー側の「お見合い」問題です。「誰かがやるだろう」という状態が続き、レビュー待ちPRがどんどん溜まっていきます。

仕組み

毎朝のDailyリマインダー(Slackに自動投稿される「PRレビュー待ちはこちら」)をトリガーに、その日のレビュー担当者をスレッド内でアサインする運用にしています。

Slackに自動投稿される日次リマインダー
素敵なお花のDailyリマインダー

「今日のレビューはこの人」が決まっていると、「誰かがやるだろう」が消えてPRが滞留しにくくなります。Dailyというすでにある習慣に乗せているだけなので、新しいツールもフローも増えず、運用コストもほぼかかっていません。

セクション1がAIで「量」を減らすアプローチだったのに対し、こちらは人間の運用で「滞留」を解消するアプローチです。AIで開発を自動化しても、「誰がいつ何を見るか」という人間どうしの調整ごとはまだ残ります。こういう泥臭い部分にも仕組みを入れておくのが、今のAIエージェントの成熟度では効いてきます。

3. 不具合懸念調査の定期巡回 〜マージ後のフォロー〜

課題

セクション1のAIコードレビューは「PRマージ前」の品質チェックですが、当然100%の精度は期待できません。AIエージェントによるPR作成と自動Approveの運用が広がるほど、「マージ後に問題が発覚した」というリスクも高まります。

そこで、マージ後の品質パトロールとして、Devinによる不具合懸念調査の定期巡回を整備しました。

仕組み

DevinのPlaybook(=繰り返し行うタスクのための再利用可能なワークフロー定義)を使って、以下の定期実行を設定しています。

月・水・金 朝8:00(スケジュール起動)
  → 直近3日間で main にマージされたPRの変更コードを巡回
    → 検出結果を Slack に報告
    → 不具合懸念があれば修正PRを自動作成

不具合調査ワークフローの起動通知
ガチャピンみたいなキャラがDevinを起動してくれる

巡回時にチェックしている観点は以下のとおりです。

  • ロジックミス(条件分岐の漏れ、off-by-oneエラーなど)
  • null / undefined 参照の可能性
  • 型の不整合
  • セキュリティ上の懸念
  • パフォーマンス問題

検出した問題は、深刻度で2段階に分類してSlackに報告されます。

カテゴリ 説明 アクション
A(明らかな不具合) 再現手順が明確で、ユーザー影響が確実なもの 修正PRを自動作成
B(不具合の疑い) 可能性は高いが、確認が必要なもの Slackに報告して人間の判断を仰ぐ

Devinによる不具合調査レポート
Devinから返ってくる不具合調査レポート

Playbookの定義例(あくまで一例)

参考までに、自チームで使っているPlaybook定義の雰囲気を簡略化したものを載せておきます。DevinのPlaybookはMarkdownで記述する形式で、Procedure / Specifications / Advice / Forbidden Actions といったセクションに分けて手順や前提を書いていきます。なお、月・水・金や毎朝8:00といった定期起動は、Slackのワークフロー(スケジュールトリガー)からDevinを呼び出す形で実現しているため、Playbook本体にはスケジュール定義は書きません。

# Bug Fix - Merged PR Bug Investigation

対象リポジトリに対して、直近3日間でマージされたPRの変更内容を調査し、
不具合の可能性があるコードを検出・報告する。

## Procedure

1. **リポジトリの準備**
   - 対象リポジトリをクローンまたは最新の状態に更新する

2. **直近3日間でマージされたPRの取得**
   - GitHub APIまたはgitコマンドを使い、直近3日間にマージされたPRの一覧を取得する
   - 各PRの変更差分(diff)を取得する

3. **変更内容の調査**
   - 各PRの変更差分を精査し、以下の観点で不具合の可能性があるコードを調査する:
     - ロジックの誤り(条件分岐の間違い、off-by-oneエラーなど)
     - Null/undefined参照の可能性
     - 型の不整合
     - エラーハンドリングの欠如
     - リソースリークの可能性
     - 競合状態(race condition)の可能性
     - APIの誤用
     - セキュリティ上の問題
     - パフォーマンス上の問題
     - その他明らかなバグパターン

4. **報告**
   - 発見した不具合を以下の2つのカテゴリに分類して、Slackで報告する
   - **カテゴリA: 誰が見ても明らかに不具合なもの**
     - 各不具合について新たにSlackスレッドを立てて報告する
     - 修正PRを作成する
   - **カテゴリB: 不具合とは断定できかねるが可能性が高いもの**
     - 報告のみ行う(PRは作成不要)

## Specifications

- 報告には以下の情報を含めること:
  - 該当PR番号とリンク
  - 該当ファイルと行番号
  - 不具合の内容と根拠
  - カテゴリ(A or B)
  - (カテゴリAの場合)修正PRのリンク

## Advice

- 変更差分だけでなく、周辺のコードも読んで文脈を理解した上で判断すること
- 既存のテストコードがある場合は、テストが不具合をカバーしているかも確認すること
- 不具合の判断に迷った場合は、カテゴリBとして報告すること
- 大量のPRがある場合でも、すべてのPRを網羅的に調査すること

## Forbidden Actions

- 実装途中のコードやTODOコメントで管理されている未完成のコードを不具合として指摘しないこと
- 不確実な根拠で不具合と断定しないこと(確信がない場合はカテゴリBにすること)
- コーディングスタイルやリファクタリングの提案を不具合として報告しないこと

ポイントは Forbidden Actions で「未完成コードを指摘しない」「確信がない場合はカテゴリBに倒す」など、偽陽性を抑える方向の制約を明文化していることです。セクション1の確信度スコア(工夫③)と同じ思想で、ノイズを減らしてSlack側で読まれる情報密度を高めています。

導入の背景にある考え方

AIエージェントの活用が進むと、将来的にはauto mergeも視野に入ってきます。その際に「マージ後の品質チェックが仕組みとして存在しない」状態は怖い、という問題意識から設計しました。

現時点ではauto mergeはまだ導入していませんが、仮に導入したとしてもこの定期巡回が予防線として機能してくれる、という安心感があります。

Appendix: AIエージェント向けのルール・スキル管理

「レビュイー側」の最初に挙げた、AIエージェントへのルール・コンテキスト伝達の土台部分です。AGENTS.md の整備自体は目新しい話ではないので折りたたんでいますが、ここの作り込みで後続の仕組み(AIレビューやセルフレビュー)の効き方が大きく変わるため、興味のある方は開いてみてください。

リポジトリ構造と設計のポイント

自チームでは Claude Code・Codex・Devin など複数のAIエージェントを併用しているため、指示やルールが分散・乖離しやすいという課題がありました。これを解決するため、以下のリポジトリ構造でルール・スキルを一元管理しています。

リポジトリルート/
  ├── AGENTS.md              # 全エージェント共通の指示書(実体)
  ├── CLAUDE.md → AGENTS.md  # Claude Code 用シンボリックリンク
  │   # Codex / Devin は AGENTS.md を直接読む規約のためリンク不要

  ├── .agent-rules/          # 常時ロードされるルール群
  │   ├── code-style.md             # 命名規則・型・コメント規約
  │   ├── architecture-guidelines.md  # オニオンアーキテクチャ・CQRS
  │   ├── testing-guidelines.md     # TDD・AAAパターン・モック戦略
  │   └── ...
  │   # .claude/rules → ../.agent-rules (シンボリックリンク)
  │   # .codex/rules  → ../.agent-rules (シンボリックリンク)

  ├── .agent-skills/         # 必要時に呼び出すワークフロースキル集
  │   ├── review-pr/         #   ← セクション1の初回AIレビューで使用
  │   │   ├── SKILL.md
  │   │   └── agents/        #     9つの専門サブエージェント
  │   ├── review-pr-recheck/ #   ← セクション1の再レビューで使用
  │   │   └── SKILL.md
  │   ├── pr-size-label/     #   ← セクション1のサイズ判定で使用
  │   │   └── SKILL.md
  │   └── ...
  │   # .claude/skills → ../.agent-skills (シンボリックリンク)
  │   # .codex/skills  → ../.agent-skills (シンボリックリンク)

  └── docs/                  # 人間とAI共通の設計ドキュメント
      ├── architecture/
      ├── design-doc/
      ├── guidelines/
      ├── specs/
      └── ...

設計のポイント

AGENTS.md による一本化

AGENTS.mdOpenAI Codex などが標準で読むファイル名規約です。Claude Code は CLAUDE.md を読むので、CLAUDE.md → AGENTS.md のシンボリックリンクを置くだけで対応できます。指示の実体は AGENTS.md 1ファイルにまとめ、各エージェントの命名規約にはシンボリックリンクで合わせる方針です。新しいエージェントを追加するときも、対応するファイル名のシンボリックリンクを追加するだけで済みます。

ルールとスキルの分離

  • .agent-rules/(常時ロード):コードスタイルやアーキテクチャ方針など、どんなタスクでも前提として知っておいてほしいルール
  • .agent-skills/(必要時にロード):AIコードレビューやSpec作成など、特定のワークフローで使うスキル

この分離により、常時ロードされるコンテキストの量を抑えつつ、必要なときに必要なスキルだけを呼び出せるようになっています。セクション1で「スキルとして切り出す」ことの意義を強調しましたが、その前提となる土台がここです。

シンボリックリンクによるツール間共有

各AIエージェントのツール固有ディレクトリ(.claude/rules.codex/rules など)から .agent-rules/ .agent-skills/ へシンボリックリンクを貼ることで、ルール・スキルの実体を複製せずに共有しています。ルールを更新するときは .agent-rules/ 以下のファイルを編集するだけで全エージェントに反映されます。

おわりに

この記事では、コードレビューのボトルネックを「レビュアー側」と「レビュイー側」の両面から解消するために取り組んできた仕組みを紹介しました。

観点 課題 仕組み
レビュイー側 AI出力の品質ばらつきにより、手戻りが多い ルール・スキルの一元管理(Appendix)+AIセルフレビュー
レビュアー側 レビュー待ちが溜まり「お見合い」が発生 AIコードレビュー+自動Approve+日次担当アサイン
フォロー マージ後に不具合が発覚するリスク Devinによる定期巡回+修正PR自動作成

レビューのボトルネックというと、つい「レビュアー側の負荷を下げる」ことだけを考えがちです。でも実際には、レビュイー側のPR品質が上がればレビュアー側の負荷も連動して下がりますし、フォローの安全網があるからこそレビュアー側は安心してスピードを上げられます。3つは互いにつながっていて、どれか一つだけでは片手落ちになる。これがこの2ヶ月で得られた一番の学びでした。

まだ発展途上の取り組みも多く、たとえば以下のような課題も感じています。今後解消していければいいなと考えています。

  • レビュー精度の継続改善:人間がコメントした箇所=AIが見落とした観点として、スキルの改善にフィードバックしたい
  • モデルの使い分け:同じモデルで実装とレビューを行うと指摘が甘くなる傾向がある(例:Claude Code で実装したPRに対する Claude Code Action のレビュー)ので、レビュー時のモデルを選択的に切り替えたい
  • GitHub Actions の動作確認:デフォルトブランチにマージしないと動作確認できない仕組みと、確率論的に動くLLMとの相性がかなり悪い

この記事が、チームでのAIコーディングエージェント活用を検討されている方の参考になれば幸いです!

atama plus techblog
atama plus techblog

Discussion