Github Actions でカジュアルに OpenAI を利用する

:::note info
[KLab Engineer Advent Calendar 2023](https://qiita.com/advent-calendar/2023/klab) の 5日目の記事です。
:::

## はじめに
今年は、ChatGPT-3などのOpenAIが注目されている年でした。
OpenAIは、様々な分野で活用されていますが、私も日々の仕事を少しでも楽にできないかといくつか楽しませてもらいました。
今回の記事では、そうやって作ったうちの GitHub Actions から Azure OpenAI Services をカジュアルにワンショットのリクエストする、公開ワークフローを紹介します。

https://github.com/gutio/ai1shot

### 技術要素
* Azure OpenAI Services : chat/completions
* GitHub Actions : JavaScript Action

## ai1shotの利用例
例えばai1shotを使うと、PRタイトルを元にしたLGTMコメントの自動生成が簡単に作れるようになります。
![LGTMデモ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32726/5affba1e-1350-2723-1cf6-7ae14ba43a52.png)


## 使い方
任意のワークフローの中で、以下のように利用できます
```yaml
    steps:
      # Ai1Shotのアクションを実行する
      - name: RunAi1Shot
        id: run_ai1shot
        uses: gutio/ai1shot@v1.0.0
        with:
          # (必須) Azure OpenAIのエンドポイントURL
          endpoint: ${{ vars.ENDPOINT_URL }}
          # (必須) Azure OpenAIのAPIキー
          key: ${{ secrets.API_KEY }}
          # (必須) 利用するモデル。あるいは独自のdeployment_id
          model: "gpt-4"
          # (必須) ワンショットリクエストする際のAI定義するシステムメッセージ
          system_message: "あなたはコードレビュワーです。つぎのタイトルのPullRequestに対してLGTMに一言添えるいいメッセージを考えてください。"
          # (必須) ワンショットリクエストする際に問いかけるユーザーメッセージ
          user_message: "Ai1Shotの初期実装完了"
```

## やっていること
ai1shotのAction内部でやっている事自体は非常にシンプルです。
JavaScript Actionで作成しており、[@azure/openai](https://www.npmjs.com/package/@azure/openai) を使ってAzure OpenAIのAPIを呼び出しているだけです。

ai1shotを作るにあたって唯一ハマったのは、Azure Open AI Servicesを利用するには Azure用のライブラリを利用しなければいけないところでした。
OpenAIのライブラリ[openai](https://www.npmjs.com/package/openai)では何故かうまく行かず、Azureのドキュメントを読み返す中で見つけて乗り換えるまでに少々手間取りました。

LGTMコメントをPRに自動でつけるワークフローの例は記事末尾に[付録](#付録)にしてあります。

## 作ってみて
「AIを活用する。チャットBotを作る。」というと、ユーザーとのやり取りなどコンテキストの管理やら、色々と大変そうに思えます。
しかし、渡されるテキストに対して固定でやって欲しいことを事前に決めておき、テキストを変えながら実行するだけでも、便利に活用することができます。

ゲームのマスタデータや技術ブログの原稿など、テキストをgit上で管理していることも多いかと思います。
こういったものについては、アイディア次第でワンショットでいろいろ応用が効きそうなので、活用を検討しています。

あと、この記事のためにLGTMコメントをPRに自動でつけるワークフローを作りましたが、実際にデモで使ってみると適当に書かれていることを知っていても嬉しくなります。ぜひプロジェクトに入れてみたいなと思っています。

## まとめ
GitHub ActionsからAzure OpenAIのAPIをカジュアルにワンショット利用するActionを作りました。
この記事のデモではLGTMコメントをPRに自動でつけるワークフローでしたが、他にも様々な用途で使えると思います。

実際、ai1shotを作ろうとしたきっかけは、ブログのtypoなど文章校正の手間を少しでも減らしたいと思ったことでした。
このあたりの実際の活用については、明日12/6の[技術広報 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/tech_pr)でご紹介します。

:::note info
公開しました！ [OpenAIを利用してAIに校正提案させた話](https://qiita.com/gutio/items/0029c95d671f71d33bac)
:::

AI活用や、チャットBotをつくるというと敷居を高く感じてしまうかもしれませんが、こんな簡単な使い途もあるというご紹介でした。

## 付録
```yaml:LgtmMessage.yml
# LGTMとPRにコメントすると、BotがPRタイトルを踏まえたLGTMメッセージをコメントする
name: LgtmMessage

on:
  issue_comment:
    types:
      - created

jobs:
  run:
    # PRコメントでLGTMとのみ書かれたら実行する
    if: (github.event.issue.pull_request != null) && github.event.comment.body == 'LGTM'
    runs-on: ubuntu-latest

    steps:
      # PRタイトルを元にLGTMメッセージを作るAi1Shotのアクションを実行する
      - name: Run Ai1Shot
        id: run_ai1shot
        uses: gutio/ai1shot@v1.0.0
        with:
          # Azure OpenAIのエンドポイントURLをActionsのパラメータから取得する
          endpoint: ${{ vars.ENDPOINT_URL }}
          # Azure OpenAIのAPIキーをActionsのSecretsから取得する
          key: ${{ secrets.API_KEY }}
          # 利用するモデル
          model: "gpt-4"
          # システムメッセージ
          system_message: "あなたはコードレビュワーです。つぎのタイトルのPullRequestに対してLGTMに一言添えるいいメッセージを考えてください。"
          # ユーザーメッセージ（PRタイトル）
          user_message: ${{ github.event.issue.title }}

      # Ai1Shotで作ったLGTMメッセージをPRにコメントする
      - name: LGTM PR Comment
        uses: actions/github-script@v6
        env:
          PR_COMMENT: ${{ steps.run_ai1shot.outputs.result_assistant_message }}
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: process.env.PR_COMMENT
            })
```