앱스토어 리뷰 차익거래
경쟁사의 앱스토어 또는 구글 플레이 URL을 하나의 세션 GTM 브리프로 변환합니다: 순위가 매겨진 불만 클러스터, 깨진 약속 맵, 랜딩 페이지 헤드라인, 그리고 광고 카피 방향성 — 모두 리뷰어의 실제 문장에서 추출됩니다.
중요 규칙 (1단계 전에 읽으세요)
이 규칙은 모든 단계에 적용됩니다. 이를 위반하면 자체 QA(6단계)에서 실패합니다.
- 모든 인용은 원문 그대로여야 합니다. 의역, 문법 수정, 정리 금지. 리뷰어의 정확한 단어만 사용합니다.
- 조작된 통계 금지. 리뷰어가 명시적으로 유사한 표현을 사용하지 않는 한 "40% 더 빠름" 또는 "2배 더 신뢰할 수 있음"을 작성하지 마십시오. 자체 QA 단계에서 출처 없는 백분율을 확인합니다.
- 클러스터 이름은 리뷰어의 언어를 사용해야 합니다. 3단계의 안티패턴 표를 참조하십시오.
- 모든 헤드라인과 광고 카피 방향성은 해당 소스 클러스터를 인용해야 합니다. 형식:
[cluster: "cluster-name"]. - 출력에 2섹션은 항상 포함됩니다 — 성능이 저하된 경우에도 마찬가지입니다. 절대 생략하지 마십시오.
- 생성된 모든 카피에 금지어 사용 금지: powerful, robust, seamless, innovative, game-changing, streamline, leverage, revolutionize, transform.
1단계 — 입력 파싱 및 플랫폼 감지
하나의 앱 URL을 포함하는 자연어 프롬프트를 받습니다. URL을 추출합니다.
플랫폼 감지:
apps.apple.com→ 앱스토어play.google.com/store/apps/details?id=→ 구글 플레이- 다른 URL → 중단하고 응답: "앱스토어 또는 구글 플레이의 직접적인 URL을 제공해 주세요. 다른 소스의 리뷰 데이터는 분석할 수 없습니다."
ID 추출 (스크립트 실행 전에 수행):
| 플랫폼 | 추출 대상 | 방법 |
|---|---|---|
| 앱스토어 | 숫자 app_id | URL의 /id 뒤에 있는 숫자 |
| 앱스토어 | country | apps.apple.com/ 뒤의 2글자 코드 (예: us, gb) |
| 구글 플레이 | package_name | id= 쿼리 매개변수의 값 |
추출된 값을 저장합니다. 7단계의 출력 파일 이름에 필요합니다.
사용자의 프롬프트에 product_context(자신의 제품이 하는 일)가 제공된 경우 저장합니다. 5단계에서 카피를 개인화하는 데 사용됩니다.
2단계 — 리뷰 및 메타데이터 수집
전체 가져오기 스크립트를 실행합니다:
python3 scripts/fetch_reviews.py "{app_url}" --output {tmpdir}/asr-raw.json
(참고: {tmpdir}을 운영 체제의 임시 디렉터리로 바꾸세요. 예: macOS/Linux의 경우 /tmp, Windows의 경우 C:\Temp).
이 스크립트는 스토어 설명 메타데이터와 리뷰를 모두 가져옵니다.
- 앱스토어: iTunes API — 무료, 인증 불필요. 앱스토어 리뷰는 Apple의 공개 iTunes RSS 피드를 통해 가져옵니다. Apple의 API 제한으로 인해 일부 앱은 리뷰 0개를 반환할 수 있습니다. 이 경우 스킬은 사용 가능한 데이터로 계속 진행하고 경고를 기록합니다. 구글 플레이가 기본 지원 경로입니다.
- 구글 플레이:
google-play-scraper패키지 — 무료, 인증 불필요
스크립트가 실패하면 stderr에서 오류를 읽습니다. 일반적인 원인:
- 패키지가 설치되지 않음:
pip install google-play-scraper실행 - 앱을 찾을 수 없음: URL이 현재 유효한 라이브 목록인지 확인
- Google Play API 오류:
pip install --upgrade google-play-scraper실행 후 재시도
스크립트는 수집 진행 상황을 stderr에 출력합니다. 완료될 때까지 기다리세요. 완료 후 {tmpdir}/asr-raw.json을 읽고 사용자에게 수집 요약을 표시합니다:
✓ [N]개 리뷰 ([N]개 저평점 1–3★) [플랫폼]에서 수집
날짜 범위: [가장 오래된 날짜] ~ [가장 최근 날짜]
패키지: [iTunes API | google-play-scraper]
종료 코드 확인:
- 종료 코드 0 → 수집 성공,
metadata.store_description확인. null인 경우: 참고 — 2섹션은 성능 저하 상태를 사용합니다. 3단계로 진행합니다. - 종료 코드 1 → 오류 (stderr 메시지를 읽고 사용자에게 표시한 후 중단)
- 종료 코드 2 → 게이트 1 트리거 (10개 미만의 저평점 리뷰 발견)
게이트 1 — 신호 부족 중단: 스크립트가 종료 코드 2로 종료되면 {tmpdir}/asr-raw.json에서 gate_message를 읽고 사용자에게 그대로 표시합니다. 3단계로 진행하지 마십시오. 부분 브리프를 생성하지 마십시오.
3단계 — 불만 클러스터링
{tmpdir}/asr-raw.json에서 low_star_reviews를 로드합니다.
모든 저평점 리뷰를 4–6개의 명명된 불만 테마로 클러스터링합니다. 각 리뷰에 다음 공식을 적용하여 점수를 계산합니다:
complaint_weight = (4 - rating) × recency_factor
recency_factor:
리뷰 연령 ≤ 90일 → 1.0
리뷰 연령 91–365일 → 0.7
리뷰 연령 > 365일 → 0.4
리뷰 연령 = (오늘 날짜) − (리뷰 date 필드) (일 단위).
cluster_score = 클러스터 내 모든 리뷰의 complaint_weight 합계.
클러스터 이름 지정 — 중요 규칙:
추상적인 이름을 쓰고 싶을 것입니다. 저항하세요. 리뷰에서 정확한 동사와 명사를 사용하세요.
| ❌ 추상화됨 (틀림) | ✅ 리뷰어 언어 (맞음) |
|---|---|
| "안정성 문제" | "PDF로 내보낼 때 충돌 발생" |
| "동기화 문제" | "휴대폰과 데스크톱 간 동기화 후 데이터 손실" |
| "수익화 마찰" | "약속된 14일이 아닌 3일 후에 결제 장벽 나타남" |
| "성능 저하" | "검색할 때마다 앱이 멈춤" |
| "온보딩 문제" | "팀원 초대 방법을 모르겠음" |
규칙:
- 각 리뷰는 정확히 하나의 클러스터에 속함 (지배적인 테마에 할당)
- 리뷰 3개 미만인 클러스터는 폐기 — 노이즈로 기록
- 클러스터당 3–4개의 축어적 인용문 선택: 가장 낮은 평점부터, 그 다음 가장 최근 순
게이트 2 — 최소 클러스터 크기: 3개 미만 리뷰 클러스터를 폐기한 후, 남은 클러스터 수를 확인합니다.
게이트 3 — 낮은 신뢰도 플래그: 3개 미만의 클러스터만 남은 경우:
- 중단하지 마십시오. 계속 출력합니다.
- 앱 메타데이터 직후 브리프 헤더에 다음을 추가합니다:
⚠ 낮은 신뢰도: 최소 증거 기준(지원 리뷰 ≥ 3건)을 충족하는 [N]개의 불만 클러스터만 있습니다. 출력은 제한된 데이터를 반영합니다. 리뷰가 더 많은 경쟁사 또는 평점 필터를 넓혀 고려하십시오.
- 출력에 중간 등급 클러스터(점수 ≥ 5)를 포함합니다.
등급 분류 (1섹션 리더보드 테이블용):
- 심각: 점수 ≥ 60
- 높음: 점수 15–59
- 중간: 점수 5–14 (게이트 3이 적용되는 경우에만 포함)
- 노이즈: 점수 < 5 (폐기, 포함하지 않음)
클러스터를 {tmpdir}/asr-clusters.json에 작성:
{
"clusters": [
{
"name": "리뷰어 언어로 된 클러스터 이름",
"score": 34.5,
"tier": "높음",
"review_count": 14,
"verbatim_quotes": [
{"rating": 1, "text": "리뷰어의 정확한 단어", "date": "YYYY-MM-DD"},
...
]
}
],
"discarded_noise": 2,
"gate_3_triggered": false
}
4단계 — 깨진 약속 감지
이 단계가 이 스킬을 기존의 모든 도구와 차별화합니다. 별도의 명명된 단계로 실행되어야 합니다.
로드:
{tmpdir}/asr-raw.json의metadata.store_description{tmpdir}/asr-clusters.json의 모든 클러스터
store_description이 null인 경우: store_description_available: false로 설정합니다. {tmpdir}/asr-promises.json에 빈 broken_promises 배열과 아래 지정된 detection_note를 작성합니다. 5단계로 진행합니다.
스토어 설명을 사용할 수 있는 경우:
-
주장 추출. 주장은 앱 동작에 대한 구체적이고 테스트 가능한 진술입니다. 전체 정의와 예시는
references/broken-promise.md를 참조하십시오. 모호한 최상급 표현, 팀 설명, 보도 인용문은 제외합니다. -
교차 참조. 각 주장에 대해 모든 클러스터 이름과 축어적 인용문을 확인합니다. 클러스터가 약속된 동작의 실패를 직접 문서화하는 경우(최소 3개 리뷰) 모순이 존재합니다.
-
깨진 약속 레코드 생성 — 확인된 모순당 하나:
{ "claim_text": "스토어 설명의 축어적 발췌문", "complaint_cluster": "정확한 클러스터 이름", "gap_label": "주장 X; 사용자 보고 Y", "evidence_count": 18 }
{tmpdir}/asr-promises.json에 작성:
{
"store_description_available": true,
"broken_promises": [...],
"no_contradictions_found": false,
"detection_note": null
}
성능 저하 상태:
- 설명 없음:
store_description_available: false,detection_note: "스토어 설명을 사용할 수 없음 (YYYY-MM-DD에 가져옴, 비어 있음 반환). 깨진 약속 비교를 수행할 수 없습니다." - 모순 없음:
no_contradictions_found: true,detection_note: "깨진 약속이 감지되지 않았습니다. 스토어 설명이 불만 클러스터에 비해 과장된 주장을 하지 않는 것으로 보입니다."
깨진 약속 감지의 안티패턴(플래그를 지정하지 말아야 할 것)은 references/broken-promise.md를 참조하십시오.
5단계 — 카피 생성
3단계의 클러스터와 4단계의 깨진 약속을 사용하여 브리프의 3섹션~5섹션을 생성합니다.
카피 규칙 (세 섹션 모두에 적용):
- 모든 헤드라인과 방향성은 해당 소스 클러스터를 인용해야 함:
[cluster: "cluster-name"] - 금지어 사용 금지: powerful, robust, seamless, innovative, game-changing, streamline, leverage, revolutionize, transform
- 조작된 통계 금지 — 리뷰어가 사용하지 않는 한 백분율이나 숫자 없음
product_context가 제공된 경우: "Say this" 방향성을 해당 제품의 기능에 맞게 구체화합니다. 제공되지 않은 경우: 사용자가 채울 포지셔닝 템플릿으로 작성합니다.- 헤드라인에 리뷰어 언어 사용 — 실제 리뷰 텍스트에서 파생하거나 인용
3섹션 — 랜딩 페이지 H1 뱅크 (3–5개 헤드라인):
- 각각:
"[헤드라인 텍스트]" [cluster: "cluster-name"] - 가능하면 8단어 이하
- 좌절한 사용자를 직접 겨냥
4섹션 — 광고 카피 방향성 (정확히 3쌍):
클러스터: [클러스터 이름]
하지 말 것: "[경쟁사가 주장하는 내용 또는 일반적인 약한 대안]"
할 것: "[불만 증거에 근거한 반대 주장]"
증거: [N]명의 리뷰어가 보고한 [축어적 불만 요약]
5섹션 — 안티클레임 경고:
- 4단계의 각 깨진 약속당 하나의 경고
- 2섹션이 성능 저하된 경우: 단일 메모 (정확한 문구는
references/brief-format.md참조)
6단계 — 자체 QA
저장하기 전에 생성된 브리프가 다음 검사를 통과하는지 확인합니다. 어떤 검사든 실패하면 특정 항목을 수정하고 재확인합니다. 실패한 브리프를 저장하지 마십시오.
| 검사 | 규칙 |
|---|---|
| 축어적 인용문 존재 | 모든 클러스터에 ≥ 2개의 축어적 인용문이 있음 |
| 금지어 없음 | 3섹션~5섹션에 9개의 금지어가 나타나지 않음 |
| 출처 없는 백분율 없음 | 출력의 모든 %는 리뷰어의 실제 단어로 추적 가능해야 함 |
| 모든 카피 인용됨 | 모든 헤드라인과 "Say this"에 [cluster: "name"] 인용문이 있음 |
| 클러스터 수 ≥ 1 | 최소 하나의 클러스터가 게이트 2/3를 통과함 |
| 2섹션 존재 | 2섹션이 출력에 나타남 (모든 상태에서) |
| 인용문 평점 ≤ 3 | 모든 축어적 인용문이 1–3★ 리뷰에서 왔음 |
클러스터 수 참고: 통과 브리프의 최소 클러스터 수는 1개입니다(3개 아님). 게이트 3 낮은 신뢰도 플래그는 3개 미만의 클러스터가 생존하는 경우를 처리합니다 — 이는 경고이지 실패가 아닙니다. 자체 QA는 0개의 클러스터가 있는 경우에만 실패합니다.
7단계 — 출력 저장
references/brief-format.md의 형식에 따라 전체 브리프를 조합합니다.
저장:
docs/review-briefs/[app-id]-[YYYY-MM-DD].md
docs/review-briefs/ 디렉터리가 없으면 생성합니다.
전체 브리프를 사용자에게 출력합니다.
임시 파일 정리: {tmpdir}/asr-raw.json, {tmpdir}/asr-clusters.json, {tmpdir}/asr-promises.json.