App Store 评论套利
将竞争对手的 App Store 或 Google Play 链接转化为一次性 GTM 简报:排名投诉聚类、失信承诺地图、着陆页标题和广告文案方向——全部源自用户原话。
重要规则(阅读第一步前必读)
以下规则适用于所有步骤。违反任何一条都将导致步骤 6(自检)失败。
- 每条引用必须原封不动。 不能改写、不能纠正语法、不能清理。只使用审核者的原话。
- 不得编造统计数字。 除非审核者明确使用了类似语言,否则不要写“快 40%”或“可靠性提升 2 倍”。自检步骤会检查未注明来源的百分比。
- 聚类名称必须使用审核者语言。 学习步骤 3 中的反例表。
- 每条标题和广告文案方向都必须注明其来源聚类。 格式:
[cluster: "聚类名称"]。 - 输出中始终包含第 2 节——即使退化。永远不要跳过或省略它。
- 在任何生成的文案中不得出现禁用词: powerful、robust、seamless、innovative、game-changing、streamline、leverage、revolutionize、transform。
步骤 1 — 解析输入并检测平台
接受一个包含一个应用 URL 的自然语言提示。提取 URL。
平台检测:
apps.apple.com→ App Storeplay.google.com/store/apps/details?id=→ Google Play- 任何其他 URL → 停止并回复:“请提供一个直接的 App Store 或 Google Play 链接。我无法分析其他来源的评论数据。”
ID 提取(在调用脚本前执行):
| 平台 | 提取内容 | 方法 |
|---|---|---|
| App Store | 数字类型的 app_id | URL 中 /id 之后的数字 |
| App Store | country | apps.apple.com/ 后的两位字母代码(例如 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 - 未找到应用:验证 URL 是否为当前有效的列表页
- Google Play API 错误:运行
pip install --upgrade google-play-scraper并重试
脚本会将收集进度打印到 stderr。等待其完成。完成后,读取 {tmpdir}/asr-raw.json 并向用户显示收集摘要:
✓ 已收集 [N] 条评论(其中 [N] 条低星 1–3★)来自 [platform]
日期范围:[oldest] 到 [newest]
包:[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 - 评分) × recency_factor
recency_factor:
评论年龄 ≤ 90 天 → 1.0
评论年龄 91–365 天 → 0.7
评论年龄 > 365 天 → 0.4
评论年龄 = (今天的日期)−(评论 date 字段)的天数。
cluster_score = 集群中所有评论的 complaint_weight 总和。
聚类命名 — 关键规则:
你可能会想写抽象的名称。请抵制住这种冲动。使用评论中确切的动词和名词。
| ❌ 抽象化(错误) | ✅ 审核者语言(正确) |
|---|---|
| "稳定性问题" | "导出为 PDF 时崩溃" |
| "同步问题" | "手机与桌面同步后数据丢失" |
| "盈利摩擦" | "3 天后出现付费墙,并非承诺的 14 天" |
| "性能下降" | "每次搜索时应用都会卡死" |
| "上手问题" | "不知道如何邀请队友" |
规则:
- 每条评论只属于一个聚类(分配到其主要主题)
- 丢弃任何少于 3 条评论的聚类——将其记录为噪声
- 每个聚类选择 3–4 条原话引用:星级评分最低的排最前,然后是最新的
门限 2 — 最小聚类大小: 丢弃少于 3 条评论的聚类后,检查还剩多少个聚类。
门限 3 — 低置信度标志: 如果剩余聚类少于 3 个:
- 不要停止。继续输出。
- 在简报标题后、应用元数据之前立即添加:
⚠ 低置信度: 只有 [N] 个投诉聚类达到最低证据阈值(≥ 3 条支持评论)。输出反映数据有限。请考虑一个评论更多的竞品,或放宽评分过滤器。
- 在输出中包含 Medium 级别的聚类(评分 ≥ 5)
级别分类(用于第 1 节的排行榜表格):
- Critical:评分 ≥ 60
- High:评分 15–59
- Medium:评分 5–14(仅当门限 3 适用时包含)
- Noise:评分 < 5(丢弃,不包含)
将聚类写入 {tmpdir}/asr-clusters.json:
{
"clusters": [
{
"name": "审核者语言中的聚类名称",
"score": 34.5,
"tier": "High",
"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: "聚类名称"] - 无禁用词:powerful、robust、seamless、innovative、game-changing、streamline、leverage、revolutionize、transform
- 无编造统计数字——除非审核者使用了它们,否则不要出现百分比或数字
- 如果提供了
product_context:使“这样说”方向针对该产品的功能。如果没有:作为定位模板,由用户填写。 - 在标题中使用审核者语言——从实际审核文本中衍生或引用
第 3 节 — 着陆页 H1 银行(3–5 条标题):
- 每条:
"[标题文本]" [cluster: "聚类名称"] - 尽可能不超过 8 个词
- 直接面向沮丧的用户
第 4 节 — 广告文案方向(正好 3 对):
聚类:[聚类名称]
不是那样:"[竞品声称的内容或一个泛泛的弱替代方案]"
这样说:"[基于投诉证据的反声明]"
证据:[N] 位审核者报告了 [原话投诉摘要]
第 5 节 — 反承诺警告:
- 每项来自步骤 4 的失信承诺一条警告
- 如果第 2 节退化:单条说明(具体措辞见
references/brief-format.md)
步骤 6 — 自检
在保存之前,根据以下检查点验证生成的简报。如果任何检查点失败,请修复具体项并重新验证——不要保存失败的简报。
| 检查点 | 规则 |
|---|---|
| 原话引用存在 | 每个聚类至少有 ≥ 2 条原话引用 |
| 无禁用词 | 第 3–5 节中未出现 9 个禁用词中的任何一个 |
| 无未注明来源的百分比 | 输出中的任何 % 都必须追溯到审核者的实际用词 |
| 所有文案都已注明来源 | 每条标题和“这样说”都有 [cluster: "名称"] 的引用 |
| 聚类数量 ≥ 1 | 至少有一个聚类通过了门限 2/3 |
| 第 2 节存在 | 第 2 节出现在输出中(任何状态均可) |
| 引用评分 ≤ 3 | 所有原话引用均来自 1–3★ 的评论 |
关于聚类数量的说明: 通过简报的最低要求是 1 个聚类(而不是 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。