LLMでコードレビューする際の自分用環境を整える
LLMでコードレビューといえばCodeRabbitのようなサービスがすでに存在していたり、
自前でコードレビュー用のGitHub Actionsを作成している事例なども散見されるようになった。
さらに最近はGitHub Copilotのbotがレビュアーとして参加してくれる機能もリリースされておりLLMによるコードレビュー環境は検証〜実践段階手前くらいまで進んでいるように感じる。
一方でこれらのLLMのコードレビューに対してはコードレビューの観点が求めるレベルに達していないという感覚もある。PR単位でのレビューなので言語やフレームワーク一般の観点でのレビューかせいぜい単一プロダクトに閉じた観点しかないことが多い。静的解析よりはもちろん柔軟とはいえ、本来プロダクションレベルの人間のレビューでは業務知識や関連プロダクト全体を通じたシステムの観点からの良し悪しといったことを考慮してレビューをするはずでそのレベルのレビューはまだ出来ていないと思う。
こういったプロダクションレベルのレビューを出来る限り自分および他人のPRに対して行えるようにしたい。それができると事前に指摘されそうな部分を十分に先回りして修正することができてレビュアーへのレビュー負荷を下げられるはず。人間のレビュアーに出す前のレビューLinterを通しておくような感覚。
そのレベルができるような自分用のコードレビュー環境を作成してみた。
作ったもの
やったこと
コードレビューガイドラインの作成
自分の求めるレベルのコードレビューをするために必要なことはまずコードレビューガイドラインをもっと充実させること。
巷の記事やブログに書いてある観点をみてるとちょっと足りなくて、LLMの知識頼りになっている感がある。個人的にはもっとここをカスタマイズしたい。
自前で全部書いても良いがまぁまぁ大変すぎるし抜け漏れも発生しそうなので先人の力を借りることにした。
Code Completeやプリンシプル オブ プログラミングの要約記事やスライドを片っ端から人間DeepResearchを行いNotebookLMに突っ込んだ。他にはGoogle Engineering Practices DocumentationというGoogle様がお作りになったCode Reviewに関するドキュメントだったり、Thoughtbotが作ったCode ReviewガイドもNotebookLMに突っ込んだ。自分は普段はRailsアプリケーションのコードを扱うことが多いのでコードレビューで学ぶRubyOnRailsのエッセンスも抽出してまとめた。加えて自前の経験則などを基にリストアップした箇条書きなどをゴニョゴニョしてMarkdownにしてまとめた。
あとはこいつらの膨大なコードレビュー観点を基にして「一般的なコードレビュー観点」と「Railsアプリ特有のコードレビュー観点」のファイルを作成。これで個人的に欲しいような観点がまとまったコードレビューガイドラインができた。
レビュアー人格の作成
コードレビューガイドラインを作成し、実際に手元にPRの内容を引っ張ってきてClineにコードレビューをさせたところいい感じのレビューはしてくれるがイマイチ頼りない感じだった。具体的には対象のファイルの良いところについて「ここの設計はいいね👌」みたいなコメントを必ずいくつか生成したり「他にも問題はありそうだが、一般的にはLGTMで良いと思います」みたいな謎のぬるいレビュアーになってしまっていた。
自分が求めるのはむしろ重箱の隅を突いてくるような口うるさいくらいのレビュアーだ。対人間だとちょっと面倒だけど、どうせAIに言われるなら感情的に何も感じないはず。それでコード品質が上がるならうざいぐらいレビューしてくれた方が良い。
ということでレビュアーの人格作成用のドキュメントも作成した。こだわりポイントとしては疑い深く意地悪なくらいに隅々まで見るようにすることを行動原則にしたり、良い点や適切であるコードに対してはレビューコメントを残させず、逆に修正すべき点や気になる点がある箇所には必ずレビューコメントを残させるようにしている点。これで質問や指摘事項をズバズバいうようになった。
レビューの実行
レビューはGitHub Actionsで行うべきか?とか実際にPRにコメントまでさせるか?といった選択肢はいろいろあるが、今回は手元のCursorやClineで実行させる方法を選んだ。
手元で実行する場合はガイドラインやプロンプトを柔軟に修正しながら実行させたりできて便利だし、利用用途としてはLinterのような感じで自分の実装PRの事前チェックだったり、他人の作ったPRへのレビュー負荷と漏れを減らせれば良いか〜といった割り切りをしたので。
あとはここまで作成したドキュメントを基に実際にPRをレビューさせるだけ。PRの取得に関してはGitHub APIを使えば良い。最初はRubyでスクリプトを書いていたが、ワンラインナーでも書けるか?と思い下記のようにした(今書いてて思ったけど流石に無理あるのでrubyとかのスクリプトにした方が良かったかも...)。
- [追記] PR内容の取得方法にghコマンドを使いrubyスクリプトを実行させる方法に変更
まずPRの内容と変更ファイルのコードをいい感じにmarkdownとしてtmpファイルに吐き出して保存する。
# 例: ruby init_pr_content.rb https://github.com/owner/repo/pull/123
ruby init_pr_content.rb <PR URL>
最初は標準出力にmarkdownを吐き出してその内容をLLMに読んでもらう実装にしていたが、それだと変更ファイルの量が多い場合に標準出力のバッファを超えたりするし微妙だったので.gitignoreされてるローカルのtmpファイルに吐き出すことにした。
LLMにPRを食わせる前に自分の手元でPRの内容を確認しやすかったりするのでこれはこれで良い。
あとは下記のプロンプトをClineなりCursorに渡してレビューを実行させるだけ。
# 要求
- あなたはこれからコードレビューを行う必要があります。
- `general_code_review_guide.md`と`rails_specific_code_review_guide.md`にコードレビューガイドラインがあります。このドキュメントを基にしてコードレビューを行ってください。
# 対象のリポジトリ
- `/Users/example/dev/hoge_repo`
# PRの内容
- `pr_content.md`に対象のPRの内容が記載されています。
# コードレビュー時に絶対に守るべき事
- コードレビューを行う際には`general_code_review_guide.md`と`rails_specific_code_review_guide.md`に記載されているコードレビューガイドラインに常に従ってください。
- コードレビューを行う際には`reviewer_personality.md`に記載されている人格に徹底的になりきって振る舞わなければなりません。
- 良い点や適切であるコードに対してはレビューコメントを残してはいけません。
- 修正すべき点や気になる点がある箇所をなんとしてでも見つけ出して必ずレビューコメントを残さなければなりません。
- コードレビューは対象のリポジトリ全体を考慮して行わないといけません。
# レビュー結果の出力
- PRのレビュー結果はmarkdown形式でまとめて`review_results/`に`<repository_name>_<PRのID>.md`をファイル名にして出力してください。
プロンプトの詳細については正直好きに改変してもらっても良いんだけど、重要なのは対象のリポジトリにローカルのリポジトリを指定している部分。対象リポジトリ
の部分に関連するプロダクトのリポジトリの場所を複数指定して、「レビューの中で他の連携プロダクトがある場合は適宜外部のワークスペースの対象リポジトリを参照しなさい」といったプロンプトを追加するだけでいい感じに見に行ってくれるようにできる。これで冒頭で課題感として挙げていた本来プロダクションレベルの人間のレビューでは業務知識や関連プロダクト全体を通じたシステムの観点からの良し悪しといったことを考慮してレビューをするはずでそのレベルのレビューはまだ出来ていない
という部分についてもある程度考慮したレビューをしてくれるようになる。
まとめ
自分用のコードレビュー環境を整えた。
今回作ったコードレビューガイドラインは例えばチームに合わせて改変するのも良いし、リポジトリごとに.review/
ディレクトリみたいなやつを作ってそこで管理するとかでも良いと思う。そんでレビュー前LLMレビューのプロンプトをチームで共有して一通り通してもらった後にPRのレビュアーアサインを行うみたいな運用もできそう。
そこまでやるならGitHub ActionsなりでCIに組み込んでbotにコメントさせるのもありだけど、今回作ったレビュアー人格はかなり細かいことまでうるさく聞いてくるのでPR上でコメント残されると邪魔になるかも。その辺は調整が必要そう。
でもとりあえず今回作ったものはコードレビュー環境の叩き台程度には使えそう。
Discussion