smoke-cross-industry.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const path = require('path');
  4. const { runXiaohongshuTrend } = require('../mcp/src/tools/xiaohongshu-trend-run');
  5. const LEAK_TERMS = [
  6. '家装',
  7. '全屋定制',
  8. '奶油风',
  9. '开放格',
  10. '厨房橱柜',
  11. '衣柜',
  12. '小户型'
  13. ];
  14. const CASES = [
  15. {
  16. name: 'pet-food',
  17. profile: {
  18. project: '行业趋势情报官',
  19. industry: '宠物食品',
  20. businessType: '品牌方/电商/门店',
  21. targetAudience: ['养宠用户', '第一次养猫养狗的新手'],
  22. keywords: ['猫粮', '狗粮', '配料表', '试吃', '复购'],
  23. trendQuestions: ['用户最近在意哪些成分和适口性?', '什么话术最容易带来复购?', '哪些风险点会影响下单?'],
  24. mustTrackSignals: ['成分', '适口性', '复购', '价格', '口碑']
  25. }
  26. },
  27. {
  28. name: 'beauty-skincare',
  29. profile: {
  30. project: '行业趋势情报官',
  31. industry: '美妆护肤',
  32. businessType: '品牌方/测评账号/门店',
  33. targetAudience: ['护肤消费者', '敏感肌用户'],
  34. keywords: ['面霜', '防晒', '粉底液', '成分党', '测评'],
  35. trendQuestions: ['哪些护肤成分被反复讨论?', '用户最担心哪些翻车点?', '什么测评角度更容易转化?'],
  36. mustTrackSignals: ['成分', '肤感', '持妆', '价格', '复购']
  37. }
  38. },
  39. {
  40. name: 'baby-maternal',
  41. profile: {
  42. project: '行业趋势情报官',
  43. industry: '母婴用品',
  44. businessType: '品牌方/门店/内容账号',
  45. targetAudience: ['宝妈', '新生儿家庭'],
  46. keywords: ['纸尿裤', '辅食', '奶瓶', '婴儿湿巾', '新手妈妈'],
  47. trendQuestions: ['家长更在意什么安全和使用细节?', '哪些场景会触发购买?', '什么内容最能降低顾虑?'],
  48. mustTrackSignals: ['安全', '舒适', '分龄', '口碑', '售后']
  49. }
  50. },
  51. {
  52. name: 'education-training',
  53. profile: {
  54. project: '行业趋势情报官',
  55. industry: '教育培训',
  56. businessType: '机构/老师/内容账号',
  57. targetAudience: ['学生家长', '学习者'],
  58. keywords: ['课程', '试听', '提分', '学习方法', '规划'],
  59. trendQuestions: ['家长更担心哪些效果问题?', '什么样的课程表达更容易被信任?', '用户最在意的决策阻力是什么?'],
  60. mustTrackSignals: ['效果', '师资', '时间', '价格', '退费']
  61. }
  62. },
  63. {
  64. name: 'local-dining',
  65. profile: {
  66. project: '行业趋势情报官',
  67. industry: '本地生活餐饮',
  68. businessType: '门店/团购/探店账号',
  69. targetAudience: ['到店消费者', '团购用户'],
  70. keywords: ['探店', '套餐', '人均', '排队', '氛围'],
  71. trendQuestions: ['用户更在意口味还是性价比?', '什么门店体验会影响复购?', '哪些负面点最容易被评论放大?'],
  72. mustTrackSignals: ['口味', '服务', '排队', '环境', '复购']
  73. }
  74. }
  75. ];
  76. async function smokeCrossIndustry({ root = path.resolve(__dirname, '..') } = {}) {
  77. const outputRoot = path.join(root, 'outputs', 'claude-code-cross-industry-smoke');
  78. fs.mkdirSync(outputRoot, { recursive: true });
  79. const results = [];
  80. for (const item of CASES) {
  81. const result = await runXiaohongshuTrend({
  82. collectionMode: 'sample',
  83. output: path.join(outputRoot, item.name),
  84. cacheAssets: false,
  85. ...item.profile
  86. });
  87. if (result.status !== 'ok') {
  88. throw new Error(`${item.name} sample failed: ${result.status}`);
  89. }
  90. const body = String(result.assistantMessage || '');
  91. const leakHits = LEAK_TERMS.filter(term => body.includes(term));
  92. if (leakHits.length) {
  93. throw new Error(`${item.name} leaked house-specific terms: ${leakHits.join(', ')}`);
  94. }
  95. results.push({
  96. industry: item.profile.industry,
  97. preset: result.summary && result.summary.industryPreset,
  98. preview: body.split('\n').slice(0, 5).join('\n')
  99. });
  100. }
  101. return {
  102. status: 'ok',
  103. cases: results
  104. };
  105. }
  106. async function main() {
  107. const result = await smokeCrossIndustry();
  108. console.log(JSON.stringify(result, null, 2));
  109. }
  110. if (require.main === module) {
  111. main().catch(error => {
  112. console.error(JSON.stringify({ status: 'error', message: error.message }, null, 2));
  113. process.exit(1);
  114. });
  115. }
  116. module.exports = {
  117. smokeCrossIndustry
  118. };