👌

withAI開発でもレビューしやすいPRを作る

に公開

「もうコード書いてない(=AIが全部書いてくれた)」系の話をより頻繁に耳にするようになりました。その一方、コードレビューまでもAIだけに任せるという現場はまだ多くないのではないでしょうか。

AIが主開発者になったことでコードの生産スピードは上がる一方で、その生産スピードに対してレビューのスピードが追いつかない、あるいはレビュワーの負担が大きい、というのは昨今の開発現場の大きな課題の一つと言えるでしょう。

そこで、我々開発者は少しでもレビュワーのペインを軽減すべく、より意識的かつ丁寧にレビューしやすいPRを作ることが重要になってきているように感じています。

この記事ではレビューしやすいPRを作るためにAIとどのように作業しているか、どういう指示をしているか、について紹介します。

もしこの記事で挙げた以外にもこういうことしてるよ〜などオススメがあれば教えてください。

commitの粒度を極力小さくしてもらう

AIに渡すタスクがそれなりにデカいとき、AIの作る差分もまぁまぁデカくなりませんか?

コード2,3行の修正で済むような小規模なタスクであれば自分で書いた方が早いでしょうから、実際の現場では変更が複数行、複数ファイルにまたがるような中規模以上のタスクをAIに渡すことの方が多いと思います。

ただ、その際にデカい差分がいっぺんに生まれるのを自分はよく目にするんですよね。指示を出した自分でさえチェックに時間を要する場合、レビュワーはそれ以上に負担を強いられる可能性は高いかもしれません。

また、デカい差分には下記のようなデメリットがあります。

  • レビュワーが内容を理解するのに時間がかかる
  • レビュワーが見落としをしてしまう可能性が高くなる
  • 後にバグが発覚した際にデバッグが面倒(commitあたりの差分が少なければ、問題のあるcommitの特定後は原因のコードが比較的短時間で見つけられる)

PR(branch)の分割はcherry-pick等を駆使すれば後からでも容易に行えますが、commitを後から分割しようと思うと少し骨が折れます。

なので、初めからなるべく小さい単位でcommitしてもらうようAIに指示することが重要です。
これはタスクを依頼する際に伝えてもいいかもしれませんし、CLAUDE.mdなどのドキュメントに記載してもいいかもしれません。

自分はCLAUDE.mdにて下記のような指示を出しており、今のところ大きな差分を見る機会はグッと減りました。

CLAUDE.md
AIは作業プランを組む際には出来る限り作業を小さな単位に分割し、また、作業ごとにgit commitを行う。

commit messageの可読性を保ちつつなるべく多くの情報を残す

commit message内に情報が多いと、差分に対する不明点のヒントになったり、「あの時になぜこうしたっけ」と見返したときにも便利です。

CLAUDE.mdに下記を追記することで常に十分な量の説明を書いてくれるようになりました。

CLAUDE.md
AIは「なぜその変更が必要だったのか」「どんなことを行なったか」「仕様書や参考にしたページのURL」などの情報をcommit messageに日本語でConventionalCommitsフォーマットに沿って簡潔に記述する。

ちなみにgit-commitというスキルを使っても同様のことができます(ただしbody文に関して72文字以内を推奨するからかやや文量は少ない印象でした)。

サクッと試してみたい方は下記を実行でinstallできます。

npx skills add https://github.com/github/awesome-copilot --skill git-commit

何点か聞かれますが基本Enter押しっぱで問題ないです。


エージェントの選択画面に関して、ClaudeCodeユーザーであればspaceでClaudeCodeを選択の上、Enterを押しましょう。

打鍵テストのケースを列挙させる

作業してもらう際に仕様を上手く伝えられていれば、作業後すぐに打鍵テスト用のテストケースも生成してもらうことが可能です。

テストコードに加えて打鍵テスト項目もPRに記述しておくと下記のようなメリットがあります。

  • レビュワーに対して「この観点での確認は実環境でも行った」と示せる
  • デバッグなどで後からPRを見返した際にこの時点までこの動作はしていたという担保になる

これを実現するため下記のような記述をCLAUDE.mdに加えました。

CLAUDE.md
AIは生成したコードに関して手動テストすべき項目があれば、`<ignoreしている任意のディレクトリ>/<YYYYMMDDhhmmss>.md`を作成し、テストケースを列挙する。

自分の場合、globalの.gitignoreに設定している任意のディレクトリ内にテストケースを列挙したmdファイルを生成する方式をとっています。ファイルとして出力している理由はVSCodeのターミナル上で確認やコピペがしづらいからという点が大きいです。

生成されたテストケースは最終的にはPR descriptionにペーストしますが、その前の確認作業も欠かせません。
生成されたもの以外にも考慮すべき事項などあるかもしれませんし、はたまたすでにテストコード側で十分に担保できているものは打鍵項目から外してもいいかもしれません。それらを確認し、適宜追加や削除を行なってからペーストします。

また、開発領域に合わせたテスト設計技法などもAIに伝えておけばより精度の高いテストケースが作成できるのでご参考までに。

同値分割法
境界値分析
デシジョンテーブルテスト
状態遷移テスト
ペアワイズ法
クラシフィケーションツリー法
ステートメントテスト

https://www.veriserve.co.jp/helloqualityworld/media/20240109010/#section1

レビュー依頼を出す前にAIレビューとセルフレビューの実施

AIで生成したものを別のAIにレビューさせたりすることで、あらかじめ指摘が入りそうな箇所を潰しておくことも大事ですね。すでに多くの現場で採用されている座組かもしれませんが、例えばローカルでClaudeCodeで生成したものをCodexにレビューさせたり、PR上であればDevinを活用したりなど。

また、自分自身でも改めて差分を確認すると良さそうです。何かコードに関して新しく疑問点が湧いてもcommit messageを参照すれば疑問が解消するというのが理想形だと個人的には考えています。

スクリーンショットを撮る

とりわけUIの変更がある場合、スクリーンショットを撮ることも重要です。

変更前後のスクリーンショットがPR descriptionにあると、レビュワーはコードの差分を見る前にUIレベルで「何が変わったのか」を視覚的に把握できます。スタイリングの変更だったり、コードだけでは変化が想像しにくい修正に効果的です。

スクリーンショットの撮影にはbefore-and-afterというスキルが便利です。

npx skills add https://github.com/vercel-labs/before-and-after --skill before-and-after

自分はやっていませんが、CLAUDE.mdに作業後は修正箇所のスクリーンショットを撮ってくださいなど書いておけば作業が終わった後で修正箇所に関して自動的にスクリーンショットを撮るという流れを組むこともできるはずです。もちろんカスタムスラッシュコマンド形式でも利用可能です。

ただし、デフォのままだと逐一参照すべきURLを渡さねばならないため、もし常に参照するURLが決まっているのであれば自前のスキルに参照すべきBefore/AfterのURLを固定しておくのがオススメです。

例えば以下のような具合です。

.claude/skills/screenshot/SKILL.md
---
name: screenshot
description: コードの差分が適用される前と後とでUIにどういった変化が生じたかスクリーンショットで比較
---

before-and-afterスキルを用いて、現在のbranchの修正箇所を含むスクリーンショットを撮ってください。
以下にBefore/AfterのURLを示しますが、修正したページに合わせてパスやクエリパラメータは修正する必要があります。

Before: `https://xxx.xxx`を利用してください。
After: PR内のVercelBotが投稿したPreview環境URLを利用してください。Preview環境URLは下記のコマンドで取得できます。
`gh api repos/{owner}/{repo}/issues/$(gh pr list --author @me --limit 1 --json number -q '.[0].number')/comments -q '.[] | select(.user.login == "vercel[bot]") | .body'`

上記の例ではghコマンド箇所は「authorが自分」かつ「最新」のPRからVercelBotのコメントをとるようにしています。

もし「PR番号は指定したい」等あればコマンド箇所に $ARGUMENTS を使ってもいいかもしれません。

スキルを呼び出すときに渡されたすべての引数。$ARGUMENTS がコンテンツに存在しない場合、引数は ARGUMENTS: <value> として追加されます。

https://code.claude.com/docs/ja/skills#利用可能な文字列置換

Vercelを利用している場合の注意点

VercelのPreview環境はデフォルトではProtectionがかかってます。そのため、このまま実行するとPreview環境へのアクセス時に401が返ってきてしまい、AIが「撮れないんだが!」とアワアワします。

そこで、HTTPヘッダまたはクエリパラメータにx-vercel-protection-bypassx-vercel-set-bypass-cookieを追加してあげる必要があります。

https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation

.env.localにVERCEL_PROTECTION_BYPASSを追加の上、mdにも

Preview環境へアクセスするにはクエリパラメータに`x-vercel-protection-bypass=<.env.localのVERCEL_PROTECTION_BYPASSを参照>&x-vercel-set-bypass-cookie=samesitenone`を付与してください。

のように追記すれば上手く動作するはずです。

GitHubの小技機能を積極活用する

ここからはAIとはあまり関係ないですが……。

アラート記法の活用

表現の強弱に関して、GHだと見出しや太文字の活用がメインになりそうですが、アラート記法もPR descriptionをぱっと見たときに目立たせる方法として有効です。

今はGHのエディター上のスラッシュコマンドから簡単に展開できるため、目立たせるべき情報を書く際には積極的に使っていけると良さそうです。

Hide whitespace機能の活用

特にFE開発ではHTMLの大きな塊をラップする類の修正を加えることもしばしば。

+ <section>
    <div>
      <div>
        <p></p>
      </div>
      <div>
        <p></p>
      </div>
    </div>
+ </section>

実際にはただ2行加えただけですが、GHのfiles changedページだとデフォでは下記のように表示されてしまいます。


これは中身がほぼ空なのでまだ見やすいが数十行をwrapした際は認知負荷がかかる

そんな時は右上の設定アイコンからHide whitespaceをチェックしましょう。

すると差分は実際の変更と同様の見た目になります。

使いどきも限られるからかまだまだ広く知られている機能とは言えないため、「この機能を有効にして見てください」とレビュワーに伝えるだけでもだいぶ効率は変わるかと思います。

まとめ

以上、PRをボトルネックにしないための自分なりの工夫をまとめてみました。

近い将来コード理解に関してはAIだけ出来ていればいいという世界が来るかもしれませんが、今はまだコードへの責任主体が人間なので、PRレビューという文化が残っています。

そうである以上、また、チームで開発する以上は綺麗なPRとレビュワーへの気遣いを心がけていきたいですね。

chot Inc. tech blog

Discussion