OpenAIを使った自動コードレビューの導入

## 1. はじめに

少し前からAIを使ったコードレビューに関する記事を目にするようになりました。その中でも特に有名なのは[CodeRabbit](https://coderabbit.ai/ja/)があるかと思います。
無料でも使用することができますが、利用機能や条件が限られており、業務や個人でちゃんと使いたい場合は有料プランに入る必要があります。それなりの額を毎月支払うのはハードルが高いため、もう少し気軽に利用できるサービスがないかを探しました。
いくつかある中で、今回は[ChatGPT-CodeReview](https://github.com/anc95/ChatGPT-CodeReview)を紹介します。

## 2. 対象読者

- AIによる自動コードレビューに興味のある方
- OpenAIのAPI利用経験者
- Github Actionsを使った開発改善に興味のある方

## 3. 目次
- [1. はじめに](#1-はじめに)
- [2. 対象読者](#2-対象読者)
- [3. 目次](#3-目次)
- [4. ChatGPT-CodeReviewの概要](#4-chatgpt-codereviewの概要)
- [5. 設定方法](#5-設定方法)
  - [5-1. Githubの設定](#5-1-githubの設定)
  - [5-2. Github Actionsのyml作成](#5-2-github-actionsのyml作成)
- [6. 使用例](#6-使用例)
  - [6-1. gpt3.5 のコメント例](#6-1-gpt35-のコメント例)
  - [ラベル名の統一性](#ラベル名の統一性)
    - [変更前:](#変更前)
    - [変更後:](#変更後)
  - [GitHub Actions 設定ファイルのコメントについて](#github-actions-設定ファイルのコメントについて)
    - [提案される追加のコメント:](#提案される追加のコメント)
- [6. 最後に](#6-最後に)

## 4. ChatGPT-CodeReviewの概要

[ChatGPT-CodeReview](https://github.com/anc95/ChatGPT-CodeReview)は、OpenAIのAPIを利用してコードレビューを行うサービスです。このサービスは使用量に応じて料金が発生します。使い方の紹介は[こちら(README)](https://github.com/anc95/ChatGPT-CodeReview/blob/main/README.ja.md)に日本語訳があります。
利用する方法は3つの方法があり、本記事は**Github Actions**を使った方法を紹介します。また、本記事ではOpenAIのAPIキーを利用しますが発行する手順は省略します。

- Github App
- Github Actions
- Self-hosting

## 5. 設定方法

設定方法は上記リンクのREADMEの記載を参考にしています。

### 5-1. Githubの設定

GitHubの設定にて`Secrets and variables`の`Actions`のページを開きます。
`Secrets`タブの`New repository secret`ボタンを押下して、下記を設定します。

- Name: `OPENAI_API_KEY`
- Value: (OpenAIのAPIキー)

![cap2024_4_9_21_41_51_380.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584089/645b44fc-8e66-c2aa-d772-5b2527fd0b7c.png)


### 5-2. Github Actionsのyml作成

Github Actionsで動作させるymlファイルを作成します。READMEにサンプルがありますので、そちらを参考に設定してください。私はサンプルから少し変更を加えたものを使っています。下記は実際に使用しているファイルです。普段はPHPを触っているので、対象はPHPファイルに限定しています。

```yml
name: Code Review

permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
    types: [opened, reopened, synchronize]
    paths:
      - "**.php"
      - "**.yml"

jobs:
  gpt-review:
    if: contains(github.event.*.labels.*.name, 'gptReview')
    runs-on: ubuntu-latest
    steps:
      - uses: anc95/ChatGPT-CodeReview@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          LANGUAGE: Japanese
          OPENAI_API_ENDPOINT: https://api.openai.com/v1
          MODEL: gpt-3.5-turbo
          PROMPT: |
            あなたはシニアエンジニアです。回答は日本語でお願いします。
            誰にとっても読みやすいコードになるよう、改善点を見つけたら積極的にレビューしてください。
            優れた箇所があれば挙げてください。
            あなたに渡されるコードは一部分であるため、未定義のメソッドやクラスなどの指摘については消極的にしてください。
            WHATを表すコメントに関する指摘については消極的にしてください。
            指摘時には変更する理由を説明した上で、変更後のコード例を示してください。
            特に以下の点を指摘してください:
            - 誤解を招いたり、実態を正確に表していない命名があるか
            - 適切な粒度で変数が定義されているか
            - メソッド・関数の区分が適切な粒度か
            - 冗長な書き方のコードがないか
            - N+1問題を引き起こす箇所がないか
            - WHYのコメントが適切にされているか
            - 複雑な条件式が作られていないか
            - 明らかなセキュリティの問題があるか
          top_p: 1
          temperature: 1
          max_tokens: 4096
          MAX_PATCH_LENGTH: 4096
```

## 6. 使用例

上記のymlファイルを実行した際の例を紹介します。
gpt3.5とgpt4を使った場合の2パターンで試しました。どちらもymlファイル対するコメントです。

2つを比較すると、やはりgpt4の方が細かくレビューしているような気がします。ただしgpt3.5の方も全く使えないほどひどいものではない印象です。

詳細な料金体系は[OpenAIの料金ページ](https://openai.com/pricing)で確認できます。1回のコミット当たりの料金目安は下記です。あくまでも私が使用した場合の平均値のため、実際に使っていただいた場合の金額と異なる場合がございます。
($1=150円換算しています)

- gpt3.5: $0.0015(=0.225円)
- gpt4: $0.035(=5.25円)

### 6-1. gpt3.5 のコメント例

```
改善点:
- PATHの指定が `.php` と `.yml` ファイルに対して行われているが、コメント文では `"**.php"` や `"**.yml"` というワイルドカードが使われているため、整合性が取れていない
- `MODEL` のコメントアウト部分が不必要であり、明示的な記述が欠けている

修正後のコード例:
```yaml
permissions:
  on:
    pull_request:
      types: [opened, reopened, synchronize]
    paths:
      - "**.php"
      - "**.yml"

jobs:
  gpt-review:
    if: contains(github.event.*.labels.*.name, 'gptReview')
    runs-on: ubuntu-latest
    steps:
      - uses: anc95/ChatGPT-CodeReview@main
        with:
          LANGUAGE: Japanese
          OPENAI_API_ENDPOINT: https://api.openai.com/v1
          MODEL: gpt-3.5-turbo # 利用できるモデル https://platform.openai.com/docs/models
          PROMPT: |
            あなたはシニアエンジニアです。回答は日本語でお願いします。
            誰にとっても読みやすいコードになるよう、改善点を見つけたら積極的にレビューしてください。
            優れた箇所があれば挙げてください。
            あなたに渡されるコードは一部分であるため、未定義のメソッドやクラスなどの指摘については消極的にしてください。
            WHATを表すコメントに関する指摘については消極的にしてください。
            指摘時には変更する理由を説明した上で、変更後のコード例を示してください。
            特に以下の点を指摘してください:
            - 誤解を招いたり、実態を正確に表していない命名があるか
            - 適切な粒度で変数が定義されているか
            - メソッド・関数の区分が適切な粒度か
            - 冗長な書き方のコードがないか
            - N+1問題を引き起こす箇所がないか
            - WHYのコメントが適切にされているか
            - 複雑な条件式が作られていないか
            - 明らかなセキュリティの問題があるか

          top_p: 1
          temperature: 1
          max_tokens: 4096
          MAX_PATCH_LENGTH: 4096
```

### 6-2. gpt4 のコメント例

```
    こちらのコード変更に関して、以下の改善点を見つけました。それぞれのポイントについて、変更する理由と変更後のコード例も併せて記載します。
    
    ### ラベル名の統一性
    
    **改善点**: `if` 文内で使用されているラベル名 `'gptReview'` は、他の部分では `'gpt review'` と表記されており、整合性がありません。
    
    **理由**: ラベル名は大文字小文字を区別し、同じ概念や機能を指す場合は全ての箇所で統一した表記を用いるべきです。この統一性の欠如は、将来的なエラーや混乱の原因となり得ます。
    
    #### 変更前:
    ```yaml
    +    if: ${{ contains(github.event.*.labels.*.name, 'gptReview') }}
    ```
    
    #### 変更後:
    ```yaml
    +    if: ${{ contains(github.event.*.labels.*.name, 'gpt review') }}
    ```
    
    ---
    
    ### GitHub Actions 設定ファイルのコメントについて
    
    **改善点**: コメントには実行条件や設定の意図を示す内容が含まれているべきですが、 `MODEL: gpt-4-0125-preview` の選択理由など具体的な説明がコメントによって示されていません。
    
    **理由**: 手順やパラメーターの選択についてのコメントは、他の開発者がコードを読み、理解し、必要に応じた変更を加える際に有効です。特に、バージョン指定や特定の設定値を採用した理由についてはその重要性が増します。
    
    #### 提案される追加のコメント:
    ```yaml
    +          #MODEL: gpt-3.5-turbo # https://platform.openai.com/docs/models (旧モデル、新モデルに更新)
    +          MODEL: gpt-4-0125-preview # gpt-4 最新プレビューバージョンを使用。性能向上のため。
    ```
    
    上記の改善点・提案を取り入れることで、より理解しやすく、かつ未来への保守性に優れた設定ファイルになると考えられます。
```

## 6. 最後に

gpt4の場合、1回あたり約5円だったため、気軽にコミットできなくなりそうな金額ですね。個人開発においてはコスト面からgpt3.5の方を使う予定です。
ChatGPTの有料プランには加入しているので、APIの方ももう少し特典があれば嬉しいなと思っています...

## 7. 参考記事

https://zenn.dev/minedia/articles/7928ef7545b393