ストアのレビューを1件ずつ読むのは続きません。かといって全部AIに投げて「まとめて」と頼むと、どこかで数字を作られます。ZOZO TECH BLOGで、Google Playのレビューを毎月GitHub Actionsで集計し、Claude Codeに考察レポートを書かせる仕組みが紹介されました。肝は、集計と考察を分け、AIの文章は検品を通ったものだけを公開する設計です。個人開発のアプリでも使える形に縮めて整理しました。
月次レビューレポートの5工程の分担表(どこをコードで確定させ、どこだけAIに任せるか)と、AIの文章を公開前にふるい落とす2層の品質ゲートの作り方。個人アプリ向けに縮めたワークフローの骨組みも添えます。
題材はZOZOの体型計測アプリZOZOFITです。端末のカメラやセンサーを使うので、端末ごとに計測の成功率が大きく変わります。
これまではGoogle PlayのレビューをSlackに流し、個別に確認していたそうです。ここに課題が2つありました。
個人開発でも、規模が違うだけで同じことが起きます。通知で1件ずつ読むと、強い言葉のレビューばかり印象に残ります。欲しいのは「先月より何が増えたか」なのに、それは個別の通知からは出てきません。
仕組みはGitHub Actionsで毎月自動実行されます。工程を並べると、AIが書くのは4番目だけです。
Google Play Consoleは、開発者アカウントごとのCloud Storageバケットにレビューを毎月CSVで出力しています。閲覧権限だけを付けたサービスアカウントで、これを取りに行きます。手作業のダウンロードは要りません。
投稿者のユーザー名をランダムな文字列に置き換えます。消し漏れがないかは、後の検品工程でもう一度コードが確かめます。
件数、平均評価、本文がある割合、★1〜5の分布、低評価の内訳、バージョン別の統計、問題カテゴリ別の言及件数(キーワードで判定)、月次推移のグラフ。レポートに載る数字は、ここで全部決まります。
集計結果のまとめ、匿名化済みのレビュー本文、Jiraのリリース情報(リリース日と修正内容)を渡し、傾向の解釈と次にやることを書かせます。次にやることには、担当(開発・ビジネスなど)と優先度まで付けさせています。
社内のConfluenceに公開し、要点とリンクをSlackに流します。後で書く検品に落ちたレポートは公開されません。
ここが核心。AIには数字を計算させない。数字はコードが先に確定させ、AIはそれを読んで解釈を書く係に限定する。
「数字は入力データにあるものだけを使う」といったルールや「レビュー分析を担当するアナリスト」という役割は、Markdownのプロンプトファイルにまとめて書かれています。Pythonは呼び出しと検品の制御だけを受け持ちます。プロンプトの文言を直したいとき、コードに触らずに済む分け方です。
入力の選び方にも意図があります。まず、本文のあるレビューは評価に関係なく全件渡しています。改善の要望は高評価のレビューにも書かれているからです。記事では、★5を付けつつ縦方向の計測機能を求めたレビューが例に挙がっていました。低評価だけを抜き出して渡すと、こうした要望が漏れます。
次に、リリース情報を一緒に渡しています。理由は2つあります。
2つ目は見落としやすい点です。先月のレビューには、先月時点の不具合への苦情が並んでいます。それが今月のリリースで直っていても、レビューだけを読んだAIには分かりません。AIが知らない事実は、入力として渡さない限り考慮されない。当たり前ですが、月次で回す仕組みでは毎回効いてきます。
この仕組みでいちばん参考になるのが検品の作りです。書き上がったレポートは2層のチェックを通ります。
見出しの構成がそろっているか、引用したレビューIDが実在するか、匿名化の漏れがないか、本文の数字が集計結果と一致するか。正解がはっきり決まる項目はAIに任せず、コードが先に落とします。
数字の解釈は妥当か、原因と結果を取り違えていないか、といった機械では判定できない観点を、書いた本人とは別の呼び出しで採点します。書いた本人に採点させると甘くなるからです。合否を決めるのはPython側です。
流れの制御もPythonが持っています。AIに「書いて、確かめて、直して」まで任せる作りにはしていません。毎月同じ手順を回す定時処理なので、実行時間や挙動のぶれを抑えたいからです。落ちたときの扱いも決まっています。
3つ目の工夫は、検品を自動化した人ほど後から欲しくなるものです。チェックする側が間違っていると、書き直しのループは何も生まずに予算だけを使います。このブログでも、AIの「できました」を信じずに検品する考え方(Art30)や、品質は制約をどこに置くかで決まるという話(Art84)を書いてきました。この仕組みは、それを定時処理の形に落とした実例です。
著者自身も限界を書いています。書く側と採点する側が同じモデルなので、モデルが共通して見落とす誤りはどちらでも検出できません。別のモデルに採点させることや、人の確認を組み合わせることが今後の課題だそうです。また構築したばかりで、削減できた時間などの数字はまだ出ていません(記事中のサンプルの数値はダミーとのことです)。
個人のアプリはレビューの件数が少なく、Jiraもありません。それでも骨組みはそのまま使えます。縮めるとこうなります。
# .github/workflows/monthly-review.yml(骨組み)
on:
schedule: [{ cron: "0 0 3 * *" }] # 毎月3日。前月分のCSVが出そろうのを待つ
workflow_dispatch:
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python fetch_reviews.py # バケットから前月のCSVを取得
- run: python anonymize.py # 名前を置換
- run: python aggregate.py # 数字を確定 → stats.json
- run: npm install -g @anthropic-ai/claude-code
- run: python write_and_gate.py # 生成→検品→書き直しのループ
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
リリース情報の代わりには、gitのタグとコミットログで足ります。git log --since で前月分を抜き出し、「この期間に直したもの」として一緒に渡せば、直した不具合を未解決として挙げられる事故は防げます。
検品は、まず機械チェックだけで始めるのが手軽です。
# write_and_gate.py の検品部分(考え方)
def machine_check(report, stats, review_ids):
errors = []
for n in numbers_in(report): # 本文に出てくる数字を全部拾う
if n not in stats.values(): errors.append(f"集計に無い数字: {n}")
for rid in cited_ids(report):
if rid not in review_ids: errors.append(f"存在しないID: {rid}")
if looks_like_username(report): errors.append("匿名化漏れ")
return errors
# 落ちたら指摘を渡して書き直し。上限3回、同じ理由が続いたら即終了
数字の照合は、桁区切りや小数の丸めで誤検知が起きやすいところです。まさに「同じ理由で落ち続ける」原因になるので、初めのうちは止まったときのログを読んでチェック側を直す運用になります。Evaluatorは、機械チェックが安定してから足しても遅くありません。足すなら、ZOZOの記事が課題に挙げているとおり、書く側と違うモデルに採点させるのが筋です。
取得まわりで一つだけ注意があります。Play Consoleがバケットに出すレビューCSVは、文字コードがUTF-8とは限りません。読み込みで文字化けしたら、まず文字コードを疑ってください。
まとめ。AIに任せるのは解釈だけ。数字はコードで先に決め、出来上がった文章はコードで照合し、通らなければ公開しない。定時で回すAIの仕事は、この順番で組むと崩れにくくなります。
出典:平川「GitHub ActionsとAIによる月次分析 ── Google Playストアレビューの考察レポートを自動生成」(ZOZO TECH BLOG、2026年10月6日)。仕組みの構成・品質ゲート・今後の課題は同記事に基づきます。使用モデルの名称は同記事に記載がありません。「個人版に縮める」のワークフローとコードは、考え方を示すために筆者が書いた骨組みで、そのままでは動きません(取得・集計の各スクリプトは各自の環境に合わせて実装が必要です)。2026年10月時点の情報です。