TENTIALのテックブログ

株式会社TENTIALのエンジニアチームが開発や組織のよもやまを謳っていきます

ChatGPT にプルリクエストのタイトルをレビューしてもらう

はじめまして。DevOpsエンジニアの田島です。

先日発表され大きな話題となったGitHub Copilot Xの中に気になる機能がありました。
曰くPR(プルリクエスト)のdescriptionを書く際に特定のタグを埋め込むことで該当部分がAIによるfiles changedの要約に置き換わるそうです。
素晴らしいですね。

参考: Copilot for Pull Requests - Suggestions for your pull request description

使い方としてはPR作成開始時に自動で展開される.github/PULL_REQUEST_TEMPLATE.mdに予めタグを入れておく方法が考えられるでしょう。

Related issue: #0000

# 概要
copilot.summary

# 詳細
copilot:walkthrough

copilot:poem

こうして足りない部分(主にWhy、なぜこの変更を行ったのか)について人間が補足を入れPR作成完了、とすればdescriptionの品質をチーム内で一定以上に保つことができます。

ではPRのタイトルはどうでしょうか?実際のところタイトルは本文よりも参照される機会が多い文です。当社でもリリースノートの記述を自動化しており、PRのタイトルがそのままノートに反映される仕組みになっています。

ですが上記Copilot for Pull Requestsを見るに現状ではタイトルの品質を担保できそうな機能は予定されていないようです…

…ので、作りましょうというのが今回のテーマですね。前置きが長くなりました。
当記事ではChatGPT APIGitHub Actionsを組み合わせてAIに全てのPRタイトルをレビューしてもらう方法について解説していこうと思います。

やること

  1. ChatGPT APIのKeyを取得する
  2. プロンプトをエンジニアリングする
  3. GitHub Actionsのワークフローを書く

1つずつ解説していきます。

1. ChatGPT APIのKeyを取得する

こちらのページから取得します。

取得したkeyは二度と表示できないためどこかにメモしておきましょう。またGitHub Actionsで使用できるようシークレットにも登録しておきます。
https://github.com/organizations/${your_organization's_name}/settings/secrets/actions

2. プロンプトエンジニアリング

参考: https://platform.openai.com/docs/api-reference/chat
細かい説明の前にまず完成品をお見せします。

OPENAI_API_KEY=sk-...

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [
      {
        "role": "system",
        "content": "あなたは優秀なエンジニアリングマネージャーです。これから送るプルリクエストのタイトルを「他のエンジニアに意図や背景が伝わるかどうか」で10段階評価し、評価理由をやさしくコメントしてください。評価値が7以下である場合は改善したタイトルの候補を3つ提示してください。評価値が8以上である場合、改善案は出力しないでください。"
      },
      {
        "role": "user",
        "content": "タイトル: ChatGPTにPRのタイトルをレビューしてもらうワークフローを追加"
      }
    ],
    "temperature": 0.2
  }'

これに対するChatGPTの返答がこちら(JSONからメッセージパートのみを抜粋)。

評価値: 9
 
理由: タイトルは簡潔で明確であり、プルリクエストの内容が一目で理解できます。また、タイトルには追加されるワークフローの内容が具体的に記載されており、他のエンジニアに意図や背景が伝わりやすいです。改善案はありません。

タイトルを「ワークフローを追加」にしてみると…

評価値: 6 

コメント: タイトル自体は簡潔で分かりやすいですが、どのようなワークフローを追加するのかが具体的に伝わっていません。他のエンジニアがプルリクエストの内容を理解しやすくする
ためには、追加するワークフローの種類や目的をタイトルに含めると良いでしょう。

改善案:
1. バグ修正用のワークフローを追加
2. テスト自動化用のワークフローを追加
3. デプロイメント用のワークフローを追加

いい感じですね。
ここで重要なポイントですが、ChatGPT(GPT-3.5)は同じ入力に対して必ずしも同じ答えを返しません

ですので、どんな投げかけに対しても同じような回答が欲しい場合にはプロンプトを工夫する必要があります。

あなたは優秀なエンジニアリングマネージャーです

ChatGPTの性能を引き出すための有名なおまじないです。
ChatGPTの人格にロールを与えることで回答の精度が上がるようです。

評価理由をやさしくコメントしてください

コメントを求めない場合ただ単に

評価値: 7

と言われてしまうことがあるため、やって欲しいことは全てかつ具体的に提示します。
また「やさしく」を入れることによって回答の口調がですます調で安定します。

評価値が7以下である場合は

ChatGPTは優しいので何も言わずとも改善案を提示してくれることがありますが、出す/出さないをこちら側でコントロールしたかったため評価を具体的な値で表してもらうことにしました。

改善したタイトルの候補を3つ提示してください

単に「改善案」とした場合

  1. タイトルに関連するキーワードを使用する
  2. 簡潔で明確なタイトルを使用する
  3. アクションを含める

と「改善するための案」を提示されてしまうことがあるため、これも具体的に表現します。

評価値が8以上である場合、改善案は出力しないでください

人間的には前段だけで十分と思われるのですが、ChatGPTでは両方の条件を書かないとダメなようです。この一文を加えない場合、評価値が8以上であっても改善案を提示されます。

検証過程

  • シンプルなif文
    「評価値が7以下である場合、~。」
    → 無視される
  • 限定を強調する
    「評価値が7以下である場合のみ、~。」
    → 無視される
  • else節を加える
    「評価値が7以下である場合、~。そうでない場合、~。」
    → 無視される
  • if文を重ねる(else ifではない)
    「評価値が7以下である場合、~。8以上である場合、~。」
    → OK

temperature

これはプロンプトではありませんが、リクエストのパラメータにtemperatureを含めると出力のバラつきをコントロールすることができます。
範囲は0~2で、値が大きいほど出力がランダムになります。

3. GitHub Actionsの設定

では最後にActionsのワークフローを書いていきましょう。
こちらも実際に当社で動かしているものをお見せします。

name: PR Title Reviewer
on:
  pull_request:
    types:
      - labeled
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
  PR_URL: ${{ github.event.pull_request.html_url }}
jobs:
  review:
    name: Review PR Title
    runs-on: ubuntu-latest
    if: github.event.label.name == '1.waiting for review'
    steps:
      - run: |
          title=$(gh pr view $PR_URL --json title | jq -r ".title")
          param=$(printf '{
            "model": "gpt-3.5-turbo",
            "messages": [
              {"role": "system", "content": "あなたは優秀なエンジニアリングマネージャーです。これから送るプルリクエストのタイトルを「他のエンジニアに意図や背景が伝わるかどうか」で10段階評価し、評価理由をやさしくコメントしてください。評価値が7以下である場合は改善したタイトルの候補を3つ提示してください。評価値が8以上である場合、改善案は出力しないでください。"},
              {"role": "user", "content": "タイトル: %s"}
            ],
            "temperature": 0.2
          }' "$title")
          res=$(curl https://api.openai.com/v1/chat/completions \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OPENAI_API_KEY" \
            -d "$param"
          )
          echo $res | jq
          echo '## ChatGPTのPRタイトルレビュー' > .comment
          echo $res | jq -r ".choices[0].message.content" >> .comment
          gh pr comment $PR_URL -F .comment

当社ではタグによってPRの状態を管理しているため、ChatGPTによるレビューのトリガーもタグとしました。

何度か登場するghというコマンドはGitHub CLIです。
GitHub-hostedのランナーにはデフォルトでインストールされていますので、GitHubに対して操作を行いたいときには是非使ってみてください。

TENTIALはGPTを含め最新技術でのAI活用に取り組んでいます!

TENTIALでは、「健康に前向きな社会を創り、人類のポテンシャルを引き出す。」というミッションを実現するために 最新の働き方を追い求めるチャレンジし続ける仲間を募集しています。

その他の求人はこちらから
https://www.wantedly.com/companies/tential