はじめに
ChatGPT すごいですよね(略)
前回の記事では、ChatGPT をつかった業務システムっぽい構成を検証してみましたが、今回はもうちょっと現実的に使えそうな方向ということで、要約機能を試したいと思います。
週次レビューでどんな作業をしてきたか、スクラムの朝会で昨日何したか、あたりを GitHub の commit log の情報を ChatGPT に与えて要約してみたいと思います。
今回は諸事情で Azure OpenAI Service を使いますが、基本的な使い方は OpenAI と一緒です。適宜読みかえてもらえたらなと思います。
なお、使ったモデルは GPT-3.5-TURBO (0301) です。(早く 4 でやってみたい。。。)
GitHub の commit log の加工
パラメータは色々ありますが、今回は以下の形式で、sinceとuntilを指定したいと思います。
https://api.github.com/repos/{owner}/{repo}/commits?since=2020-01-01T00:00:00+09:00&until=2020-12-31T23:59:59+09:00
これだと {owner}/{repo} の 2020年1月1日0時0分0秒~2020年12月31日23時59分59秒(日本時間+9)
の commit 履歴を全部抜いてくることができます。
ただこの commit 履歴には様々な情報が含まれるため、これをそのまま ChatGPT に渡すと token の盛大な無駄遣いになること&余計な情報が要約に悪影響しそうなため、API を呼び出した結果から必要な情報(author.name と commit.message、あと author.date) だけ抜きます。
前回の記事で作ったアプリを元にしたため、サンプルコードは、Vue3.2(CDN) + Expressjs での実装抜粋です
あと今回は public なリポジトリを対象にしました。 private の場合は認証を通してあげれば同じことができます。が、ここでは割愛します。
fetch("https://api.github.com/repos/{owner}/{repo}/commits?since=2020-01-01T00:00:00+09:00&until=2020-12-31T23:59:59+09:00")
.then(response => response.json())
.then(data => {
const commits = data.map((item)=>({
"name": item.commit.author.name,
"message": item.commit.message,
"date":item.commit.author.date
}))
this.message = JSON.stringify(commits)
})
ここで取得した this.message を Azure OpenAI Servcie にポストする形にしました。
ChatGPT の AI モデルについて
Azure OpenAI Service の場合、以下のパラメータを指定します。
- {Azure OpenAI Endpoint}
- {Deployment Model}
- {Azure OpenAI API Key}
それぞれのパラメータについては、公式のドキュメントを参考にしました。
また、もしOpenAI の方を使うのであれば、前回記事のように、公式サイトのSDKベースで実装するといいですね。
前回は ChatGPT に日本語で指示を与えていましたが、どうしても回答を固定フォーマットにすることが安定しなかったので、今回は英語+temperatureを0.5 にしてやってみました。この辺も細かい調整ノウハウありますね・・
なお、やっている内容は、
[
{"name":NAME1,"message":MESSAGE1,"date":DATE1},
{"name":NAME2,"message":MESSAGE2,"date":DATE2},
{"name":NAME1,"message":MESSAGE3,"date":DATE3}
]
のスタイルで受信したコミット履歴の情報を、NAMEごとにMESSAGEs を要約してくれ、という指示と、回答は、以下のフォーマットであることを指定する指示をいれました。
[
{
"name":NAME1,
"summary": **SUMMARY OF NAME1's messages in Japanese**
},
{
"name":NAME2,
"summary": **SUMMARY OF NAME2's messages in Japanese**
},
]
メソッドの全体像は以下の通りです。
async function getAOAIAnswer(message) {
const response = await axios.post({Azure OpenAI Endpoint }+"/openai/deployments/{Deployment Model}/completions?api-version=2022-12-01", {
"prompt": `
<|im_start|>system\n
You receive a JSON list like [{"name":NAME1,"message":MESSAGE1,"date":DATE1},{"name":NAME2,"message":MESSAGE2,"date":DATE2},{"name":NAME1,"message":MESSAGE3,"date":DATE3}].
Please summarize the list by each person and output a JSON list only.
Your output JSON format MUST BE below. please return **ONLY A JSON LIST**.
[
{
"name":NAME1,
"summary": **SUMMARY OF NAME1's messages in Japanese**
},
{
"name":NAME2,
"summary": **SUMMARY OF NAME2's messages in Japanese**
},
]
<|im_end|>
<|im_start|>user\n
${message}
<|im_end|>
<|im_start|>assistant`,
"max_tokens": 800,
"temperature": 0.5,
"frequency_penalty": 0,
"presence_penalty": 0,
"top_p": 0.95,
"stop": ["<|im_end|>"]
}, {
headers: {
'Content-Type': 'application/json',
'api-key': {Azure OpenAI API Key}
}
});
return response.data.choices[0].text
サンプルアプリでの実行結果
それでは上記の内容をもとに、public なリポジトリということで、今回は dotnet/aspnetcore のコミット履歴を使わせてもらいたいと思います。
選んだ基準は、コミットが頻繁に行われていること、コミットログがキレイに入っていることでした。色々他のプロジェクトのも見てみたいところです。
実際に試したのは、日本時間の2023年3月1日9時~2023年3月2日9時までの24時間のデータです。
こんなのです-> https ://api.github.com/repos/dotnet/aspnetcore/commits?since=2023-03-01T18:00:00Z&until=2023-03-02T18:00:00Z
取得できたコミットログを必要なデータのみに絞って、ChatGPT に要約してもらった結果が以下です。きちんと全部確認はしてませんが、それっぽく要約してくれていますね!
[
{
"name": "Brennan",
"summary": "client result fail でクライアントが呼び出し引数を解析できない場合は失敗する(#46910)"
},
{
"name": "Nick Stanton",
"summary": "QuickGridを製品化する(#46573)"
},
{
"name": "dotnet-maestro[bot]",
"summary": "dotnet / efcoreビルド20230301.1から依存関係を更新する(#46966) [main] dotnet / efcoreから依存関係を更新する(#46930)"
},
{
"name": "William Godbe",
"summary": "sourceIndexPackageVersionを更新する(#46946)"
},
{
"name": "Thays Grazia",
"summary": "_hotReloadAgent変数を初期化する前に使用しようとしないようにする(#46916)"
},
{
"name": "Bruno Oliveira",
"summary": "ProblemDetailsJsonOptionsSetupでJsonSerializerOptionsコピーを削除する(#46716)"
},
{
"name": "Mitch Denny",
"summary": "ルートパラメーターのTryParseサポートを追加する(#46921)"
}
]
今回は英語で指示をしたからか、JSONフォーマットの返り値はかなり確実に(試している限りは安定して)返ってきました。JSONで返ってくるなら Web 上に綺麗に表示できますねやったー。
ちょっとおまけ的に、shyamagu/choi のコミットログも要約してみます。
こんなURLをもとにします。 -> https ://api.github.com/repos/shyamagu/choi/commits?since=2022-06-01T18:00:00Z&until=2022-07-01T18:00:00Z
2022年6月1日9時~7月1日9時までの1か月間のデータです。(そもそもコミットが少ないので、期間を長くして対応)
最近なのか?というのはありますが、何をやったかは何となくわかりますね。いいですね。
まとめと考察
今回は、GitHub のコミットログを ChatGPT に与えて、要約してもらうことに挑戦してみました。結構いい感じにまとめが出てるかな?と思いましたが、課題としては
- コミットログが適当だとどうしようもない ("hoge"とか"test"とか入れられてると…)
- コミットログが少なければ、別に要約なんかしなくても GitHub 上で確認すればよい
- きちんと要約ができるとして、コスパの観点はどうなんだろう?(大したコストではないですが…)
っていうところでしょうか。逆に、
- コミットが多人数で、頻繁に実施されている
- コミットログがきちんと書かれている
のであれば、パッと確認するのにはとても良さそうかなと思いました。
Private リポジトリ―に対しても GitHub Apps とかつかって認証とれば取得できますので、レビュー時に表示して、あとは個々人に補足してもらう使い方をすると良いかもですよね。もし ChatGPT がきちんと要約できていなくても、その場で訂正できるのであれば使い方として間違いないかなとも。(あると嬉しい系)
あと今回は英語で実施したことで JSON フォーマットが安定して返ってきたもの面白いポイントでした。GPT-4 とかになれば日本語でも問題ないようになるかもしれませんが、それでも英語の方が精度は良いらしいので、やっぱり英語かぁっていう。
それでもたまに回答が途中で途切れる事象は発生しました。今回のつくりだとJSON にパースできなかったら再取得とかするといいかもです。
あとそうだ。summary の内容がやっぱり実行の都度かなり揺れます。ここについては、どんな summary なのかもう少し補足してあげれば良さそうです。
というわけで、もし GitHub をつかっていて、かつレビュなどのタイミングで誰が何をしたかをコミットベースで会話している(人間系でまとめている)のであれば、役に立ちそうな感じがしましたということで、今回の検証はここで終わりです。読んでいただき、ありがとうございました。