◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-05-12中級

App Storeのレビュー1,000件をClaude APIで分析したら、自分のアプリの本当の問題が見えてきた

個人開発10年超・累計5,000万DLの経験から語る。App StoreレビューをClaude APIでバッチ分析し、次の改善優先順位を自動生成する実装パターンと、試して気づいた落とし穴を共有します。

Claude API128App Store9感情分析個人開発130Python22アプリ開発8レビュー分析

壁紙アプリのレビューが3,000件を超えたあたりで、自分の限界に気づきました。

毎週末、App Store Connectにログインしてレビューをひとつひとつ読み、Notionに分類しながらメモしていく作業。2014年から続けてきたその習慣は、アプリが増えるにつれて現実的ではなくなっていきました。4本のアプリで合計1,000件超のレビューが毎月つき、半日かけても全部読めありません。

そこでClaude APIを使ったバッチ分析を組んでみたのですが、試して最初に驚いたのは「分析の精度」ではなく「自分の認知バイアス」が可視化されたことでした。

手で読む限界と、3つ星レビューに眠っていたもの

人間がレビューを読むと、どうしても5つ星と1つ星に目が行きます。嬉しいコメントと、傷つく批判。その中間にある3つ星レビューは、感情的な引力が弱く、流し読みしがちです。

ところが、Claude APIでレビューを感情・キーワード・改善要望の3軸で構造化分析してみると、3つ星レビューに明確に多くの「具体的な改善ヒント」が含まれていることがわかりました。

「通知のタイミングが微妙にずれる」「ダウンロード後に一度アプリを閉じないと壁紙が反映されない」「有料プランへの導線がわかりにくい」——これらはどれも1〜2件ずつ書かれていて、手で読むと見落とすレベルです。でも1,000件をAPIで処理すると、同じ問題が30件に1件の頻度で繰り返されているのが見えてきます。

実装の全体像

分析フローはシンプルです。

  1. App Store Connect APIまたはiTunesのRSS APIでレビューを取得
  2. Claude APIに渡して構造化レスポンスを得る
  3. 結果をカテゴリ別に集計して優先度スコアを算出

以下に、実際に使っているPythonコードの要所を示します(APIキーやアプリIDは環境変数から読み込む構成です)。

import anthropic
import json
import os
from typing import Optional
 
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
 
def analyze_reviews_batch(reviews: list[dict]) -> list[dict]:
    """
    App Storeレビューのリストを受け取り、
    感情・カテゴリ・改善提案の構造化データを返す
    """
    # 1回のAPIコールで最大20件をまとめて処理(コスト削減)
    reviews_text = "\n---\n".join([
        f"評価: {r['rating']}星\nタイトル: {r['title']}\n本文: {r['body']}"
        for r in reviews[:20]
    ])
 
    message = client.messages.create(
        model="claude-haiku-4-5-20251001",  # 分析はHaikuで十分なコスパ
        max_tokens=2048,
        messages=[
            {
                "role": "user",
                "content": f"""以下のApp Storeレビューを分析し、JSON配列で返してください。
各レビューに対して:
- sentiment: "positive" / "neutral" / "negative"
- category: "ui" / "bug" / "feature_request" / "performance" / "billing" / "other"
- improvement_hint: 具体的な改善点(あれば)、なければ null
- priority_score: 1〜5(5が最高優先度。具体的で再現性の高い問題ほど高くする)
 
レビュー:
{reviews_text}
 
JSON配列のみを返してください。説明文は不要です。"""
            }
        ]
    )
 
    try:
        results = json.loads(message.content[0].text)
        return results
    except json.JSONDecodeError:
        # パース失敗時は空のリストを返してスキップ
        return []
 
def aggregate_by_priority(analyzed_reviews: list[dict]) -> dict:
    """
    分析結果を優先度スコアで集計し、
    次のスプリントで対応すべき改善点を上位5件抽出する
    """
    # priority_score 4以上の improvement_hint を抽出
    high_priority = [
        r["improvement_hint"]
        for r in analyzed_reviews
        if r.get("priority_score", 0) >= 4
        and r.get("improvement_hint")
    ]
 
    # Claude Sonnet 4.6で優先度上位5件を要約・整理
    if not high_priority:
        return {"top_issues": [], "summary": "高優先度の改善点は見つかりませんでした"}
 
    issues_text = "\n".join(f"- {h}" for h in high_priority)
 
    summary_message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=512,
        messages=[
            {
                "role": "user",
                "content": f"""以下のApp Storeレビューから抽出した改善ヒントをまとめ、
重複を排除して上位5件に絞ってください。
開発者がすぐに対応できる形式で、箇条書きで出力してください。
 
改善ヒント一覧:
{issues_text}"""
            }
        ]
    )
 
    return {
        "top_issues": high_priority[:10],
        "summary": summary_message.content[0].text
    }

Haikuで一括分析し、SonnetでまとめるツーステップにすることでAPI費用を抑えています。1,000件を処理してもだいたい$0.5〜$1.5程度です。

バッチ処理のポイント — レート制限とコスト管理

実装で一番詰まったのは、APIのレート制限との戦いでした。

レビューを1件ずつAPIに投げると遅すぎますし、一気に100件まとめると応答のJSON解析が安定しません。20件ごとのバッチが、精度とコストのバランス上もっとも安定していました。

import time
 
def process_all_reviews(reviews: list[dict]) -> list[dict]:
    """全レビューをバッチで処理する"""
    all_results = []
    batch_size = 20
 
    for i in range(0, len(reviews), batch_size):
        batch = reviews[i:i + batch_size]
        results = analyze_reviews_batch(batch)
        all_results.extend(results)
 
        # レート制限を避けるため1秒待機
        # Haikuの場合、TPMが高いので通常は不要だが安全のため入れる
        if i + batch_size < len(reviews):
            time.sleep(1)
 
        print(f"処理済み: {min(i + batch_size, len(reviews))}/{len(reviews)}")
 
    return all_results

time.sleep(1) を入れるかどうかは使っているティアによりますが、個人開発で使っているTier 1〜2の範囲では、これがあると安心です。

もうひとつ、max_tokens=2048 の制限は必ず設定してください。設定しないと、Claudeが丁寧に解説付きのJSONを返してしまい、パースに失敗することがあります(実際にこれで1時間溶かしました)。

分析結果を見てわかった「自分の思い込み」

実装そのものよりも、分析結果を見たときの体験の方が印象に残っています。

1,000件の分析を終えて出てきた優先度上位の課題は「ウィジェット機能のiOS最新版での動作不安定」でした。自分ではウィジェット機能には手をかけているつもりでしたし、レビューを手で読んでいたときは気づいていませんでした。でも頻度で見ると、この問題が他のどのカテゴリよりも多く報告されていたのです。

個人開発を長く続けていると、自分が熱中している部分と、ユーザーが困っている部分がずれてくることがあります。累計5,000万DLを超えてなお、この感覚のずれは埋まらないのだと気づきました。APIを使った定量分析は、その感覚的なずれを補正する道具として、思っていたより有用でした。

App Store Connect APIとiTunes RSS APIについて

レビューの取得方法についても簡単に触れます。

App Store Connect APIは公式ですが、セットアップに秘密鍵の設定が必要です。素早く試したい場合は、iTunes RSS APIが手軽です。

import requests
 
def fetch_reviews_rss(app_id: str, page: int = 1) -> list[dict]:
    """
    iTunes RSS APIを使ってApp Storeレビューを取得する。
    最大10ページ(500件)まで取得可能。
    """
    url = f"https://itunes.apple.com/jp/rss/customerreviews/page={page}/id={app_id}/sortby=mostrecent/json"
    response = requests.get(url)
 
    if response.status_code != 200:
        return []
 
    data = response.json()
    entries = data.get("feed", {}).get("entry", [])
 
    # 最初のentryはアプリ情報なのでスキップ
    return [
        {
            "rating": int(e["im:rating"]["label"]),
            "title": e["title"]["label"],
            "body": e["content"]["label"]
        }
        for e in entries[1:]  # index 0をスキップ
        if "im:rating" in e
    ]

ただしiTunes RSS APIは非公式扱いで、取得できるのは最新500件程度です。それ以上のデータが必要な場合はApp Store Connect APIが必要です。

試して気づいた落とし穴

  • JSON解析の失敗: Claudeが「以下がJSONです:」のような前置きをつけることがあります。message.content[0].text をstrip()した上で、最初の[から最後の]を切り出すと安定します
  • 感情の誤分類: 「〇〇機能を追加してほしい」という要望を、ネガティブと分類することがあります。プロンプトに「機能要望はfeature_requestカテゴリにしてください」と明示すると改善します
  • 日本語レビューの精度: Haikuは日本語の文脈を読む精度が高く、意外なほど正確でした。一方で、絵文字が多いレビューは誤分類されやすい傾向があります

まず手持ちのアプリのレビュー100件から試してみるのが一番早いと思います。小さい規模でも、自分が見落としていた傾向が出てくるはずです。


関連記事: Python SDKを使ったClaude APIチャットボット実装チュートリアル

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ API & SDK2026-09-17
画像は20枚ずつ送っています — 21枚目から全画像に別の上限がかかると知った日
素材フォルダの62枚を一度に送ったら invalid_request_error で落ちました。容量ではなく枚数が原因です。視覚トークンを28pxのパッチで数え直し、枚数・寸法・ペイロードの3つの上限を同時に見てバッチを組むまでの記録です。
⬡ API & SDK2026-09-06
訳文は自然なのに、実行時に落ちる翻訳がありました
多言語アプリの文言を Claude API で訳したとき、意味は正しいのに書式指定子だけが壊れることがあります。重大度で分けた受け入れ検査と、壊れた行だけを訳し直す修復ループを実装と実測でまとめました。
⬡ API & SDK2026-05-15
壁紙アプリの一括カテゴリ分類を Claude Vision API で自動化した話 — 実運用で見えた精度と限界
個人開発の壁紙アプリで画像のカテゴリ分類をClaude Vision APIに任せた実体験の記録です。SonnetとHaikuのモデル選択、75枚の手動検証で確かめた分類精度、実運用で踏んだ落とし穴、途中で落ちても再開できるバッチ設計、そして実際にかかったコストの感覚まで正直に書きました。