generative-ai, githubactions
生成AIを使ってブログ記事のレビューを自動化する方法
かれこれ 8年間ほどブログ記事を書いているが、個人で書き進めている関係上、誰かにレビューしてもらうことがない。 そのため、go-zen-chu/aictl を開発し、GitHub Actions で PR を出した記事に対してレビューをしてもらうようにする。
コードレビューを生成AIで行ってくれる製品や Copilot のようなツールはあるものの、ブログ記事をレビューしてもらうためのツールはあまりなさそうなのと、OpenAI のクライアントを利用すれば簡単に実現できそうだったので、自分の学習のためにも作ってみた。
導入方法
導入方法は go-zen-chu/aictl の README に記載しているが、
- 下記の yaml を
.github/workflows/check-pr.ymlに配置する - repository の secret に AICTL_OPENAI_API_KEY を設定する
- API KEY については、API Reference - OpenAI API を確認
で導入は完了する(secrets.GITHUB_TOKEN が出てくるが、これは GitHub Actions 実行時にデフォルト存在するので設定不要)
1name: check-pr
2on:
3 pull_request_target:
4 types: [opened, synchronize]
5jobs:
6 aictl-review:
7 runs-on: ubuntu-latest
8 permissions:
9 pull-requests: write
10 steps:
11 - name: Get number of commits for fetch depth
12 run: echo "fetch_depth=$(( commits + 1 ))" >> $GITHUB_ENV
13 env:
14 commits: ${{ github.event.pull_request.commits }}
15 - name: Git checkout until fetch-depth
16 uses: actions/checkout@v4
17 with:
18 fetch-depth: ${{ env.fetch_depth }}
19 # need to specify ref to fetch PR head, otherwise you get main branch with no HEAD
20 ref: ${{ github.event.pull_request.head.sha }}
21 - name: Fetch base branch as origin
22 run: git fetch origin ${{ github.event.pull_request.base.ref }}
23 - name: Get the diff between PR and origin branch and get commit message too
24 id: git-diff
25 run: |
26 # If fetch-depth is not specified in checkout, HEAD cannot be found
27 # Make sure to filter out deleted file in `git diff` since you cannot review deleted files
28 diff_files=$(git diff --name-only --diff-filter=ACMR origin/${{ github.event.pull_request.base.ref }}..HEAD | tr '\n' ',' | sed 's/,$/\n/')
29 echo "diff_files: ${diff_files}"
30 echo "diff-files=${diff_files}" >> "$GITHUB_OUTPUT"
31
32 # In PR, you cannot get `github.event.head_commit.message` so you need to get commit message via git log
33 commit_msg=$(git log --format=%B -n 1 ${{ github.event.pull_request.head.sha }})
34 echo "commit_msg: ${commit_msg}"
35 echo "commit-msg=${commit_msg}" >> "$GITHUB_OUTPUT"
36 - name: Run aictl for code review
37 id: aictl-review
38 uses: go-zen-chu/aictl@main
39 if: ${{ steps.git-diff.outputs.diff-files != '' && !contains(steps.git-diff.outputs.commit-msg, '[skip ai]') }}
40 with:
41 query: |
42 Markdown ファイルはプログラミングなどの技術記事、ライフハック記事や書評などを記載しています。
43 より読みやすく、多くの人に読んでもらえるようにする観点でレビューをお願いします。
44
45 その他ファイルは、このブログシステム自体のソースコードになります。
46 より良いブログシステムを構築できるように、コードの品質や保守性の観点でレビューをお願いします。
47 language: 日本語
48 text-files: ${{ steps.git-diff.outputs.diff-files }}
49 env:
50 AICTL_OPENAI_API_KEY: ${{ secrets.AICTL_OPENAI_API_KEY }}
51 - name: Post aictl review result to PR comment
52 if: steps.aictl-review.outcome != 'skipped'
53 run: |
54 # make sure to checkout to pr branch and resolve detached HEAD state
55 git checkout ${{ github.ref_name }}
56 # TIPS: surrounding with single quote, you can ignore `code` string in outputs
57 cat <<'AICTL_REVIEW_EOF' > response.md
58 ${{ steps.aictl-review.outputs.response }}
59 AICTL_REVIEW_EOF
60 gh pr comment --body-file response.md "${URL}"
61 env:
62 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63 URL: ${{ github.event.pull_request.html_url }}
実行結果
上記の説明をすると、
- PR 作成時や更新時に実行される
- PR で出しているコミットすべてを取得して、ファイルの差分を出す (git-diff)
- 2.の差分を aictl で生成AI に問い合わせる。
queryの内容は自由に決める[skip ai]を commit メッセージに入れると、実行をスキップする
- aictl の出力内容を PR に出力する
という流れだ。
実際にこの記事の内容を PR レビューさせたものを画像として載せる。
結構、良いレビューがもらえているのではないだろうか。より詳細にレビューがほしければ、aictl-review の query でより具体的にレビューしてもらいたいポイントを指示するようにすればよい。
制限事項や今後の展望
現時点である程度実用的だが、これから aictl で実装していきたいものとして、下記が挙げられる。
- 現在は強制的に安いモデルの GPT-4o-Mini になっているので、モデルを自由に選択できるようにする
- 他の生成AIもサポートできるようにする(これは時間がかかりそう)
- Context を理解するために、過去の PR で出した内容を覚えられるようにする
今後、時間を見つけて開発していきたい所存だ。