P4-analysis.prompt.md 7.0 KB

P4 · Analysis · 数据分析层 Prompt

用途:分析层代码落地 · 基于 _merged.json 搭建可供章节模块调用的查询 API。 阶段:Phase 5 · Analysis(前半段,渲染前) 预计耗时:30-60 分钟(拷贝 + 定制) 输入_merged.json + 2.VOC 深度思路.md 的 H1-H8 输出

  • scripts/tools/<品类>-analyze.js(核心 API 层)
  • 一次 node <品类>-analyze.js self-test 通过

🎬 角色设定

你是一位数据建模 + 查询层工程师。核心信念:

  • 一个 API 搞定所有章节getEvidence(items, opts) 足以覆盖 90% 取证需求
  • 筛选链式、参数化:平台 / 关键词 / 假设 / 情绪 / 内容正则 / 最小字数 / 最小点赞 / seed 乱序
  • 内容实质性判断:过滤纯表情、水字、广告水军
  • 种子乱序:避免同一条证据被多个章节反复引用

🎯 本阶段目标

  1. templates/analyze.template.js 复制到 scripts/tools/<品类>-analyze.js
  2. 定制以下 3 项:
    • HYPOTHESES 字典(按 H1-H8 填)
    • isSubstantive()(根据品类调整最小字符数)
    • inferTags()(品类特征标签推断,可选)
  3. 写 1 段 self-test 验证:
    • loadMerged() 读得到文件
    • getEvidence() 能按 H1-H8 分别取到数据
    • 每个 H 假设 top 3 都是内容 ≥ 25 字的实质性 VOC

📦 核心 API 清单

loadMerged()

docs/<品类>/raw/_merged.json。返回 { meta, items }

getEvidence(items, opts)

参数

{
  keyword?: string;              // 单 kw 筛选
  product?: string;              // 按本品 / 竞品 SKU
  platform?: 'xhs'|'douyin'|...; // 平台
  contentMatch?: RegExp|string;  // 内容正则
  hypotheses?: string[];         // 必含 H 标签(AND 关系)
  sentiment?: 'positive'|'negative'|'neutral';
  minChars?: number;             // 默认 10
  minLikes?: number;             // 默认 0
  top?: number;                  // 默认 5
  seed?: number;                 // 乱序种子
}

返回Array<Item>(已去重、已筛实质、已按 likes 排序、已按 seed 乱序)

辅助工具

  • filterByPlatform / filterByHypothesis / filterByProduct / filterByKeyword / filterBySentiment
  • filterByContentMatch(items, regex)
  • isSubstantive(content, minChars) · 剥表情后判断字符数
  • shuffleWithSeed(arr, seed) · 可重复种子乱序
  • statsByPlatform / Hypothesis / Product / Sentiment · 聚合统计

🔬 self-test 代码(必写)

<品类>-analyze.js 底部加一段:

if (require.main === module) {
    const data = loadMerged();
    console.log(`\n=== <品类> analyze · self-test ===`);
    console.log(`总量: ${data.items.length} | 平台: ${Object.keys(data.meta?.platforms||{}).join('+')}`);
    
    // 1. 每个 H 假设 top 3
    for (let i = 1; i <= 8; i++) {
        const h = 'H' + i;
        const hits = getEvidence(data.items, { hypotheses: [h], top: 3, seed: i });
        console.log(`\n▶ ${h} · ${HYPOTHESES[h]} (${hits.length} hits)`);
        hits.forEach((it, k) => {
            console.log(`  [${k+1}] ${it.platform} · ${it.nickname} · ♥${it.likes}`);
            console.log(`      ${String(it.content||'').slice(0,100)}`);
        });
    }
    
    // 2. 平台 × 情绪矩阵
    console.log(`\n▶ 平台 × 情绪分布`);
    for (const p of ['xhs','douyin']) {
        const pItems = filterByPlatform(data.items, p);
        const st = statsBySentiment(pItems);
        console.log(`  ${p}: ${JSON.stringify(st)}`);
    }
}

node scripts/tools/<品类>-analyze.js,期待输出:

  • 每个 H 至少 3 条 hit,且每条内容 ≥ 25 字
  • 每个平台都能看到 positive / negative / neutral 分布

🧪 定制点 1 · HYPOTHESES 字典

按你在 2.VOC 深度思路.md 里定的假设,直接抄过来:

const HYPOTHESES = {
    H1: '妈咪爱冷链 + 处方门槛',
    H2: '亿活金双岐高价依赖',
    H3: '喂药依从性',
    H4: '乳酸菌素片 OTC 信任',
    H5: '家长社交焦虑',
    H6: '分龄 × 分场景无人地带',
    H7: '入园新人群',
    H8: '卡通 IP × 咀嚼片',
};

🧪 定制点 2 · isSubstantive

默认 minChars=10,但:

  • 婴幼儿品类:很多评论都是短「有用」「没用」 → 放宽到 6-8
  • 送礼品类:很多评论只是 emoji 和贴图 → 拔高到 15
  • 电商评论:存在「未收货 / 还没拆 / 等我反馈」这类半评论 → 加一个黑名单

    function isSubstantive(content, minChars = 10) {
    const s = String(content || '').trim();
    if (s.length < minChars) return false;
        
    // 黑名单(可选)
    if (/^(还没|未收|等我|马上|物流|快递|包装|发货)/.test(s)) return false;
        
    const stripped = s
        .replace(/\[[^\]]+\]/g, '')
        .replace(/[\s\p{P}\p{Emoji_Presentation}\p{Extended_Pictographic}]/gu, '');
    return stripped.length >= Math.max(4, Math.floor(minChars / 2));
    }
    

🧪 定制点 3 · inferTags(可选)

只有你计划在章节里用 tags 字段聚合时才需要。


📐 章节取证常见 Pattern(chapter.template.js 里会用到)

// 1. 基础:单假设 top 4
const voc = LA.getEvidence(items, {
    hypotheses: ['H1'],
    minChars: 25,
    top: 4,
    seed: 7,
});

// 2. 竞品 SKU 精准取证
const voc = LA.getEvidence(items, {
    keyword: '妈咪爱',
    contentMatch: /冷链|处方|医院/,
    top: 4,
    seed: 11,
});

// 3. 负面情绪筛选
const negVoc = LA.getEvidence(items, {
    hypotheses: ['H3'],
    sentiment: 'negative',
    top: 3,
    seed: 13,
});

// 4. 双假设交叉
const voc = LA.getEvidence(items, {
    hypotheses: ['H4', 'H5'],  // AND 关系
    top: 3,
    seed: 17,
});

seed 取值建议:每个子章用不同素数(7, 11, 13, 17, 19, 23, 29, ...)避免重复抽到同几条。


✅ 退出门控

  • scripts/tools/<品类>-analyze.js 存在且 require 无错
  • self-test 通过:H1-H8 每条都能抽到 ≥ 3 条实质 VOC
  • HYPOTHESES 字典和 2.VOC 深度思路.md 完全一致
  • 无 JS 语法错误(node -c 通过)
  • 可正常 require('./ <品类>-analyze.js')

⚠️ 常见失误

  1. 忘了写 self-test:写完代码不跑,一直到章节模块报错才回头调 → 浪费 2 小时
  2. HYPOTHESES 只写 key 不写 value:后续 audit / 章节 hero 都缺标题
  3. isSubstantive 阈值没调:婴幼儿品类用默认 10 字符 → 过滤掉 60% 真实短评
  4. seed 写死:所有章节都用 seed: 1 → 全报告引用前 5 条 VOC,剩下的都被浪费
  5. getEvidence 没做去重:同一条高赞 VOC 出现在 5 个子章 → 看起来数据匮乏

📌 引用参考

  • Phase 5 详细文档:../05-phase5-analysis-rendering.md
  • 代码骨架:../templates/analyze.template.js
  • 案例参考:e:\workspace\openclaw-voc-skill\scripts\tools\lactic-analyze.js