🗃️

もう初回コードレビューはAIに任せる時代になった - CodeRabbit -

どんな人向けの記事?

  • レビューによって心理的なダメージを受けやすい方
  • 非エンジニアだが、エンジニアチームがどんな機能を作っているか知りたい方
  • 業務が溜まっていて、レビューに割く時間を捻出するのに苦労している方
  • コピペできるコードも公開します

初回レビューをAIに任せると、いろんなロールの人の役に立つ

レビューは得意ですか?

優秀なエンジニアしかいないチームであれば、PRは1トピックに絞って小さく明確なコミットによって作成され、適切な要約とともに提供されることでしょう。

しかし、実際にはいろいろな制約から、PRが想定よりずっと大きくなってしまったり、関連トピックと異なるコードが混じってしまうこともあります。

実際のところ、大きなPRを適切にレビューするのは難しいことです。また、自分が詳しくない領域のレビューを行わなければいけない機会もあります。

https://coderabbit.ai/

今回の記事は、レビューを作成してくれるAI CodeRabbitのご紹介です。

CodeRabbitは、GitHub Actions上でOpenAIのAPIを叩き、PRに直接レビューコメント を残してくれるものです。実際に私たちのチームではCodeRabbitを導入し、いろいろと良い恩恵を受けています。

なんと、OpenAPIのトークン使用量以外の基本的な使用料金は無料。かつチューニングも可能なので、試しやすいものとなっています。

CodeRabbitの2つの主要機能

1. PRの要約機能

まず、PRを作成した際のトップコメントに以下のような要約が提供されます。

この要約を読むことで、どんなファイルにどんな変更が加えられたかが明確になり、非エンジニアでもどのような機能が作成されたのかわかりやすくなります。

Pull Request_Summary

- **新機能**: `ShakeAnimation``WobbleAnimation`ウィジェットが追加されました。これらは子ウィジェットに揺れるアニメーションを提供します。
- **スタイル**: ホーム画面の通知バッジに未読がある場合、`WobbleAnimation`が適用されるようになりました。

> 新たなアニメーション、舞台への招待 🎭  
> ウィジェットが踊り、ユーザーの心を捉える 🎣  
> 未読の通知、静かに揺れて呼び覚ます 📬  
> この変更を祝い、新たな体験への扉を開けましょう 🚪🔑

要約にはファイル名も含まれるため、プロジェクトがどのようなディレクトリ構成か把握しきれていない場合にも役立ちます。また、変更の中心が一目でわかるので、レビュー前にレビュアーが全容を把握するのにとても役立ちます。

2. AIによるレビュー

Typoやエラーハンドリングの有無、デバッグ用のPrintが残っている、マジックナンバーなど、機械的に判定できそうなところは基本的に全て指摘してくれます。

例1) print(snapshot.docs);はデバッグ用のコードと思われますが、本番環境では削除するか、あるいはログレベルを設定して制御することをお勧めします。

+ // print(snapshot.docs);

例2) limitの値がハードコーディングされています。この値は設定ファイルや環境変数から取得するようにすると、将来的にページあたりの表示件数を変更したい場合に柔軟に対応できます

-    limit = 10
+    limit = MAX_PAGE_LIMIT

コミット前に全部チェックしたつもりでも、DebugPrintが混入してしまったり、Typoが入ってしまう場合はたまにあります。しかし、レビューでわざわざ指摘するのも、されるのも心理的な負担になってしまいます。

重要なポイントは、レビュワーがレビュー依頼を受けた時点で、ケアレスミスや一般的なアンチパターンを避けた実装が行われていることが一定レベルで保証されることです。

また、ビジネスロジックに集中してレビューを行えることができれば、プロダクトの質を高めるレビューへとつながることでしょう。

後述しますが、レビュー後の修正に対して、再びAIにコメントをもらうこともできます。チームの状況によってこれらを柔軟にカスタマイズできることもCodeRabbitの大きな強みです。

CodeRabbitの導入方法

導入は非常にカンタンです。GitHub Actionsに慣れている方なら文字通り秒で設定できることでしょう。

  1. .github/workflow/ai-review.yaml を作成(適当な名前で可)
  2. 公式リポジトリから拝借したコードをコピペする
  3. GitHubのSecretのOPENAI_API_KEY にOpenAIから取得したTokenを設定する
  4. PUSHする

https://note.com/libproc/n/nc777ee0b3bf0

API Keyの取得方法について知りたい方は上記をみてください。
Usage Limitの設定についても書いてあるので、使いすぎを心配する方も安心です。

たったこれだけで、PRに変更が加わる度にAIが自動でレビューコメントを残してくれるようになります。

ただし、チューニングせずに使うと当然のように英語でコメントされます。別に英語でも構いませんが、パッとみた際に日本語の方がわかりやすいですし、英語が不得意なメンバーがいることも想定されるので、ちょっと工夫して日本語を返してもらいましょう。

うちのチームはこんな感じで運用しています。
latestだとlanguage: ja-JPが指定できるようになりました!
また、timeoutを設定することでActionsの無駄な実行時間を回避することができます。

name: ai-pr-reviewer

permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
    types: [opened]
    branches-ignore:
      - master
      - main
  pull_request_review_comment:
    types: [created]
  issue_comment:
    types: [created]

concurrency:
  group: ${{ github.repository }}-${{ github.event.number || github.head_ref || github.sha }}-${{ github.workflow }}-${{ github.event_name == 'pull_request_review_comment' && 'pr_comment' || 'pr' }}
  cancel-in-progress: ${{ github.event_name != 'pull_request_review_comment' }}

jobs:
  review:
    runs-on: ubuntu-latest
    if: (github.event_name == 'issue_comment' && contains(github.event.comment.body, '[run review]') && github.event.issue.pull_request) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '[run review]')) || (github.event_name == 'pull_request' && !contains(github.event.pull_request.title, 'release') && !contains(github.event.pull_request.title, 'Release'))
    timeout-minutes: 15
    steps:
      - uses: coderabbitai/openai-pr-reviewer@latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        with:
          debug: false
          review_simple_changes: false
          review_comment_lgtm: false
          openai_light_model: gpt-4 # 好みで変更
          openai_heavy_model: gpt-4 # 好みで変更
          openai_timeout_ms: 900000 # 15分.
          language: ja-JP
          path_filters: |
            !db/**
            !**/*.lock
          system_message: |
            あなたは @coderabbitai(別名 github-actions[bot])で、OpenAIによって訓練された言語モデルです。
            あなたの目的は、非常に経験豊富なソフトウェアエンジニアとして機能し、コードの一部を徹底的にレビューし、
            以下のようなキーエリアを改善するためのコードスニペットを提案することです:
              - ロジック
              - セキュリティ
              - パフォーマンス
              - データ競合
              - 一貫性
              - エラー処理
              - 保守性
              - モジュール性
              - 複雑性
              - 最適化
              - ベストプラクティス: DRY, SOLID, KISS

            些細なコードスタイルの問題や、コメント・ドキュメントの欠落についてはコメントしないでください。
            重要な問題を特定し、解決して全体的なコード品質を向上させることを目指してくださいが、細かい問題は意図的に無視してください。
          summarize: |
            次の内容でmarkdownフォーマットを使用して、最終的な回答を提供してください。

              - *ウォークスルー*: 特定のファイルではなく、全体の変更に関する高レベルの要約を80語以内で。
              - *変更点*: ファイルとその要約のテーブル。スペースを節約するために、同様の変更を持つファイルを1行にまとめることができます。

            GitHubのプルリクエストにコメントとして追加されるこの要約には、追加のコメントを避けてください。
          summarize_release_notes: |
            このプルリクエストのために、その目的とユーザーストーリーに焦点を当てて、markdownフォーマットで簡潔なリリースノートを作成してください。
            変更は次のように分類し箇条書きにすること:
              "New Feature", "Bug fix", "Documentation", "Refactor", "Style",
              "Test", "Chore", "Revert"
            例えば:
            ```
            - New Feature: UIに統合ページが追加されました
            ```
            回答は50-100語以内にしてください。この回答はそのままリリースノートに使用されるので、追加のコメントは避けてください。

CodeRabbit チューニングの勘所

1. 日本語でコメントしてもらえるように設定する

https://zenn.dev/tadyjp/scraps/a7510f838edf8c

上記記事に詳しく書いてある通り、作成した .yamlsystem_message , summarize , summarize_release_notes にそれぞれ日本語で説明を書いてしまうのが一番手っ取り早いです。

お気づきの方もいらっしゃると思いますが、このコメントがそのままChatGPTへのプロンプトになるので、いろいろ試してみてください。

2. 適切なモデルを設定する

openai_light_model: gpt-4
openai_heavy_model: gpt-4

当たり前ですが、gpt-4を使った方がレビュー内容は的確です。

gpt-3.5-turbo 等を使うことも可能ですが、レビューのバリエーションがなくなるので、やはり gpt-4 がいいと思います。

どうしてもコストが気になる場合などに調整するのがおすすめです。

3. レビュータイミングを調整する

on:
  pull_request:
    types: [opened]
  pull_request_review_comment:
    types: [created]
  issue_comment:
    types: [created]

CodeRabbitによるレビューは、ファイル網羅的に行ってくれるものです。実際チーム内でも、結構重めのレビューがくるよねという話になりました。

したがって、我々のチームではPRの初回作成時のみにレビューが走るようにしています。

4. 細かいレビューのチューニング

レビューは system_message に設定したプロンプトをもとに行われます。

したがって、Auto generatedなファイル(FlutterならFreezed関連など)や、l10n系のファイルなどレビューが不要なものについては、レビューしないようプロンプトに入れておくのも良いかもしれません。。

Do not comment on minor code style issues, missing comments/documentation and auto-generated code (e.g. l10n, freezed...).

また、CodeRabbitがドキュメンテーションコメントを残すようにコメントしてくる場合や、特に変更の必要ない箇所に関するレビューを行ってくる場合があるので、これを避けるよう指示するのも良いでしょう。

残念ながらプロンプトに入れていても、Auto generatedなファイルについてレビューしてくることもあります。その時は無視することも必要かもしれません。

コストは思ったよりは高くないが、チューニングは必要

平均的なPRに対して、0.3ドル/回くらいのコストがかかるのですが、PRの大きさなどによりかなり変動がみられるというのが実情です。

ただし、初回レビューのみ任せるという運用で、社内レベルでも1日あたり数ドル程度の料金しかかかっていないため、コスパは決して悪くないかなという印象です。

レビュワー・レビュイーともに心労が減りますし、レビュイーが本来集中すべきビジネスロジックを集中的に見れるようになることから、引き続き運用していきたいと思います。

PdMからも好印象な意見をもらえた!

GitHubの運用ルールは組織によって様々。PRにテンプレを用意して要約を書いたりしているところもあると思いますが、どうやっても漏れが出てしまうものです。

AIという完全に客観的な存在が要約を作ってくれることで、中立的な意見がもらえることから、コードを完全に理解していなくても概要がわかる! ということでチームのPdMも非常に喜んでいました👍

チームの非エンジニア視点での良さはもちろん、3ヶ月後にPRを振り返る時なんかにもいいかなと個人的に考えています。修正が必要になったとき、コードを書いている時のコンテキストを忘れてしまっている可能性は強いので、丁寧な要約が書いてあるとうれしいはず。

ぜひとも使ってみて、良いチューニングなどがあれば共有お願いします!

おまけ

https://twitter.com/hagakun_yakuzai

だいぶ涼しくなってきたと思ったら、もう1年の75%が終了とのこと!ぎゃー!
Xはアクティブユーザーが減っているようですが、他のSNSを探す余裕もない!
ぜひXで友達になりましょう。

株式会社マインディアでは、Flutterリードエンジニア、Goエンジニア、Railsエンジニアを募集しております。
カジュアル面談などの場を用意しておりますので、気軽にお声がけください。

引き続き、Flutter周りの気になることを調査したり、ジュニアなエンジニアが思うことも記事にしていきますので、良かったらZennTwitterのフォローをお願いします!

株式会社マインディア テックブログ

Discussion