Skill: fyi0329-pixel/noodle-create-writing (version 1.0.0)

--- name: noodle-create-writing description: 自媒体文章生成技能 - 根据关键词自动搜索、汇总数据、生成抖音/小红书/微博文章，特别擅长美食（面食）主题 version: 1.0.0 author: 飞云儿 --- # 🍜 Noodle Create Writing - 自媒体文章生成技能 一个专门为美食（特别是面食）主题设计的自媒体文章生成技能。根据关键词自动搜索网页、汇总数据，生成适合抖音、小红书、微博平台的文章。 ## 🎯 功能特点 ### 核心功能 1. **智能搜索** - 使用Tavily API搜索最新、最相关的内容 2. **数据提取** - 从搜索结果中提取关键信息 3. **内容生成** - 根据平台特点生成不同风格的文章 4. **模板系统** - 提供各平台的文章模板 ### 支持平台 - **抖音** - 简短、吸引眼球、话题标签丰富 - **小红书** - 详细、实用、配图建议 - **微博** - 热点敏感、互动性强 ## 🚀 快速开始 ### 1. 安装依赖 ```bash cd noodle-create-writing npm install ``` ### 2. 环境变量配置 需要设置Tavily API密钥： ```bash export TAVILY_API_KEY="your_tavily_api_key" ``` ### 3. 基本使用 ```bash # 生成关于"春天苏式面"的文章 node scripts/generate-article.js "春天里的苏式面" --keywords "浇头,吃法,时间,地点,好处,文化" # 指定平台 node scripts/generate-article.js "主题" --platform douyin node scripts/generate-article.js "主题" --platform xiaohongshu node scripts/generate-article.js "主题" --platform weibo # 多平台生成 node scripts/generate-article.js "主题" --platform all ``` ## 📋 脚本说明 ### `scripts/generate-article.js` 主脚本，完整的工作流程： 1. 搜索相关信息 2. 提取关键数据 3. 生成文章内容 4. 保存到文件 ### `scripts/search-content.js` 搜索相关内容，支持： - 关键词搜索 - 时间范围限制 - 深度搜索模式 ### `scripts/extract-data.js` 从搜索结果中提取结构化数据： - 关键信息点 - 统计数据 - 引用来源 ### `scripts/format-article.js` 根据平台格式化文章： - 抖音：15秒文案格式 - 小红书：详细教程格式 - 微博：热点讨论格式 ## 🎨 文章模板 ### 抖音模板 (`templates/douyin-template.md`) - 15秒内可读完 - 使用热门话题标签 - 吸引眼球的标题 - 互动引导语 ### 小红书模板 (`templates/xiaohongshu-template.md`) - 详细步骤说明 - 实用技巧分享 - 配图建议 - 产品推荐 ### 微博模板 (`templates/weibo-template.md`) - 热点话题切入 - 数据支撑观点 - 互动问题设置 - 相关话题标签 ## 📊 工作流程 ```mermaid graph LR A[输入主题和关键词] --> B[搜索相关内容] B --> C[提取关键信息] C --> D{选择平台} D --> E[抖音格式] D --> F[小红书格式] D --> G[微博格式] E --> H[生成文章] F --> H G --> H H --> I[保存输出] ``` ## 🔧 高级选项 ### 搜索参数 ```bash # 限制搜索结果数量 node scripts/generate-article.js "主题" --search-count 10 # 限制时间范围（天） node scripts/generate-article.js "主题" --days 7 # 深度搜索模式 node scripts/generate-article.js "主题" --deep-search # 指定搜索主题 node scripts/generate-article.js "主题" --topic news ``` ### 输出控制 ```bash # 指定输出目录 node scripts/generate-article.js "主题" --output-dir ./articles # 仅生成不保存 node scripts/generate-article.js "主题" --dry-run # 显示详细过程 node scripts/generate-article.js "主题" --verbose ``` ## 🍜 美食主题专用功能 ### 面食相关关键词库 内置面食相关关键词，自动补充搜索： - 浇头/配料 - 汤底/汤头 - 面条类型 - 吃法/习俗 - 季节限定 - 地方特色 ### 文化内涵挖掘 自动挖掘美食背后的文化内涵： - 历史渊源 - 地方习俗 - 季节时令 - 健康养生 ## 📝 示例输出 ### 抖音示例 ``` 🍜 春天必吃！苏式面这样吃才地道！ #春天美食 #苏式面 #苏州美食 #时令美食 👉 三虾面、枫镇大肉面、鲜笋面 👉 早上6-8点头汤面最鲜 👉 松鹤楼、朱鸿兴老字号推荐 关注我，解锁更多春天美食攻略！👇 ``` ### 小红书示例 ``` #春天里的苏式面 #苏州美食攻略 #时令美食 春天来苏州，怎么能错过一碗地道的苏式面？作为苏州本地人，今天给大家分享春天吃苏式面的全攻略！ 🍜 浇头推荐（春天限定）： 1. 三虾面 - 虾仁+虾脑+虾籽，鲜掉眉毛 2. 鲜笋面 - 春笋最嫩的时候 3. 香椿面 - 春天的味道 ⏰ 最佳时间：早上6-8点，头汤面最鲜美 📍 老字号推荐： • 松鹤楼 - 环境优雅，可听评弹 • 朱鸿兴 - 本地人最爱 • 裕面堂 - 精品苏式面 📸 拍照Tips： • 拍汤面要体现"观音头、鲤鱼背" • 浇头特写展示食材新鲜度 • 环境照体现苏式园林风格 💡 文化内涵：苏式面讲究"不时不食"，春天吃鲜，体现苏州人精致生活态度。 收藏这篇，春天去苏州不迷路！🌸 ``` ### 微博示例 ``` #春天里的苏式面# #苏州美食# #时令饮食# 【春天吃苏式面，你吃对了吗？】 数据显示，苏州人春天最爱这三碗面： 1. 三虾面 - 虾肥籽饱的季节限定 2. 鲜笋面 - 春笋营养价值最高 3. 香椿面 - 只有春天才有的香气 文化内涵：苏式面体现苏州"不时不食"的饮食哲学，一碗面里藏着四季轮回。 🍜 投票：你春天最爱哪种苏式面？ A. 三虾面 B. 鲜笋面 C. 香椿面 D. 其他 👉 转发+评论，抽3位送苏州老字号面馆代金券！ #美食文化# #传统美食# #饮食养生# ``` ## 🔍 技术架构 ### 依赖技能 - `tavily-search` - AI优化搜索 - `summarize` - 内容总结（可选） ### 文件结构 ``` noodle-create-writing/ ├── SKILL.md ├── package.json ├── scripts/ │ ├── generate-article.js │ ├── search-content.js │ ├── extract-data.js │ └── format-article.js ├── templates/ │ ├── douyin-template.md │ ├── xiaohongshu-template.md │ └── weibo-template.md ├── keywords/ │ ├── noodle-keywords.json │ └── culture-keywords.json └── examples/ ├── douyin-example.md ├── xiaohongshu-example.md └── weibo-example.md ``` ## 🛠️ 故障排除 ### 常见问题 1. **搜索无结果** - 检查API密钥，尝试简化关键词 2. **内容重复** - 使用`--deep-search`获取更多样化结果 3. **生成质量低** - 提供更具体的关键词，使用`--verbose`查看过程 ### 性能优化 - 搜索结果缓存 - 并行处理多个关键词 - 增量更新已有内容 ## 📈 未来计划 ### 功能增强 - [ ] 支持图片生成建议 - [ ] 视频脚本生成 - [ ] 多语言支持 - [ ] 自动发布到平台API ### 主题扩展 - [ ] 其他美食类别 - [ ] 旅游攻略 - [ ] 生活技巧 - [ ] 健康养生 ## 📚 相关资源 - [Tavily API文档](https://tavily.com) - [OpenClaw技能开发指南](https://docs.openclaw.ai) - [自媒体内容创作指南](https://weibo.com) --- **开始创作你的第一篇美食自媒体文章吧！** 🍜✨

path: examples/douyin-example.md
content: 🍜 春天里的苏式面这样吃才地道！

👉 浇头推荐：三虾面、鲜笋面、香椿面
👉 最佳时间：早上6-8点头汤面最鲜
👉 老字号推荐：松鹤楼、朱鸿兴
👉 必尝：春天限定的三虾面
👉 小贴士：讲究"不时不食"，春天吃鲜

#春天里的苏式面 #苏州美食 #时令美食 #美食教程 #地方美食 #浇头 #春季美食 #传统美食

关注我，解锁更多春天美食攻略！👇

path: examples/weibo-example.md
content: #春天里的苏式面# #苏州美食# #时令饮食# #传统美食# #美食文化# #饮食养生# #非遗美食#

【春天里的苏式面，你吃对了吗？】

数据显示，苏州人春天最爱这三碗面：
1. 三虾面 - 虾肥籽饱的季节限定
2. 鲜笋面 - 春笋营养价值最高
3. 香椿面 - 只有春天才有的香气

季节特色：春季食材新鲜，讲究"不时不食"

文化内涵：苏式面体现苏州"不时不食"的饮食哲学，一碗面里藏着四季轮回，是非遗美食的重要代表。

健康好处：春季苏式面选用时令食材，营养丰富，易于消化，符合春季养生的需求。

老字号推荐：松鹤楼、朱鸿兴、同得兴

📊 数据支撑：基于10个权威来源，相关性评分85/100

🍜 投票：你春天最爱哪种苏式面？
A. 三虾面
B. 鲜笋面  
C. 香椿面
D. 其他春季限定

👉 转发+评论，抽3位送苏州老字号面馆代金券！

#美食文化# #传统美食# #饮食养生# #春季养生# #苏州旅游#

path: examples/xiaohongshu-example.md
content: #春天里的苏式面 #美食攻略 #时令美食

春天来苏州，怎么能错过一碗地道的苏式面？作为苏州本地人，今天给大家分享春天吃苏式面的全攻略！

🍜 浇头推荐（春天限定）：
• 三虾面 - 虾仁+虾脑+虾籽，鲜掉眉毛
• 鲜笋面 - 春笋最嫩的时候
• 香椿面 - 春天的味道
• 爆鳝面 - 春季鳝鱼最肥美
• 青团子面 - 清明时节特色

⏰ 最佳时间：早上6-8点，头汤面最鲜美

📍 老字号推荐：
• 松鹤楼 - 环境优雅，可听评弹
• 朱鸿兴 - 本地人最爱
• 裕面堂 - 精品苏式面
• 同得兴 - 传统奥灶面
• 陆长兴 - 老字号面馆

🎯 吃法讲究：
• 宽汤 - 汤多些
• 紧汤 - 汤少些  
• 重青 - 多放葱蒜
• 免青 - 不放葱蒜
• 过桥 - 浇头分开装

💪 健康好处：
• 富含蛋白质和碳水化合物
• 春季食材新鲜营养
• 有助于消化吸收
• 体现"不时不食"养生理念

📚 文化内涵：
• 苏式面体现苏州人精致生活
• "不时不食"的饮食哲学
• 一碗面里藏着四季轮回
• 非遗美食的文化传承

📸 拍照Tips：
• 拍汤面要体现"观音头、鲤鱼背"
• 浇头特写展示食材新鲜度
• 环境照体现苏式园林风格
• 制作过程展现传统技艺

#春天里的苏式面 #苏州美食攻略 #吃货日常 #地方美食 #传统美食 #时令美食 #春季限定 #美食文化 #非遗美食 #健康饮食

收藏这篇，春天去苏州不迷路！🌟

path: keywords/noodle-keywords.json
content: {
  "toppings": [
    "焖肉", "爆鱼", "爆鳝", "虾仁", "卤鸭", "大排", "炒素", "三虾", "蟹粉", "秃黄油",
    "枫镇大肉", "鳝糊", "雪菜肉丝", "辣肉", "素鸡", "烤麸", "面筋", "熏鱼", "酱鸭",
    "咸菜肉丝", "青椒肉丝", "鱼香肉丝", "宫保鸡丁", "回锅肉", "红烧肉", "糖醋排骨",
    "狮子头", "腌笃鲜", "油面筋塞肉", "百叶包", "蛋饺", "肉圆", "鱼圆", "虾球"
  ],
  
  "soupBases": [
    "红汤", "白汤", "清汤", "浓汤", "高汤", "原汤", "骨汤", "鸡汤", "鱼汤",
    "海鲜汤", "菌菇汤", "蔬菜汤", "麻辣汤", "酸辣汤", "番茄汤", "咖喱汤",
    "药膳汤", "养生汤", "滋补汤", "老火汤"
  ],
  
  "noodleTypes": [
    "细面", "宽面", "拉面", "刀削面", "手擀面", "机制面", "鸡蛋面", "蔬菜面",
    "杂粮面", "荞麦面", "乌冬面", "米粉", "米线", "粉丝", "河粉", "粿条",
    "意面", "通心粉", "面线", "挂面", "方便面", "速食面"
  ],
  
  "eatingMethods": [
    "宽汤", "紧汤", "重青", "免青", "过桥", "头汤面", "拌面", "汤面",
    "炒面", "烩面", "捞面", "凉面", "热干面", "炸酱面", "打卤面",
    "盖浇面", "浇头面", "臊子面", "码子面", "配菜面", "自助面"
  ],
  
  "seasonal": [
    "春季", "夏季", "秋季", "冬季", "春天", "夏天", "秋天", "冬天",
    "时令", "季节", "限定", "当季", "应季", "反季", "旺季", "淡季",
    "清明", "立夏", "立秋", "立冬", "春分", "秋分", "夏至", "冬至"
  ],
  
  "regional": [
    "苏州", "上海", "杭州", "南京", "无锡", "常州", "镇江", "扬州",
    "南通", "泰州", "盐城", "淮安", "宿迁", "连云港", "徐州", "合肥",
    "宁波", "温州", "绍兴", "嘉兴", "湖州", "金华", "衢州", "台州",
    "丽水", "舟山", "福建", "广东", "四川", "湖南", "湖北", "陕西"
  ],
  
  "healthBenefits": [
    "蛋白质", "碳水化合物", "膳食纤维", "维生素", "矿物质", "氨基酸",
    "低脂肪", "低热量", "高蛋白", "易消化", "养胃", "健脾", "补肾",
    "补血", "补气", "滋阴", "壮阳", "清热解毒", "祛湿", "化痰",
    "止咳", "润肺", "养肝", "明目", "安神", "助眠", "抗衰老",
    "抗氧化", "增强免疫力", "促进消化", "降低胆固醇", "控制血糖"
  ],
  
  "cultural": [
    "文化", "历史", "传统", "民俗", "非遗", "遗产", "渊源", "起源",
    "发展", "演变", "传承", "创新", "融合", "交流", "影响", "意义",
    "价值", "内涵", "精神", "哲学", "艺术", "美学", "礼仪", "习俗",
    "节日", "庆典", "祭祀", "宴会", "家常", "待客", "商务", "社交"
  ],
  
  "restaurants": [
    "松鹤楼", "朱鸿兴", "同得兴", "裕面堂", "陆长兴", "黄天源",
    "得月楼", "苏州面馆", "老苏州", "苏州饭店", "观振兴", "五芳斋",
    "绿杨邨", "王家沙", "沈大成", "杏花楼", "新雅", "老正兴",
    "功德林", "松月楼", "春风松月楼", "老半斋", "沧浪亭", "吴苑",
    "鸿兴馆", "王兴记", "熙盛源", "灵山素面", "寒山寺素面", "西园寺素面"
  ],
  
  "cookingMethods": [
    "煮", "炖", "烩", "炒", "炸", "蒸", "烤", "煎", "烙", "涮",
    "烫", "拌", "腌", "卤", "酱", "熏", "腊", "风干", "烘干",
    "发酵", "腌制", "泡制", "糟制", "醉制", "糖渍", "盐渍", "醋泡"
  ],
  
  "tasteProfiles": [
    "鲜", "香", "甜", "咸", "酸", "辣", "苦", "麻", "涩", "醇",
    "厚", "薄", "浓", "淡", "清", "爽", "滑", "嫩", "脆", "酥",
    "软", "糯", "韧", "劲", "弹", "Q", "爽口", "入味", "回味",
    "余味", "层次", "丰富", "单一", "平衡", "协调", "突出", "鲜明"
  ]
}

path: package.json
content: {
  "name": "noodle-create-writing",
  "version": "1.0.0",
  "description": "自媒体文章生成技能 - 根据关键词自动搜索、汇总数据、生成抖音/小红书/微博文章",
  "main": "scripts/generate-article.js",
  "scripts": {
    "start": "node scripts/generate-article.js",
    "test": "node scripts/generate-article.js \"测试主题\" --keywords \"测试\" --dry-run",
    "douyin": "node scripts/generate-article.js",
    "xiaohongshu": "node scripts/generate-article.js --platform xiaohongshu",
    "weibo": "node scripts/generate-article.js --platform weibo"
  },
  "keywords": [
    "自媒体",
    "文章生成",
    "美食",
    "面食",
    "抖音",
    "小红书",
    "微博",
    "内容创作"
  ],
  "author": "飞云儿",
  "license": "MIT",
  "dependencies": {
    "axios": "^1.6.0",
    "cheerio": "^1.0.0",
    "marked": "^12.0.0",
    "yargs": "^17.7.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}

path: scripts/extract-data.js
content: /**
 * 提取关键数据模块
 * 从搜索结果中提取结构化数据
 */

/**
 * 从搜索结果中提取关键数据
 * @param {Object} searchResults 搜索结果
 * @param {Object} options 选项
 * @returns {Object} 提取的结构化数据
 */
function extractData(searchResults, options = {}) {
  const { topic, verbose = false } = options;
  
  const sources = searchResults.sources || [];
  const summary = searchResults.summary || '';
  
  if (verbose) {
    console.log(`📊 处理 ${sources.length} 个来源`);
  }
  
  // 初始化数据结构
  const data = {
    topic,
    basicInfo: {
      description: '',
      characteristics: [],
      history: ''
    },
    categories: {
      toppings: [],      // 浇头
      soupBases: [],     // 汤底
      noodleTypes: [],   // 面条类型
      eatingMethods: [], // 吃法
      seasonal: [],      // 季节限定
      regional: [],      // 地方特色
      healthBenefits: [], // 健康好处
      cultural: []       // 文化内涵
    },
    recommendations: {
      bestTime: '',      // 最佳时间
      bestPlaces: [],    // 推荐地点
      mustTry: [],       // 必尝推荐
      tips: []           // 小贴士
    },
    statistics: {
      sourceCount: sources.length,
      topSources: [],
      relevanceScore: 0
    },
    quotes: [],          // 引用语句
    keywords: searchResults.keywords || []
  };
  
  // 处理每个来源
  for (const source of sources) {
    const content = (source.content || '').toLowerCase();
    const title = (source.title || '').toLowerCase();
    
    // 提取基本信息
    extractBasicInfo(data, content, title, source);
    
    // 提取分类信息
    extractCategoryInfo(data, content, title);
    
    // 提取推荐信息
    extractRecommendationInfo(data, content, title);
    
    // 收集引用
    if (source.content && source.content.length > 20 && source.content.length < 200) {
      data.quotes.push({
        text: source.content.trim(),
        source: source.title,
        url: source.url
      });
    }
  }
  
  // 处理总结
  if (summary) {
    data.basicInfo.description = summary;
  }
  
  // 去重和排序
  processExtractedData(data);
  
  // 计算相关性分数
  data.statistics.relevanceScore = calculateRelevanceScore(data, sources);
  
  // 选择最重要的来源
  data.statistics.topSources = sources
    .slice(0, 5)
    .map(s => ({ title: s.title, url: s.url, relevance: s.relevance }));
  
  if (verbose) {
    console.log('✅ 数据提取完成');
    console.log(`📈 提取到：${data.categories.toppings.length} 种浇头，${data.recommendations.bestPlaces.length} 个推荐地点`);
  }
  
  return data;
}

/**
 * 提取基本信息
 */
function extractBasicInfo(data, content, title, source) {
  // 提取描述
  if (!data.basicInfo.description && content.length > 50) {
    const sentences = content.split(/[.!?。！？]/);
    if (sentences[0] && sentences[0].length > 20) {
      data.basicInfo.description = sentences[0].trim();
    }
  }
  
  // 提取特点
  const characteristicKeywords = ['特点', '特色', '特征', '独特', '与众不同'];
  if (characteristicKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (characteristicKeywords.some(keyword => line.includes(keyword)) && line.length > 10) {
        data.basicInfo.characteristics.push(line.trim());
      }
    }
  }
  
  // 提取历史
  const historyKeywords = ['历史', '由来', '起源', '传统', '古老', '百年'];
  if (historyKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (historyKeywords.some(keyword => line.includes(keyword)) && line.length > 15) {
        if (!data.basicInfo.history) {
          data.basicInfo.history = line.trim();
        }
      }
    }
  }
}

/**
 * 提取分类信息
 */
function extractCategoryInfo(data, content, title) {
  // 浇头提取
  const toppingKeywords = ['浇头', '配料', '臊子', '码子', 'topping'];
  const toppingItems = ['焖肉', '爆鱼', '爆鳝', '虾仁', '卤鸭', '大排', '炒素', '三虾', '蟹粉', '秃黄油'];
  
  if (toppingKeywords.some(keyword => content.includes(keyword))) {
    for (const item of toppingItems) {
      if (content.includes(item.toLowerCase())) {
        data.categories.toppings.push(item);
      }
    }
  }
  
  // 汤底提取
  const soupKeywords = ['汤', '汤底', '汤头', '高汤', 'soup'];
  const soupTypes = ['红汤', '白汤', '清汤', '浓汤'];
  
  if (soupKeywords.some(keyword => content.includes(keyword))) {
    for (const type of soupTypes) {
      if (content.includes(type.toLowerCase())) {
        data.categories.soupBases.push(type);
      }
    }
  }
  
  // 吃法提取
  const eatingKeywords = ['吃法', '怎么吃', '如何吃', '吃的方式', 'eating method'];
  const eatingMethods = ['宽汤', '紧汤', '重青', '免青', '过桥', '头汤面'];
  
  if (eatingKeywords.some(keyword => content.includes(keyword))) {
    for (const method of eatingMethods) {
      if (content.includes(method.toLowerCase())) {
        data.categories.eatingMethods.push(method);
      }
    }
  }
  
  // 季节限定提取
  const seasonalKeywords = ['季节', '时令', '春季', '夏季', '秋季', '冬季', 'seasonal'];
  if (seasonalKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (seasonalKeywords.some(keyword => line.includes(keyword)) && line.length > 10) {
        data.categories.seasonal.push(line.trim());
      }
    }
  }
  
  // 健康好处提取
  const healthKeywords = ['健康', '营养', '养生', '好处', '功效', 'health', 'benefit'];
  if (healthKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (healthKeywords.some(keyword => line.includes(keyword)) && line.length > 10) {
        data.categories.healthBenefits.push(line.trim());
      }
    }
  }
  
  // 文化内涵提取
  const cultureKeywords = ['文化', '内涵', '历史', '传统', '民俗', 'culture'];
  if (cultureKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (cultureKeywords.some(keyword => line.includes(keyword)) && line.length > 15) {
        data.categories.cultural.push(line.trim());
      }
    }
  }
}

/**
 * 提取推荐信息
 */
function extractRecommendationInfo(data, content, title) {
  // 最佳时间提取
  const timeKeywords = ['时间', '时候', '时机', '最佳时间', '最好吃', 'time', 'best time'];
  if (timeKeywords.some(keyword => content.includes(keyword)) && !data.recommendations.bestTime) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (timeKeywords.some(keyword => line.includes(keyword)) && line.length > 8) {
        data.recommendations.bestTime = line.trim();
        break;
      }
    }
  }
  
  // 推荐地点提取
  const placeKeywords = ['地方', '地点', '店铺', '面馆', '老字号', '推荐', 'place', 'restaurant'];
  const placeNames = ['松鹤楼', '朱鸿兴', '同得兴', '裕面堂', '陆长兴', '黄天源'];
  
  if (placeKeywords.some(keyword => content.includes(keyword))) {
    for (const place of placeNames) {
      if (content.includes(place.toLowerCase())) {
        data.recommendations.bestPlaces.push(place);
      }
    }
  }
  
  // 必尝推荐提取
  const mustTryKeywords = ['必吃', '必尝', '推荐', '招牌', '特色', 'must try'];
  if (mustTryKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (mustTryKeywords.some(keyword => line.includes(keyword)) && line.length > 8) {
        data.recommendations.mustTry.push(line.trim());
      }
    }
  }
  
  // 小贴士提取
  const tipsKeywords = ['贴士', '技巧', '注意', '建议', 'tip', 'advice'];
  if (tipsKeywords.some(keyword => content.includes(keyword))) {
    const lines = content.split(/[.!?。！？]/);
    for (const line of lines) {
      if (tipsKeywords.some(keyword => line.includes(keyword)) && line.length > 8) {
        data.recommendations.tips.push(line.trim());
      }
    }
  }
}

/**
 * 处理提取的数据（去重、排序等）
 */
function processExtractedData(data) {
  // 去重
  for (const category in data.categories) {
    data.categories[category] = [...new Set(data.categories[category])];
  }
  
  data.recommendations.bestPlaces = [...new Set(data.recommendations.bestPlaces)];
  data.recommendations.mustTry = [...new Set(data.recommendations.mustTry)];
  data.recommendations.tips = [...new Set(data.recommendations.tips)];
  
  // 限制数量
  data.categories.toppings = data.categories.toppings.slice(0, 10);
  data.categories.soupBases = data.categories.soupBases.slice(0, 5);
  data.categories.eatingMethods = data.categories.eatingMethods.slice(0, 8);
  data.categories.seasonal = data.categories.seasonal.slice(0, 5);
  data.categories.healthBenefits = data.categories.healthBenefits.slice(0, 5);
  data.categories.cultural = data.categories.cultural.slice(0, 5);
  
  data.recommendations.bestPlaces = data.recommendations.bestPlaces.slice(0, 8);
  data.recommendations.mustTry = data.recommendations.mustTry.slice(0, 5);
  data.recommendations.tips = data.recommendations.tips.slice(0, 5);
  
  // 排序（按长度或重要性）
  data.categories.toppings.sort();
  data.recommendations.bestPlaces.sort();
}

/**
 * 计算相关性分数
 */
function calculateRelevanceScore(data, sources) {
  if (sources.length === 0) return 0;
  
  let score = 0;
  
  // 基础分数：来源数量和质量
  score += Math.min(sources.length, 10) * 5;
  
  // 数据丰富度分数
  const dataPoints = 
    data.categories.toppings.length +
    data.categories.soupBases.length +
    data.categories.eatingMethods.length +
    data.recommendations.bestPlaces.length +
    data.categories.healthBenefits.length +
    data.categories.cultural.length;
  
  score += Math.min(dataPoints, 20) * 2;
  
  // 关键信息完整性分数
  if (data.basicInfo.description) score += 10;
  if (data.recommendations.bestTime) score += 5;
  if (data.basicInfo.history) score += 5;
  if (data.categories.cultural.length > 0) score += 5;
  
  return Math.min(score, 100);
}

module.exports = { extractData };

path: scripts/format-article.js
content: /**
 * 格式化文章模块
 * 根据平台特点格式化文章内容
 */

/**
 * 根据平台格式化文章
 * @param {Object} data 提取的数据
 * @param {string} platform 平台：douyin, xiaohongshu, weibo
 * @returns {string} 格式化后的文章
 */
function formatArticle(data, platform) {
  switch (platform) {
    case 'douyin':
      return formatDouyinArticle(data);
    case 'xiaohongshu':
      return formatXiaohongshuArticle(data);
    case 'weibo':
      return formatWeiboArticle(data);
    default:
      return formatGenericArticle(data);
  }
}

/**
 * 格式化抖音文章
 */
function formatDouyinArticle(data) {
  const { topic, basicInfo, categories, recommendations } = data;
  
  // 生成吸引眼球的标题
  const title = generateDouyinTitle(topic, basicInfo);
  
  // 生成话题标签
  const hashtags = generateDouyinHashtags(topic, categories);
  
  // 生成正文内容（15秒内可读完）
  const content = generateDouyinContent(data);
  
  // 生成互动引导语
  const callToAction = generateDouyinCallToAction();
  
  return `${title}\n\n${content}\n\n${hashtags}\n\n${callToAction}`;
}

/**
 * 格式化小红书文章
 */
function formatXiaohongshuArticle(data) {
  const { topic, basicInfo, categories, recommendations, quotes } = data;
  
  // 生成标题和话题标签
  const title = `#${topic.replace(/\s+/g, '')} #美食攻略 #时令美食`;
  const hashtags = generateXiaohongshuHashtags(topic, categories);
  
  // 生成正文
  const content = generateXiaohongshuContent(data);
  
  // 生成拍照建议
  const photoTips = generatePhotoTips();
  
  // 生成收藏引导
  const savePrompt = generateSavePrompt();
  
  return `${title}\n\n${content}\n\n${photoTips}\n\n${hashtags}\n\n${savePrompt}`;
}

/**
 * 格式化微博文章
 */
function formatWeiboArticle(data) {
  const { topic, basicInfo, categories, recommendations, statistics } = data;
  
  // 生成话题标签
  const hashtags = generateWeiboHashtags(topic);
  
  // 生成标题
  const title = `【${topic}，你了解多少？】`;
  
  // 生成正文（热点讨论风格）
  const content = generateWeiboContent(data);
  
  // 生成互动元素
  const interaction = generateWeiboInteraction(topic);
  
  // 生成数据支撑
  const dataSupport = generateDataSupport(statistics);
  
  return `${hashtags}\n\n${title}\n\n${content}\n\n${dataSupport}\n\n${interaction}`;
}

/**
 * 生成通用文章
 */
function formatGenericArticle(data) {
  const { topic, basicInfo, categories, recommendations } = data;
  
  return `# ${topic}

## 基本信息
${basicInfo.description || '暂无描述'}

${basicInfo.history ? `## 历史渊源\n${basicInfo.history}\n` : ''}

## 主要特点
${basicInfo.characteristics.length > 0 ? basicInfo.characteristics.map(c => `- ${c}`).join('\n') : '暂无特点描述'}

## 分类信息
${Object.entries(categories)
  .filter(([_, items]) => items.length > 0)
  .map(([category, items]) => `### ${getCategoryName(category)}\n${items.map(item => `- ${item}`).join('\n')}`)
  .join('\n\n')}

## 推荐信息
${recommendations.bestTime ? `### 最佳时间\n${recommendations.bestTime}\n` : ''}
${recommendations.bestPlaces.length > 0 ? `### 推荐地点\n${recommendations.bestPlaces.map(p => `- ${p}`).join('\n')}\n` : ''}
${recommendations.mustTry.length > 0 ? `### 必尝推荐\n${recommendations.mustTry.map(m => `- ${m}`).join('\n')}\n` : ''}
${recommendations.tips.length > 0 ? `### 小贴士\n${recommendations.tips.map(t => `- ${t}`).join('\n')}\n` : ''}

---
*文章基于${statistics?.sourceCount || 0}个来源生成，相关性评分：${statistics?.relevanceScore || 0}/100*`;
}

/**
 * 生成抖音标题
 */
function generateDouyinTitle(topic, basicInfo) {
  const emojis = ['🍜', '✨', '🌟', '💫', '🔥', '👍', '👑'];
  const emoji = emojis[Math.floor(Math.random() * emojis.length)];
  
  const titleTemplates = [
    `${emoji} ${topic}这样吃才地道！`,
    `${emoji} 揭秘${topic}的正确打开方式`,
    `${emoji} ${topic}｜本地人才知道的吃法`,
    `${emoji} 春天必吃！${topic}攻略`,
    `${emoji} ${topic}｜吃货必备指南`
  ];
  
  return titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
}

/**
 * 生成抖音内容
 */
function generateDouyinContent(data) {
  const { categories, recommendations } = data;
  
  const contentParts = [];
  
  // 浇头推荐
  if (categories.toppings.length > 0) {
    const toppings = categories.toppings.slice(0, 3).join('、');
    contentParts.push(`👉 浇头推荐：${toppings}`);
  }
  
  // 最佳时间
  if (recommendations.bestTime) {
    contentParts.push(`👉 最佳时间：${recommendations.bestTime}`);
  }
  
  // 推荐地点
  if (recommendations.bestPlaces.length > 0) {
    const places = recommendations.bestPlaces.slice(0, 2).join('、');
    contentParts.push(`👉 老字号推荐：${places}`);
  }
  
  // 必尝推荐
  if (recommendations.mustTry.length > 0) {
    const mustTry = recommendations.mustTry[0];
    contentParts.push(`👉 必尝：${mustTry}`);
  }
  
  // 小贴士
  if (recommendations.tips.length > 0) {
    const tip = recommendations.tips[0];
    contentParts.push(`👉 小贴士：${tip}`);
  }
  
  return contentParts.join('\n');
}

/**
 * 生成抖音话题标签
 */
function generateDouyinHashtags(topic, categories) {
  const baseHashtags = [
    `#${topic}`,
    '#美食',
    '#吃货',
    '#美食教程',
    '#地方美食'
  ];
  
  const specificHashtags = [];
  
  // 根据分类添加标签
  if (categories.toppings.length > 0) {
    specificHashtags.push('#浇头', '#配料');
  }
  
  if (categories.seasonal.length > 0) {
    specificHashtags.push('#时令美食', '#春季美食');
  }
  
  if (categories.cultural.length > 0) {
    specificHashtags.push('#美食文化', '#传统美食');
  }
  
  // 合并并限制数量
  const allHashtags = [...baseHashtags, ...specificHashtags];
  return allHashtags.slice(0, 8).join(' ');
}

/**
 * 生成抖音互动引导语
 */
function generateDouyinCallToAction() {
  const ctas = [
    '关注我，解锁更多美食攻略！👇',
    '点赞收藏，下次不迷路！❤️',
    '评论区告诉我你想看哪个城市的美食攻略！💬',
    '转发给爱吃面的朋友！👯‍♀️',
    '下期想看什么美食？留言告诉我！📝'
  ];
  
  return ctas[Math.floor(Math.random() * ctas.length)];
}

/**
 * 生成小红书内容
 */
function generateXiaohongshuContent(data) {
  const { topic, basicInfo, categories, recommendations } = data;
  
  const sections = [];
  
  // 引言
  sections.push(`${topic}，作为传统美食的代表，今天给大家分享全攻略！`);
  
  // 浇头推荐
  if (categories.toppings.length > 0) {
    sections.push(`🍜 浇头推荐（精选）：\n${categories.toppings.slice(0, 5).map(t => `• ${t}`).join('\n')}`);
  }
  
  // 最佳时间
  if (recommendations.bestTime) {
    sections.push(`⏰ 最佳时间：${recommendations.bestTime}`);
  }
  
  // 老字号推荐
  if (recommendations.bestPlaces.length > 0) {
    sections.push(`📍 老字号推荐：\n${recommendations.bestPlaces.slice(0, 5).map(p => `• ${p}`).join('\n')}`);
  }
  
  // 吃法讲究
  if (categories.eatingMethods.length > 0) {
    sections.push(`🎯 吃法讲究：\n${categories.eatingMethods.slice(0, 3).map(m => `• ${m}`).join('\n')}`);
  }
  
  // 健康好处
  if (categories.healthBenefits.length > 0) {
    sections.push(`💪 健康好处：\n${categories.healthBenefits.slice(0, 3).map(h => `• ${h}`).join('\n')}`);
  }
  
  // 文化内涵
  if (categories.cultural.length > 0) {
    sections.push(`📚 文化内涵：\n${categories.cultural.slice(0, 2).map(c => `• ${c}`).join('\n')}`);
  }
  
  return sections.join('\n\n');
}

/**
 * 生成小红书话题标签
 */
function generateXiaohongshuHashtags(topic, categories) {
  const baseHashtags = [
    `#${topic.replace(/\s+/g, '')}`,
    '#美食攻略',
    '#吃货日常',
    '#地方美食',
    '#传统美食'
  ];
  
  const specificHashtags = [];
  
  // 添加分类相关标签
  if (categories.seasonal.length > 0) {
    specificHashtags.push('#时令美食', '#春季限定');
  }
  
  if (categories.cultural.length > 0) {
    specificHashtags.push('#美食文化', '#非遗美食');
  }
  
  if (categories.healthBenefits.length > 0) {
    specificHashtags.push('#健康饮食', '#养生美食');
  }
  
  // 合并
  return [...baseHashtags, ...specificHashtags].slice(0, 10).join(' ');
}

/**
 * 生成拍照建议
 */
function generatePhotoTips() {
  return `📸 拍照Tips：
• 拍汤面要体现"观音头、鲤鱼背"
• 浇头特写展示食材新鲜度
• 环境照体现传统风格
• 人物互动增加生活感`;
}

/**
 * 生成收藏引导
 */
function generateSavePrompt() {
  const prompts = [
    '收藏这篇，下次去不迷路！🌟',
    '点赞收藏，美食攻略不丢失！❤️',
    '关注我，更多美食攻略持续更新！👉',
    '转发给朋友，一起打卡美食！👯‍♀️'
  ];
  
  return prompts[Math.floor(Math.random() * prompts.length)];
}

/**
 * 生成微博内容
 */
function generateWeiboContent(data) {
  const { topic, basicInfo, categories, recommendations } = data;
  
  const sections = [];
  
  // 数据开场
  if (categories.toppings.length > 0) {
    sections.push(`数据显示，${topic}最受欢迎的浇头有：${categories.toppings.slice(0, 3).join('、')}`);
  }
  
  // 季节特色
  if (categories.seasonal.length > 0) {
    sections.push(`季节特色：${categories.seasonal[0]}`);
  }
  
  // 文化内涵
  if (categories.cultural.length > 0) {
    sections.push(`文化内涵：${categories.cultural[0]}`);
  }
  
  // 健康好处
  if (categories.healthBenefits.length > 0) {
    sections.push(`健康好处：${categories.healthBenefits[0]}`);
  }
  
  // 老字号推荐
  if (recommendations.bestPlaces.length > 0) {
    sections.push(`老字号推荐：${recommendations.bestPlaces.slice(0, 2).join('、')}`);
  }
  
  return sections.join('\n\n');
}

/**
 * 生成微博话题标签
 */
function generateWeiboHashtags(topic) {
  const baseHashtags = [
    `#${topic}#`,
    '#美食#',
    '#地方美食#',
    '#传统美食#'
  ];
  
  const additionalHashtags = [
    '#美食文化#',
    '#时令饮食#',
    '#饮食养生#',
    '#非遗美食#'
  ];
  
  return [...baseHashtags, ...additionalHashtags].slice(0, 8).join(' ');
}

/**
 * 生成微博互动
 */
function generateWeiboInteraction(topic) {
  const questions = [
    `你最喜欢${topic}的哪种浇头？`,
    `你吃过最地道的${topic}在哪里？`,
    `你觉得${topic}最能代表什么文化？`,
    `你会在什么季节特别想吃${topic}？`
  ];
  
  const question = questions[Math.floor(Math.random() * questions.length)];
  
  const options = ['A', 'B', 'C', 'D'];
  const optionTexts = [
    '经典传统口味',
    '创新改良口味', 
    '季节限定口味',
    '地方特色口味'
  ];
  
  const pollOptions = options.map((opt, i) => `${opt}. ${optionTexts[i]}`).join('\n');
  
  return `🍜 投票：${question}\n\n${pollOptions}\n\n👉 转发+评论，抽3位送美食代金券！`;
}

/**
 * 生成数据支撑
 */
function generateDataSupport(statistics) {
  if (!statistics || statistics.sourceCount === 0) {
    return '';
  }
  
  return `📊 数据支撑：基于${statistics.sourceCount}个权威来源，相关性评分${statistics.relevanceScore}/100`;
}

/**
 * 获取分类名称
 */
function getCategoryName(category) {
  const names = {
    toppings: '浇头推荐',
    soupBases: '汤底类型',
    noodleTypes: '面条种类',
    eatingMethods: '吃法讲究',
    seasonal: '季节限定',
    regional: '地方特色',
    healthBenefits: '健康好处',
    cultural: '文化内涵'
  };
  
  return names[category] || category;
}

module.exports = { formatArticle };

path: scripts/generate-article.js
content: #!/usr/bin/env node

/**
 * 自媒体文章生成主脚本
 * 根据主题和关键词自动搜索、汇总数据、生成文章
 */

const fs = require('fs');
const path = require('path');
const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');

// 导入自定义模块
const { searchContent } = require('./search-content.js');
const { extractData } = require('./extract-data.js');
const { formatArticle } = require('./format-article.js');

const argv = yargs(hideBin(process.argv))
  .option('topic', {
    alias: 't',
    type: 'string',
    description: '文章主题',
    demandOption: true
  })
  .option('keywords', {
    alias: 'k',
    type: 'string',
    description: '关键词，用逗号分隔',
    default: ''
  })
  .option('platform', {
    alias: 'p',
    type: 'string',
    description: '目标平台：douyin, xiaohongshu, weibo, all',
    default: 'all'
  })
  .option('search-count', {
    alias: 'n',
    type: 'number',
    description: '搜索结果数量',
    default: 10
  })
  .option('days', {
    alias: 'd',
    type: 'number',
    description: '搜索时间范围（天）',
    default: 30
  })
  .option('deep-search', {
    type: 'boolean',
    description: '使用深度搜索模式',
    default: false
  })
  .option('output-dir', {
    alias: 'o',
    type: 'string',
    description: '输出目录',
    default: './output'
  })
  .option('dry-run', {
    type: 'boolean',
    description: '仅显示过程，不保存文件',
    default: false
  })
  .option('verbose', {
    alias: 'v',
    type: 'boolean',
    description: '显示详细过程',
    default: false
  })
  .help()
  .alias('help', 'h')
  .argv;

async function main() {
  console.log('🎬 开始生成自媒体文章...');
  console.log(`📝 主题：${argv.topic}`);
  console.log(`🔑 关键词：${argv.keywords || '使用默认关键词'}`);
  console.log(`📱 平台：${argv.platform}`);
  
  // 1. 搜索相关内容
  console.log('\n🔍 步骤1：搜索相关内容...');
  const searchResults = await searchContent({
    topic: argv.topic,
    keywords: argv.keywords.split(',').filter(k => k.trim()),
    count: argv.searchCount,
    days: argv.days,
    deep: argv.deepSearch,
    verbose: argv.verbose
  });
  
  if (argv.verbose) {
    console.log(`📊 搜索到 ${searchResults.sources?.length || 0} 个来源`);
  }
  
  // 2. 提取关键数据
  console.log('📋 步骤2：提取关键数据...');
  const extractedData = extractData(searchResults, {
    topic: argv.topic,
    verbose: argv.verbose
  });
  
  if (argv.verbose) {
    console.log('📈 提取的数据结构：');
    console.log(JSON.stringify(extractedData, null, 2));
  }
  
  // 3. 生成文章
  console.log('✍️ 步骤3：生成文章内容...');
  const platforms = argv.platform === 'all' 
    ? ['douyin', 'xiaohongshu', 'weibo'] 
    : [argv.platform];
  
  const articles = {};
  
  for (const platform of platforms) {
    console.log(`  生成 ${platform} 文章...`);
    articles[platform] = formatArticle(extractedData, platform);
  }
  
  // 4. 保存输出
  if (!argv.dryRun) {
    console.log('💾 步骤4：保存文章...');
    
    // 创建输出目录
    const outputDir = path.resolve(argv.outputDir);
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }
    
    // 生成时间戳
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
    const topicSlug = argv.topic.replace(/[^\w\u4e00-\u9fa5]/g, '-').toLowerCase();
    
    for (const [platform, content] of Object.entries(articles)) {
      const filename = `${topicSlug}-${platform}-${timestamp}.md`;
      const filepath = path.join(outputDir, filename);
      
      fs.writeFileSync(filepath, content, 'utf8');
      console.log(`  已保存：${filename}`);
      
      // 同时保存一个简化的txt版本
      const txtContent = content.replace(/[#*`]/g, '').replace(/\n{3,}/g, '\n\n');
      const txtFilename = `${topicSlug}-${platform}-${timestamp}.txt`;
      const txtFilepath = path.join(outputDir, txtFilename);
      
      fs.writeFileSync(txtFilepath, txtContent, 'utf8');
    }
    
    // 保存原始数据（用于调试）
    const dataFilename = `${topicSlug}-data-${timestamp}.json`;
    const dataFilepath = path.join(outputDir, dataFilename);
    
    fs.writeFileSync(dataFilepath, JSON.stringify({
      topic: argv.topic,
      keywords: argv.keywords,
      searchResults,
      extractedData,
      generatedAt: new Date().toISOString()
    }, null, 2), 'utf8');
    
    console.log(`\n✅ 所有文章已保存到：${outputDir}`);
  } else {
    console.log('\n🔍 干运行模式，不保存文件');
  }
  
  // 5. 显示生成的文章预览
  console.log('\n📄 生成的文章预览：');
  console.log('='.repeat(50));
  
  for (const [platform, content] of Object.entries(articles)) {
    console.log(`\n📱 ${platform.toUpperCase()} 文章预览：`);
    console.log('-'.repeat(30));
    
    // 显示前10行
    const lines = content.split('\n').slice(0, 15);
    console.log(lines.join('\n'));
    
    if (content.split('\n').length > 15) {
      console.log('...（更多内容已保存到文件）');
    }
    
    console.log('-'.repeat(30));
  }
  
  console.log('='.repeat(50));
  console.log('🎉 文章生成完成！');
}

// 错误处理
main().catch(error => {
  console.error('❌ 生成文章时出错：', error.message);
  if (argv.verbose) {
    console.error(error.stack);
  }
  process.exit(1);
});

path: scripts/search-content.js
content: /**
 * 搜索相关内容模块
 * 使用Tavily API搜索与主题相关的信息
 */

const { execSync } = require('child_process');
const path = require('path');

// 面食相关关键词库
const NOODLE_KEYWORDS = {
  // 浇头/配料
  toppings: ['浇头', '配料', '臊子', '码子', '配菜', '佐料'],
  
  // 汤底/汤头
  soup: ['汤底', '汤头', '高汤', '清汤', '红汤', '白汤'],
  
  // 面条类型
  noodleTypes: ['细面', '宽面', '拉面', '刀削面', '手擀面', '机制面'],
  
  // 吃法/习俗
  eatingHabits: ['吃法', '习俗', '传统', '讲究', '规矩', '礼仪'],
  
  // 季节限定
  seasonal: ['时令', '季节', '春季', '夏季', '秋季', '冬季', '限定'],
  
  // 地方特色
  regional: ['地方特色', '地域', '本地', '传统', '老字号', '非遗'],
  
  // 健康营养
  health: ['健康', '营养', '养生', '好处', '功效', '营养价值'],
  
  // 文化内涵
  culture: ['文化', '内涵', '历史', '渊源', '故事', '传说', '民俗']
};

// 默认搜索关键词
const DEFAULT_KEYWORDS = {
  noodle: ['面', '面条', '面食', '汤面', '拌面'],
  general: ['怎么吃', '吃什么', '哪里吃', '什么时候吃', '好处', '文化']
};

/**
 * 搜索相关内容
 * @param {Object} options 搜索选项
 * @returns {Promise<Object>} 搜索结果
 */
async function searchContent(options) {
  const {
    topic,
    keywords = [],
    count = 10,
    days = 30,
    deep = false,
    verbose = false
  } = options;
  
  // 构建搜索查询
  const searchQueries = buildSearchQueries(topic, keywords);
  
  if (verbose) {
    console.log(`🔍 搜索查询：${searchQueries.join(', ')}`);
  }
  
  // 执行搜索（这里使用tavily-search技能）
  const searchResults = [];
  
  for (const query of searchQueries.slice(0, 3)) { // 限制前3个查询
    try {
      const result = await executeTavilySearch(query, count, days, deep);
      if (result && result.sources) {
        searchResults.push(...result.sources);
        
        if (verbose) {
          console.log(`✅ 搜索 "${query}" 获得 ${result.sources.length} 个结果`);
        }
      }
    } catch (error) {
      if (verbose) {
        console.warn(`⚠️ 搜索 "${query}" 失败：${error.message}`);
      }
    }
    
    // 避免请求过快
    await sleep(1000);
  }
  
  // 去重结果
  const uniqueResults = removeDuplicates(searchResults);
  
  return {
    topic,
    keywords,
    searchQueries,
    sources: uniqueResults.slice(0, count * 2), // 保留更多结果供后续处理
    totalResults: uniqueResults.length,
    searchDate: new Date().toISOString()
  };
}

/**
 * 构建搜索查询
 */
function buildSearchQueries(topic, userKeywords) {
  const queries = [];
  
  // 1. 基础查询：主题 + 通用关键词
  for (const generalKeyword of DEFAULT_KEYWORDS.general) {
    queries.push(`${topic} ${generalKeyword}`);
  }
  
  // 2. 用户指定关键词
  for (const keyword of userKeywords) {
    if (keyword.trim()) {
      queries.push(`${topic} ${keyword}`);
    }
  }
  
  // 3. 面食相关关键词（如果主题包含面食相关词汇）
  if (isNoodleRelated(topic)) {
    for (const category in NOODLE_KEYWORDS) {
      for (const keyword of NOODLE_KEYWORDS[category]) {
        queries.push(`${topic} ${keyword}`);
      }
    }
  }
  
  // 4. 组合查询
  if (userKeywords.length >= 2) {
    queries.push(`${topic} ${userKeywords.slice(0, 3).join(' ')}`);
  }
  
  // 去重并限制数量
  return [...new Set(queries)].slice(0, 10);
}

/**
 * 判断是否与面食相关
 */
function isNoodleRelated(text) {
  const noodleIndicators = ['面', '面条', '面食', '汤面', '拌面', '拉面', '刀削面'];
  return noodleIndicators.some(indicator => text.includes(indicator));
}

/**
 * 执行Tavily搜索
 */
async function executeTavilySearch(query, count, days, deep) {
  try {
    // 构建命令
    const tavilySkillPath = path.join(__dirname, '../../tavily-search');
    const cmd = [
      'node',
      path.join(tavilySkillPath, 'scripts/search.mjs'),
      `"${query}"`,
      `-n ${count}`,
      days ? `--days ${days}` : '',
      deep ? '--deep' : '',
      '--topic general'
    ].filter(Boolean).join(' ');
    
    // 执行命令
    const output = execSync(cmd, { 
      encoding: 'utf8',
      cwd: tavilySkillPath,
      stdio: ['pipe', 'pipe', 'pipe']
    });
    
    // 解析输出（Tavily搜索返回markdown格式）
    return parseTavilyOutput(output);
  } catch (error) {
    console.error(`执行Tavily搜索失败：${error.message}`);
    return null;
  }
}

/**
 * 解析Tavily输出
 */
function parseTavilyOutput(output) {
  try {
    const lines = output.split('\n');
    const sources = [];
    let currentSource = null;
    
    for (const line of lines) {
      // 匹配来源行：- **标题** (relevance: XX%)
      const sourceMatch = line.match(/^- \*\*(.*?)\*\* \(relevance: (\d+)%\)/);
      if (sourceMatch) {
        if (currentSource) {
          sources.push(currentSource);
        }
        currentSource = {
          title: sourceMatch[1].trim(),
          relevance: parseInt(sourceMatch[2]),
          content: ''
        };
        continue;
      }
      
      // 匹配URL行
      const urlMatch = line.match(/^\s+(https?:\/\/[^\s]+)/);
      if (urlMatch && currentSource) {
        currentSource.url = urlMatch[1].trim();
        continue;
      }
      
      // 收集内容（在标题和URL之后的行）
      if (currentSource && line.trim() && !line.startsWith('  ') && !line.match(/^[=-]+$/)) {
        currentSource.content += line.trim() + ' ';
      }
    }
    
    // 添加最后一个来源
    if (currentSource) {
      sources.push(currentSource);
    }
    
    // 提取总结（第一段）
    const summaryMatch = output.match(/^## Answer\s*\n\s*\n(.+?)\s*\n\s*\n---/s);
    const summary = summaryMatch ? summaryMatch[1].trim() : '';
    
    return {
      summary,
      sources,
      rawOutput: output
    };
  } catch (error) {
    console.error('解析Tavily输出失败：', error);
    return { summary: '', sources: [], rawOutput: output };
  }
}

/**
 * 去重搜索结果
 */
function removeDuplicates(results) {
  const seen = new Set();
  return results.filter(result => {
    const key = result.url || result.title;
    if (seen.has(key)) {
      return false;
    }
    seen.add(key);
    return true;
  });
}

/**
 * 睡眠函数
 */
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

module.exports = { searchContent, NOODLE_KEYWORDS, DEFAULT_KEYWORDS };

path: templates/douyin-template.md
content: # 抖音文章模板

## 结构说明
1. 吸引眼球的标题（带emoji）
2. 简洁明了的内容要点
3. 丰富的话题标签
4. 互动引导语

## 模板示例

🍜 [主题]这样吃才地道！

👉 浇头推荐：[浇头1]、[浇头2]、[浇头3]
👉 最佳时间：[具体时间]
👉 老字号推荐：[店铺1]、[店铺2]
👉 必尝：[推荐菜品]
👉 小贴士：[实用建议]

#主题 #美食 #吃货 #美食教程 #地方美食 #浇头 #时令美食 #传统美食

关注我，解锁更多美食攻略！👇

## 内容要点
- 每行以👉开头，简洁明了
- 使用emoji增加视觉吸引力
- 控制在15秒内可读完
- 话题标签8个左右，涵盖广泛

## 标题创意
- 🍜 [主题]｜本地人才知道的吃法
- ✨ 揭秘[主题]的正确打开方式
- 🔥 [主题]这样吃，味道提升100%
- 🌟 春天必吃！[主题]全攻略
- 💫 [主题]｜吃货必备指南

## 互动引导语
- 关注我，解锁更多美食攻略！👇
- 点赞收藏，下次不迷路！❤️
- 评论区告诉我你想看哪个城市的美食攻略！💬
- 转发给爱吃面的朋友！👯‍♀️
- 下期想看什么美食？留言告诉我！📝

## 话题标签组合
基础标签：#主题 #美食 #吃货 #美食教程 #地方美食
扩展标签：#浇头 #配料 #时令美食 #春季美食 #美食文化 #传统美食 #非遗美食

## 注意事项
1. 内容要简短，每条信息一行
2. 使用数字和具体名称增加可信度
3. 包含实用建议和小贴士
4. 引导用户互动（评论、点赞、关注）
5. 话题标签要相关且热门

path: templates/weibo-template.md
content: # 微博文章模板

## 结构说明
1. 话题标签
2. 吸引眼球的标题
3. 数据支撑的观点
4. 文化内涵挖掘
5. 互动元素（投票、抽奖）
6. 相关话题标签

## 模板示例

#[主题]# #美食# #地方美食# #传统美食# #美食文化# #时令饮食# #饮食养生# #非遗美食#

【[主题]，你了解多少？】

数据显示，[主题]最受欢迎的浇头有：[浇头1]、[浇头2]、[浇头3]

季节特色：[季节特色描述]

文化内涵：[文化内涵描述]

健康好处：[健康好处描述]

老字号推荐：[店铺1]、[店铺2]

📊 数据支撑：基于[数量]个权威来源，相关性评分[分数]/100

🍜 投票：你最喜欢[主题]的哪种浇头？
A. 经典传统口味
B. 创新改良口味
C. 季节限定口味
D. 地方特色口味

👉 转发+评论，抽3位送美食代金券！

## 内容要点
- 以数据开场增加可信度
- 挖掘文化内涵提升深度
- 包含健康价值吸引关注
- 设置互动增加参与度

## 标题创意
- 【[主题]，你吃对了吗？】
- 【春天吃[主题]，这些知识要知道】
- 【[主题]背后的文化密码】
- 【数据说话：[主题]最全指南】
- 【传统与现代的碰撞：[主题]新吃法】

## 数据开场模板
- 数据显示，[主题]最受欢迎的浇头有：[具体数据]
- 据统计，[主题]的最佳食用时间是：[具体时间]
- 调查发现，[主题]的文化内涵包括：[具体内容]
- 研究显示，[主题]的健康好处有：[具体好处]

## 文化内涵挖掘
- 历史渊源：[历史故事]
- 地方特色：[地域特点]
- 季节时令：[季节关联]
- 民俗传统：[民间习俗]
- 非遗价值：[文化遗产]

## 互动元素设计
### 投票模板
🍜 投票：[问题]
A. [选项1]
B. [选项2]
C. [选项3]
D. [选项4]

### 抽奖模板
👉 转发+评论，抽[数量]位送[奖品]！
👉 关注+转发，抽[数量]位送[奖品]！
👉 评论分享你的故事，抽[数量]位送[奖品]！

### 问答模板
❓ 提问：[问题]
💬 评论区分享你的答案！

## 话题标签策略
核心标签：#[主题]# #美食# #地方美食# #传统美食#
扩展标签：#美食文化# #时令饮食# #饮食养生# #非遗美食# #健康饮食# #美食探店# #美食测评#

## 数据支撑模板
📊 数据支撑：基于[数量]个权威来源，相关性评分[分数]/100
📈 信息来源：[机构1]、[机构2]、[机构3]
🔍 研究显示：[具体研究发现]

## 专业术语使用
- 不时不食：按季节吃东西
- 食不厌精：饮食讲究精致
- 药食同源：食物有药用价值
- 饮食养生：通过饮食保养身体
- 非遗传承：非物质文化遗产传承

## 注意事项
1. 内容要有数据支撑，增加可信度
2. 挖掘深度文化内涵，提升文章价值
3. 设置互动环节，提高用户参与度
4. 使用热门话题标签，增加曝光
5. 保持专业性和趣味性的平衡
6. 注意抽奖活动的合规性

path: templates/xiaohongshu-template.md
content: # 小红书文章模板

## 结构说明
1. 标题和话题标签
2. 引言和整体介绍
3. 详细分类推荐
4. 实用技巧和建议
5. 拍照建议
6. 话题标签
7. 收藏引导

## 模板示例

#[主题] #美食攻略 #时令美食

[主题]，作为传统美食的代表，今天给大家分享全攻略！

🍜 浇头推荐（精选）：
• [浇头1]
• [浇头2]
• [浇头3]
• [浇头4]
• [浇头5]

⏰ 最佳时间：[具体时间]

📍 老字号推荐：
• [店铺1]
• [店铺2]
• [店铺3]
• [店铺4]
• [店铺5]

🎯 吃法讲究：
• [吃法1]
• [吃法2]
• [吃法3]

💪 健康好处：
• [好处1]
• [好处2]
• [好处3]

📚 文化内涵：
• [文化点1]
• [文化点2]

📸 拍照Tips：
• 拍汤面要体现"观音头、鲤鱼背"
• 浇头特写展示食材新鲜度
• 环境照体现传统风格
• 人物互动增加生活感

#主题 #美食攻略 #吃货日常 #地方美食 #传统美食 #时令美食 #春季限定 #美食文化 #非遗美食 #健康饮食

收藏这篇，下次去不迷路！🌟

## 内容要点
- 使用bullet points（•）列出项目
- 每个分类有小标题和emoji
- 内容详细但条理清晰
- 包含实用建议和文化内涵

## 分类结构
1. 🍜 浇头推荐 - 精选5种左右
2. ⏰ 最佳时间 - 具体时间段
3. 📍 老字号推荐 - 5家左右店铺
4. 🎯 吃法讲究 - 传统吃法
5. 💪 健康好处 - 营养价值
6. 📚 文化内涵 - 历史传统

## 拍照建议模板
📸 拍照Tips：
• 拍汤面要体现"观音头、鲤鱼背"
• 浇头特写展示食材新鲜度
• 环境照体现传统风格
• 人物互动增加生活感
• 细节展示制作过程
• 色彩搭配要和谐

## 话题标签策略
基础标签：#主题 #美食攻略 #吃货日常 #地方美食 #传统美食
深度标签：#时令美食 #春季限定 #美食文化 #非遗美食 #健康饮食 #养生美食 #美食摄影

## 收藏引导语
- 收藏这篇，下次去不迷路！🌟
- 点赞收藏，美食攻略不丢失！❤️
- 关注我，更多美食攻略持续更新！👉
- 转发给朋友，一起打卡美食！👯‍♀️
- 需要完整攻略的私信我！💌

## 专业术语
- 观音头、鲤鱼背：苏式面的经典造型
- 宽汤、紧汤：汤多汤少
- 重青、免青：葱蒜多少
- 过桥：浇头分开装
- 头汤面：早上第一锅汤的面

## 注意事项
1. 内容要详细但不过于冗长
2. 使用专业术语体现专业性
3. 包含文化内涵提升文章深度
4. 提供实用建议增加价值
5. 引导用户收藏和互动

Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)