生成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 実行時にデフォルト存在するので設定不要)
name: check-pr
on:
pull_request_target:
types: [opened, synchronize]
jobs:
aictl-review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Get number of commits for fetch depth
run: echo "fetch_depth=$(( commits + 1 ))" >> $GITHUB_ENV
env:
commits: ${{ github.event.pull_request.commits }}
- name: Git checkout until fetch-depth
uses: actions/checkout@v4
with:
fetch-depth: ${{ env.fetch_depth }}
# need to specify ref to fetch PR head, otherwise you get main branch with no HEAD
ref: ${{ github.event.pull_request.head.sha }}
- name: Fetch base branch as origin
run: git fetch origin ${{ github.event.pull_request.base.ref }}
- name: Get the diff between PR and origin branch and get commit message too
id: git-diff
run: |
# If fetch-depth is not specified in checkout, HEAD cannot be found
# Make sure to filter out deleted file in `git diff` since you cannot review deleted files
diff_files=$(git diff --name-only --diff-filter=ACMR origin/${{ github.event.pull_request.base.ref }}..HEAD | tr '\n' ',' | sed 's/,$/\n/')
echo "diff_files: ${diff_files}"
echo "diff-files=${diff_files}" >> "$GITHUB_OUTPUT"
# In PR, you cannot get `github.event.head_commit.message` so you need to get commit message via git log
commit_msg=$(git log --format=%B -n 1 ${{ github.event.pull_request.head.sha }})
echo "commit_msg: ${commit_msg}"
echo "commit-msg=${commit_msg}" >> "$GITHUB_OUTPUT"
- name: Run aictl for code review
id: aictl-review
uses: go-zen-chu/aictl@main
if: ${{ steps.git-diff.outputs.diff-files != '' && !contains(steps.git-diff.outputs.commit-msg, '[skip ai]') }}
with:
query: |
Markdown ファイルはプログラミングなどの技術記事、ライフハック記事や書評などを記載しています。
より読みやすく、多くの人に読んでもらえるようにする観点でレビューをお願いします。
その他ファイルは、このブログシステム自体のソースコードになります。
より良いブログシステムを構築できるように、コードの品質や保守性の観点でレビューをお願いします。
language: 日本語
text-files: ${{ steps.git-diff.outputs.diff-files }}
env:
AICTL_OPENAI_API_KEY: ${{ secrets.AICTL_OPENAI_API_KEY }}
- name: Post aictl review result to PR comment
if: steps.aictl-review.outcome != 'skipped'
run: |
# make sure to checkout to pr branch and resolve detached HEAD state
git checkout ${{ github.ref_name }}
# TIPS: surrounding with single quote, you can ignore `code` string in outputs
cat <<'AICTL_REVIEW_EOF' > response.md
${{ steps.aictl-review.outputs.response }}
AICTL_REVIEW_EOF
gh pr comment --body-file response.md "${URL}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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 で出した内容を覚えられるようにする
今後、時間を見つけて開発していきたい所存だ。