

PRレビューの品質と速度の改善#
- 開発時にPRを作成して複数人でレビューしてマージするというのが一般的な開発の進め方になっています。
- ただ、PRレビューには時間も手間もかかるためPRを作成してもなかなかレビューが終わらなかったり、レビューする人によって指摘の品質がまちまちだったりします。
- そこでAIにPRレビューをさせることで、自動でPRレビューをさせてPRレビューの品質と速度の改善を行います。
- AIがレビューすることによりLintチェックやフォーマッターのように人間がレビューする時点のコード品質を一定以上になるようにして人間のレビュアーの負担を軽減しつつ品質の均一化も狙っています。
GitHub Actions#
GitHub ActionsとしてAIレビューのワークフローを組んで実装してみました。 また、今回はAIレビューだけでなくPRの修正量をチェックするワークフローを追加しています。 これはAIで入力できるデータ量には制限があるのと、要約などを行うのに量が多すぎるとレビューの精度が下がるためです。 人間がレビューする時にも大量の修正を含むPRレビューの効果は低いと言われているため、PRサイズの制限も導入しています。(Pull requestの理想的なサイズとその理由 ↗) このワークフローを使用する際には、OpenAI APIのAPIKeyを取得してGithubのSecretsにOPENAI_API_KEYの変数として設定してください。
今回作成したGithubActionsのコードが下記です。#
- .github/workflows/main.yml
name: On pull request
on:
pull_request:
types: [opened]
pull_request_review_comment:
types: [created]
issue_comment:
types: [created]
jobs:
limit-changes:
if: ${{ github.event_name == 'pull_request' }}
uses: ./.github/workflows/check-pr-changes-limit.yml
with:
limit: 400
extension: kt|java
code-review:
if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'issue_comment' }}
uses: ./.github/workflows/check-pr-ai-reviewer.yml
with:
openai_light_model: 'gpt-4'
openai_heavy_model: 'gpt-4'
language: 'ja-JP'
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}yml- github/workflows/check-pr-ai-reviewer.yml
name: Code Review
permissions:
contents: read
pull-requests: write
on:
workflow_call:
inputs:
debug:
description: Debug mode
required: false
type: boolean
default: false
review_simple_changes:
description: Review simple changes
required: false
type: boolean
default: false
review_comment_lgtm:
description: Review comment LGTM
required: false
type: boolean
default: false
openai_light_model:
description: OpenAI light model to use
required: true
type: string
default: 'gpt-4'
openai_heavy_model:
description: OpenAI heavy model to use
required: true
type: string
default: 'gpt-4'
openai_timeout_ms:
description: OpenAI timeout in milliseconds
required: false
type: number
default: 900000
language:
description: Language of the review
required: true
type: string
default: 'ja-JP'
secrets:
GITHUB_TOKEN:
required: true
OPENAI_API_KEY:
required: true
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
steps:
- uses: coderabbitai/ai-pr-reviewer@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
with:
debug: ${{ inputs.debug }}
review_simple_changes: ${{ inputs.review_simple_changes }}
review_comment_lgtm: ${{ inputs.review_comment_lgtm }}
openai_light_model: ${{ inputs.openai_light_model }}
openai_heavy_model: ${{ inputs.openai_heavy_model }}
openai_timeout_ms: ${{ inputs.openai_timeout_ms }}
language: ${{ inputs.language }}
system_message: |
あなたは @coderabbitai(別名 github-actions[bot])で、OpenAIによって訓練された言語モデルです。
些細なコードスタイルの問題や、コメント・ドキュメントの欠落についてはコメントしないでください。
summarize: |
次の内容でmarkdownフォーマットを使用して、最終的な回答を提供してください。
### 概要: 特定のファイルではなく、全体の変更に関する高レベルの要約を80語以内で。
### 詳細: ファイルとその要約のテーブル。スペースを節約するために、同様の変更を持つファイルを1行にまとめることが可能
summarize_release_notes: |
このプルリクエストのために、markdownフォーマットで簡潔なリリースノートを作成してください。
変更は以下のような分類で箇条書きにすること:
"New Feature", "Bug fix", "Documentation", "Refactor", "Style",
"Test", "Chore", "Revert"
例えば:
```
- New Feature: モーダルコンポーネントを追加
```
回答は50-100語以内にしてください。yml- github/workflows/check-pr-changes-limit.yml
ymlname: Limit number of changed lines
on: workflow_call: inputs: limit: description: Limit of changes required: true type: number extension: description: > File extensions that you want to count changes. Do not include ”.” before extensions. Use regular expressions if you want to specify multiple extensions. (example) kt|yml|gradle required: true type: string exclude_dir: description: > Directories where you don’t want to count changes. Do not add ”/” at the end of directory name. type: string required: false
env: LIMIT: {{ inputs.extension }} EXCLUDE: ${{ inputs.exclude_dir }}
jobs: limit-changed-lines: name: Limit changed lines in the pull request runs-on: ubuntu-latest steps:
- name: Checkout base branch uses: actions/checkout@v3 with: ref: ${{ github.base_ref }}
- name: Setup base commit ID run: echo “BASE=GITHUB_ENV
- name: Checkout PR branch uses: actions/checkout@v3
- name: Count number of changed lines and prepare comment id: count_changes run: | changed=BASE —numstat \ | if [ -n “EXCLUDE" \]; then grep -vE "^(\\d+\\s+)+\\/?(EXCLUDE)\/”; else cat; fi \ | grep -E ”.*.(” \ | awk ’{ additions+=2 } END { print additions+deletions }’) echo “CHANGED=GITHUB_ENV
plaintextif [ $changed -gt $LIMIT ]; then message="**The number of changed lines exceeds the limit.**\n:hammer_and_wrench: LIMIT: $LIMIT, :fire: CHANGED: $changed" echo "MESSAGE=$message" >> $GITHUB_ENV echo "::error::Exceeds limit. (Limit: $LIMIT, Changed: $changed)" else message=":sparkles: Changes are within the limit :sparkles:" echo "MESSAGE=$message" >> $GITHUB_ENV fi - name: Post comment uses: actions/github-script@v6 with: script: | const message = process.env.MESSAGE; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: message });
Code Review Workflowの解説#
このWorkflowは、プルリクエストの開始、プルリクエストレビューコメントの作成、およびイシューコメントの作成に反応します。 特に、GitHubのイベントに基づいて動作し、コードレビューのプロセスを自動化するために設計されています。
Githubの権限権限#
このWorkflowには、コンテンツの読み取りとプルリクエストの書き込み権限が必要です。
トリガー#
下記のイベントに反応して自動レビューが起動されます。
pull_request: プルリクエストが開かれたときpull_request_review_comment: プルリクエストのレビューコメントが作成されたときissue_comment: イシューにコメントが作成されたとき
並行性#
このWorkflowでは、concurrencyを設定しています。 これは、特定のグループ内で複数のジョブが同時に実行されるのを防ぎ、重複や競合を避けるためです。 また、プルリクエストレビューコメントイベントが発生した場合にのみ、進行中のジョブのキャンセルを避ける設定が施されています。
レビュー#
このアクションは、AIによるコードレビューを提供し、以下の環境変数を使用します:
GITHUB_TOKEN: GitHubから提供されるトークンを設定します。OPENAI_API_KEY: OpenAIのAPIキーを設定します。
また、以下のオプションを設定しています:
`debug: false`: デバッグモードの無効化`review_simple_changes: false`: 単純な変更に対するレビューの無効化`review_comment_lgtm: false`: LGTMのレビューコメントを無効化`openai_light_model: gpt-4`: 要約などに使用するOpenAIモデルの選択しています、コスト削減でgpt-3.5-turboを指定するのもあり`openai_heavy_model: gpt-4`; コードレビューに使用するOpenAIモデルの選択しています`openai_timeout_ms: 900000`:処理のタイムアウト時間`language: ja-JP`: 生成する言語を設定しています
レビューの概要と詳細#
AIは、レビューの概要と詳細なフィードバックを提供します。 これには、変更の高レベルの要約、ファイルごとの変更点の詳細、リリースノートの作成が含まれます。
このWorkflowは、開発プロセスを効率化し、より迅速かつ正確なフィードバックを提供することを目的としています。
実行結果#
- ワークフローをリポジトリに反映して、実際にPRを作成してAIコードレビューを試してみます。
- PRが作成されるとAIレビューが開始され下記のような処理中コメントが追加されます。
↗ - そのまま数分待つと下記のようにPRのサマリが自動で更新されます。
↗
↗ - またコメントでもPRの詳細な要約が生成されます。
↗ - さらにケアレスミスや改善案のコメントも追加されています。
↗
↗ - AIレビューの設定で日本語指定していたのでレビューもしっかり日本語で生成されています。
コスト面#
- コスト麺はだいたい1回レビューするのに100円程度かかりました。
- すべてをGPT4で処理するようにしているのと日本語で回答するようにしているので高めになっていると思います。
- この辺はチューニングの余地アリで、
`openai_light_model: 'gpt-4'`としていたところをgpt-3-turboにする- レビューを英語で生成する
- レビュー生成用のプロンプトを工夫してトークン数が減るようにする
- 上記の対応をすることでもう少しコスト削減はできると思います。
まとめ#
AIによるコードレビューを導入して試してみました。 思ったより使えるなという印象で、フォーマッターやLintチェックではレビューし辛い内容のレビューが生成できていたかと思います。 GPT4を使用するので1回のレビューでもそれなりのコストがかかりますが、人間がレビューするよりは低いコストでレビューが行えました。 また、人間によるレビューではレビュアーによってレビューの品質はまちまちになりがちですが、フォーマッターやLintチェックのようにAIレビューであれば一定以上の品質を担保しやすくなります。 AIレビュー用にPRサイズ制限もしているので最終的に人間がレビューする際も見やすいサイズのPRになります。 gpt-4のコストがさらに安くなればもっと気軽にバンバン使いたいとこです。
参考#
- githubのPR行数制限フローを作ってみた ↗
- Pull requestの理想的なサイズとその理由 ↗
- GitHub Actionsでプルリクエストの変更行数を制限する #GitHubActions - Qiita ↗
- githubのPR行数制限フローを作ってみた ↗
- check-PR-update-rows/.github/workflows/check_update_rows.yml at main · eno-conan/check-PR-update-rows · GitHub ↗
- PR-Agent を使って Pull Request をAIレビューしてみた。(日本語対応もしてみた) - LayerX エンジニアブログ ↗
- ChatGPT CodeReviewでコードレビューを自動化してみた|LLMラボ ↗
- ChatGPT APIとGitHub ActionsでPull RequestのAI Code Reviewをつくってみた ↗
- ChatGPT にプルリクエストのタイトルをレビューしてもらう - TENTIALのテックブログ ↗
- 【ChatGpt】CodeRabbitとGithubActionsを連携してプルリクエストのレビューと要約を自動生成する ↗
- CodeRabbit: AI-powered Code Reviews ↗
- もう初回コードレビューはAIに任せる時代になった - CodeRabbit - ↗


