关于 app-store-review-arbitrage
将竞争对手 App Store 或 Google Play 评论转化为 GTM 简报的营销技能,供产品营销团队分析用户抱怨并制定定位。它结合评论主题聚类、承诺落差识别和文案建议,并要求引用原评论。
主要功能
- 01评论抓取与低评分筛选
- 02按主题聚类并排序抱怨
- 03对照商店描述识别承诺落差
- 04生成落地页标题与广告方向
- 05校验引文与文案规则
适用场景
- 01分析竞争应用的低评分评论
- 02依据用户投诉制定产品定位
- 03为落地页和广告准备文案方向
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ varnan-tech/ opendirectory --skill app-store-review-arbitrage安装后在 Claude Code 中输入/app-store-review-arbitrage确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.env.examplepackage.jsonREADME.mdevals/evals.jsonREADME.mdevals/fixtures/eval3-mock.jsonreferences/brief-format.mdbroken-promise.mdscoring.mdscripts/fetch_reviews.py详细介绍
app-store-review-arbitrage
将竞品的 App Store 或 Google Play 网址转化为一份可在单次会话中完成的 GTM 简报:按优先级排列的投诉聚类、承诺落差图、落地页标题和广告文案方向——所有内容均源自评论原文。
关键规则(请在第 1 步前阅读)
以下规则适用于所有步骤。违反任何一条都会导致自检(第 6 步)失败。
- 所有引用都必须逐字照录。 不得改述、纠正语法或清理文本。只能使用评论者的原话。
- 不得编造统计数据。 除非评论者明确使用过类似表述,否则不要写“快 40%”或“可靠性提高 2×”。自检步骤会检查未注明来源的百分比。
- 聚类名称必须使用评论者的语言。 请参阅第 3 步中的反面模式表。
- 每条标题和广告文案方向都必须注明其来源聚类。 格式:
[cluster: "cluster-name"]。 - 输出中始终必须包含第 2 部分——即使处于降级状态也不例外。绝不能跳过或省略。
- 生成的文案中不得出现以下禁用词: powerful、robust、seamless、innovative、game-changing、streamline、leverage、revolutionize、transform。
第 1 步 — 解析输入并检测平台
接受包含一个应用网址的自然语言提示。提取网址。
平台检测:
apps.apple.com→ App Storeplay.google.com/store/apps/details?id=→ Google Play- 任何其他网址 → 停止并回复:“请提供直接的 App Store 或 Google Play 网址。我无法分析其他来源的评论数据。”
提取 ID(调用脚本前完成):
| 平台 | 要提取的内容 | 方法 |
|---|---|---|
| App Store | 数字 app_id | 网址中 /id 后的数字 |
| App Store | country | apps.apple.com/ 后的 2 个字母代码(例如 us、gb) |
| Google Play | 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。)
此脚本会抓取应用商店的描述元数据和评论。
- App Store: iTunes API——免费,无需身份验证。App Store 评论通过 Apple 的公开 iTunes RSS feed 抓取。由于 Apple API 的限制,部分应用返回的评论数为 0——此时该技能会使用可用数据继续处理,并记录警告。Google Play 是主要支持的路径。
- Google Play:
google-play-scraper包——免费,无需身份验证
如果脚本失败,请从 stderr 读取错误信息。常见原因:
- 未安装软件包:运行
pip install google-play-scraper - 未找到应用:确认网址指向当前有效的应用页面
- Google Play API 错误:运行
pip install --upgrade google-play-scraper并重试
脚本会将收集进度打印到 stderr。请等待脚本运行完成。完成后,读取 {tmpdir}/asr-raw.json 并向用户展示收集摘要:
✓ Collected [N] reviews ([N] low-star 1–3★) from [platform]
Date range: [oldest] to [newest]
Package: [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:
review age ≤ 90 days → 1.0
review age 91–365 days → 0.7
review age > 365 days → 0.4
review age =(今天的日期)−(评价的 date 字段),单位为天。
cluster_score = 集群中所有评价的 complaint_weight 之和。
集群命名 — 关键规则:
你可能会想用抽象的名称。不要这样做。使用评价中的确切动词和名词。
| ❌ 抽象化(错误) | ✅ 评价者用语(正确) |
|---|---|
| “稳定性问题” | “导出 PDF 时崩溃” |
| “同步问题” | “手机和桌面端同步后数据丢失” |
| “付费障碍” | “承诺 14 天后才出现的付费墙,3 天后就出现了” |
| “性能下降” | “每次搜索时应用都会卡死” |
| “新手引导问题” | “不知道如何邀请队友” |
规则:
- 每条评价只能属于一个集群(分配到其主导主题)
- 丢弃少于 3 条评价的集群,并将其记录为噪声
- 每个集群选取 3–4 条原文引述:先按星级从低到高,再按时间从新到旧排序
关卡 2 — 最小集群规模: 丢弃少于 3 条评价的集群后,检查剩余集群的数量。
关卡 3 — 低置信度标记: 如果剩余集群少于 3 个:
- 不要停止。继续输出。
- 在简报标题中紧接应用元数据之后添加以下内容:
⚠ 低置信度: 只有 [N] 个投诉集群达到最低证据门槛(≥ 3 条支持评价)。输出反映的数据有限。请考虑选择评价更多的竞品,或扩大评分筛选范围。
- 在输出中包含中等层级的集群(分数 ≥ 5)
层级分类(用于第 1 节的排行榜表格):
- 严重:分数 ≥ 60
- 高:分数 15–59
- 中:分数 5–14(仅在适用关卡 3 时包含)
- 噪声:分数 < 5(丢弃,不要包含)
将集群写入 {tmpdir}/asr-clusters.json:
{
"clusters": [
{
"name": "cluster name in reviewer language",
"score": 34.5,
"tier": "High",
"review_count": 14,
"verbatim_quotes": [
{"rating": 1, "text": "exact reviewer words", "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 设为 false。按下方指定内容,将空的 broken_promises 数组和 detection_note 写入 {tmpdir}/asr-promises.json。继续执行第 5 步。
如果商店描述可用:
-
提取声明。 声明是对应用行为作出的任何具体、可验证的断言。完整定义和示例请参见
references/broken-promise.md。排除含糊的最高级描述、团队介绍和媒体引述。 -
交叉核对。 对每项声明,检查所有集群名称和原文引述。当集群直接记录了所承诺行为未能实现的情况(至少 3 条评价)时,即存在矛盾。
-
生成承诺落空记录 — 每项已确认的矛盾对应一条记录:
{ "claim_text": "verbatim excerpt from store description", "complaint_cluster": "exact cluster name", "gap_label": "Claims X; users report 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: "Store description unavailable (fetched YYYY-MM-DD, returned empty). Broken promise comparison cannot be performed." - 没有矛盾:
no_contradictions_found: true,detection_note: "No broken promises detected. Store description does not appear to overclaim relative to complaint clusters."
反模式(哪些内容不应标记)请参见 references/broken-promise.md。
步骤 5 — 生成文案
使用步骤 3 中的聚类和步骤 4 中未兑现的承诺,生成简报的第 3–5 节。
文案规则(适用于这三节):
- 每个标题和方向都必须注明来源聚类:
[cluster: "cluster-name"] - 禁用词:powerful、robust、seamless、innovative、game-changing、streamline、leverage、revolutionize、transform
- 不得捏造统计数据——除非评审者提及,否则不得使用百分比或数字
- 如果提供了
product_context:让“这样说”的方向具体体现该产品的功能。如果没有:写成由用户填写的定位模板。 - 标题中使用评审者的语言——从实际评审文本中提炼或引用
第 3 节 — 落地页 H1 标题库(3–5 个标题):
- 每个标题:
"[headline text]" [cluster: "cluster-name"] - 尽可能不超过 8 个词
- 直接面向感到沮丧的用户
第 4 节 — 广告文案方向(恰好 3 组):
Cluster: [cluster name]
Not that: "[what the competitor claims or a generic weak alternative]"
Say this: "[counter-claim grounded in complaint evidence]"
Evidence: [N] reviewers reported [verbatim complaint summary]
第 5 节 — 禁止性声明警示:
- 步骤 4 中每条未兑现的承诺对应一条警示
- 如果第 2 节已降级:添加一条说明(确切措辞见
references/brief-format.md)
步骤 6 — 自我质检
保存前,根据以下检查项核验生成的简报。如果有任何检查未通过,请修正对应内容并重新核验——不得保存未通过检查的简报。
| 检查项 | 规则 |
|---|---|
| 包含逐字引用 | 每个聚类至少包含 2 条逐字引用 |
| 不含禁用词 | 第 3–5 节均不含 9 个禁用词 |
| 不含未注明来源的百分比 | 输出中的任何 % 都必须能追溯到评审者的原话 |
| 所有文案均注明来源 | 每个标题和“这样说”都带有 [cluster: "name"] 引用 |
| 聚类数量 ≥ 1 | 至少有一个聚类通过第 2/3 道关卡 |
| 包含第 2 节 | 输出中包含第 2 节(无论其状态如何) |
| 引用评分 ≤ 3 | 所有逐字引用均来自评分为 1–3★ 的评审 |
**关于聚类数量的说明:**简报通过检查的最低要求是 1 个聚类(不是 3 个)。如果通过第 3 道关卡的聚类少于 3 个,第 3 道关卡的低置信度标记会对此进行提示——这是警告,不是失败。只有聚类数量为 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。