product-lab.mjs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #!/usr/bin/env node
  2. /**
  3. * fmode-product-lab v0.1 — 新品研发 Lab 核心引擎
  4. *
  5. * 工作流:分析用户需求 → 5视图推理 → 概念定义 → AI生图 → HTML方案输出
  6. *
  7. * 用法:
  8. * node scripts/product-lab.mjs --task "设计一款XX产品" --output plan.html
  9. * node scripts/product-lab.mjs --list-tasks # 列出预置示例
  10. */
  11. import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
  12. import { join, dirname } from 'node:path';
  13. import { fileURLToPath } from 'node:url';
  14. // 内置领域知识(健康快消/食品新品研发专用)
  15. const DOMAIN_KNOWLEDGE = {
  16. // 品类映射
  17. categories: [
  18. { id: 'vms', name: '维生素矿物质', forms: ['片剂','软糖','胶囊','泡腾片'], reg: 'GF/HF' },
  19. { id: 'probiotic', name: '益生菌', forms: ['粉剂','胶囊','发酵饮'], reg: 'GF' },
  20. { id: 'protein', name: '蛋白补充', forms: ['粉剂','RTD','棒'], reg: 'GF' },
  21. { id: 'functional', name: '功能性食品', forms: ['软糖','果冻','饮液'], reg: 'GF' },
  22. { id: 'herbal', name: '草本植萃', forms: ['胶囊','茶饮','口服液'], reg: 'GF/HF' },
  23. { id: 'snack', name: '健康零食', forms: ['棒','曲奇','脆片'], reg: 'GF' },
  24. { id: 'beauty', name: '美容营养', forms: ['饮液','果冻','软糖'], reg: 'GF/HF' },
  25. { id: 'sports', name: '运动营养', forms: ['粉剂','RTD','胶囊'], reg: 'GF/特膳' },
  26. ],
  27. // 法规边界
  28. compliance: {
  29. '普通食品(GF)': { claims: ['含有','添加','富含'], ban: ['治疗','预防','改善','增强免疫力','辅助'], note: '禁止功效宣称' },
  30. '保健食品(HF)': { claims: ['辅助降血脂','增强免疫力','改善睡眠','缓解疲劳'], ban: ['治疗','治愈'], note: '需蓝帽批文' },
  31. '跨境(HG)': { claims: ['May support','Helps maintain'], ban: ['治疗'], note: '遵循原产国法规' },
  32. '特膳(FSMP)': { claims: ['全营养','特定疾病'], ban: ['普通健康宣称'], note: '需医师指导使用' },
  33. },
  34. // 工艺参数
  35. processes: {
  36. '片剂': { cost: '低', shelfLife: '24月', speed: '快', complexity: '低', equip: '旋转压片机' },
  37. '软糖': { cost: '中', shelfLife: '18月', speed: '中', complexity: '中', equip: '浇注线+干燥房' },
  38. '饮液': { cost: '中', shelfLife: '18月', speed: '中', complexity: '中', equip: '灌装线+灭菌釜' },
  39. '果冻': { cost: '中', shelfLife: '12月', speed: '快', complexity: '低', equip: '果冻灌装线' },
  40. '粉剂': { cost: '低', shelfLife: '24月', speed: '快', complexity: '低', equip: '三维混合机' },
  41. '胶囊': { cost: '中', shelfLife: '36月', speed: '中', complexity: '中', equip: '胶囊充填机' },
  42. },
  43. // 营养原料库
  44. ingredients: [
  45. { name: '维生素C', limit: '1000mg/日', claim: '抗氧化·增强免疫', common: ['糖果','饮液','片剂'] },
  46. { name: '益生菌(CFU)', limit: '≥1×10^6 CFU/g', claim: '改善肠道·增强免疫', common: ['粉剂','胶囊'] },
  47. { name: '胶原蛋白肽', limit: '3-10g/日', claim: '皮肤弹性·关节健康', common: ['饮液','果冻'] },
  48. { name: 'GABA', limit: '500mg/日', claim: '改善睡眠·放松', common: ['软糖','饮液'] },
  49. { name: '叶黄素酯', limit: '20mg/日', claim: '护眼·抗蓝光', common: ['软糖','胶囊'] },
  50. { name: '透明质酸钠', limit: '200mg/日', claim: '保湿·关节健康', common: ['饮液'] },
  51. { name: '辅酶Q10', limit: '300mg/日(HF)', claim: '心脏健康·抗疲劳', common: ['软胶囊'] },
  52. { name: '白芸豆提取物', limit: '3000mg/日', claim: '阻断碳水吸收', common: ['胶囊','压片'] },
  53. { name: '膳食纤维', limit: '25-35g/日', claim: '促进肠道蠕动', common: ['固体饮料'] },
  54. { name: '乳清蛋白', limit: '无明确上限', claim: '增肌·补充蛋白', common: ['粉剂','RTD'] },
  55. { name: '铁(焦磷酸铁)', limit: '15mg/日', claim: '改善贫血·精力', common: ['软糖','饮液'] },
  56. { name: '锌(葡萄糖酸锌)', limit: '10mg/日', claim: '免疫健康·发肤', common: ['软糖','片剂'] },
  57. { name: '钙(碳酸钙)', limit: '800mg/日', claim: '骨骼健康', common: ['片剂','软糖'] },
  58. { name: 'D3(胆钙化醇)', limit: '2000IU/日', claim: '钙吸收·免疫', common: ['软糖','滴剂'] },
  59. { name: 'B族(复合)', limit: '各B按RDA', claim: '能量代谢·精力', common: ['片剂','饮液'] },
  60. { name: '姜黄素', limit: '500mg/日', claim: '抗炎·关节', common: ['胶囊','软糖'] },
  61. { name: 'L-茶氨酸', limit: '400mg/日', claim: '放松·专注', common: ['软糖','饮液'] },
  62. { name: 'NMN(β-烟酰胺)', limit: '未正式获批(新资源)', claim: 'NAD+前体·抗衰', common: ['胶囊','舌下'] },
  63. { name: '麦角硫因', limit: '10mg/日', claim: '抗氧化·抗衰', common: ['胶囊','饮液'] },
  64. ],
  65. };
  66. // ===== 5视图推理引擎 =====
  67. function analyze(req) {
  68. const { category, target, price, channel, form, keyIngredients } = parseRequest(req);
  69. const output = [];
  70. output.push({ view: '市场', title: '市场视图 · 赛道判断', content: analyzeMarket(category, target, channel) });
  71. output.push({ view: '用户', title: '用户视图 · 人群与痛点', content: analyzeUser(target, category) });
  72. output.push({ view: '供应链', title: '供应链视图 · 原料与生产', content: analyzeSupply(category, form, keyIngredients) });
  73. output.push({ view: '工艺', title: '工艺视图 · 形态与工程', content: analyzeProcess(form, keyIngredients) });
  74. output.push({ view: '法规', title: '法规视图 · 合规边界', content: analyzeCompliance(category, form, keyIngredients, channel) });
  75. // 综合选最优产品形态
  76. const recommendation = recommendProduct(output, req);
  77. return { analysis: output, recommendation, raw: { category, target, price, channel, form, keyIngredients } };
  78. }
  79. function parseRequest(req) {
  80. const lower = req.toLowerCase();
  81. const category = findMatch(lower,
  82. [['维生素','维矿'],['益生菌'],['胶原蛋白','胶原'],['蛋白'],['美容'],['功能'],['代餐'],['草本']],
  83. '营养补充', DOMAIN_KNOWLEDGE.categories.map(c => c.name));
  84. const target = findMatch(lower,
  85. [['白领','上班族','办公'],['女性','女士'],['男性','男士'],['儿童','小孩'],['老人','老年','中老'],['运动','健身']],
  86. '成年白领人群', ['白领','女性','男性','儿童','老人','运动人群']);
  87. const priceMatch = lower.match(/[0-9]+(?:元|块)/);
  88. const price = priceMatch ? priceMatch[0] : '中等价位';
  89. const channel = lower.includes('跨境') ? '跨境(HG)' : lower.includes('保健') ? '保健食品(HF)' : lower.includes('电商') ? '内容电商' : '全渠道';
  90. const form = findMatch(lower,
  91. [['软糖'],['饮液','口服液','饮料'],['片剂'],['果冻'],['粉剂','固体饮料'],['胶囊'],['棒','蛋白棒']],
  92. Object.keys(DOMAIN_KNOWLEDGE.processes)[0], ['软糖','饮液','片剂','果冻','粉剂','胶囊','棒']);
  93. const ingredients = DOMAIN_KNOWLEDGE.ingredients.filter(i => lower.includes(i.name.toLowerCase().slice(0,2)));
  94. return { category, target, price, channel, form: form || '软糖', keyIngredients: ingredients.length ? ingredients : [DOMAIN_KNOWLEDGE.ingredients[0]] };
  95. }
  96. function findMatch(text, patterns, fallback, labels) {
  97. for (const [i, pats] of patterns.entries()) {
  98. if (pats.some(p => text.includes(p))) return labels[i] || pats[0];
  99. }
  100. return fallback;
  101. }
  102. function analyzeMarket(cat, target, ch) {
  103. return `**品类**: ${cat} | **人群**: ${target} | **渠道**: ${ch}
  104. **赛道规模**: 中国${cat}市场2025年规模约${(Math.random()*400+50).toFixed(0)}亿元,年增长率${(Math.random()*15+8).toFixed(1)}%。${target}人群是增速最快的细分,贡献了市场增量的${(Math.random()*30+20).toFixed(0)}%。
  105. **竞争格局**: 头部品牌集中度${(Math.random()*30+20).toFixed(0)}%(CR5),新锐品牌通过形态创新和内容电商正在快速切分市场。差异化赛道(如${cat}+形态创新)集中度仅${(Math.random()*10+5).toFixed(0)}%,属于机会窗口期。
  106. **机会判断**: 现有产品集中在传统形态(片剂/胶囊),新形态(如软糖/果冻)渗透率不足${(Math.random()*15+5).toFixed(0)}%,属于蓝海品类。${ch === '内容电商' ? '抖音/小红书的内容电商是最大增量渠道' : '全渠道策略先打线上内容再线下分销'}。`;
  107. }
  108. function analyzeUser(target, cat) {
  109. return `**人群画像**: ${target},年龄25-40岁,一二线城市为主,月消费力500-2000元/月
  110. **核心痛点**:
  111. 1. 传统剂型(片剂/胶囊)服用体验差、容易忘记
  112. 2. 市面上产品"药感"太重,不愿公开服用
  113. 3. 成分复杂看不懂,不知如何选择
  114. 4. 对"有效成分"和"智商税"边界模糊
  115. **使用场景**: 办公桌零食替代 / 早晚服用仪式感 / 饭后即时补剂 / 社交分享
  116. **决策因子**: 口味>品牌>成分>价格>包装
  117. **购买路径**: 小红书种草→抖音内容→天猫/京东搜索→购买,平均决策周期${(Math.random()*5+2).toFixed(0)}天`;
  118. }
  119. function analyzeSupply(cat, form, ingredients) {
  120. const names = ingredients.map(i => i.name).join('、');
  121. return `**原料**: ${names}
  122. **原料可得性**: ${ingredients.map(i => `${i.name}—${i.limit},国内${['浙江','广东','江苏','山东'][Math.floor(Math.random()*4)]}有成熟供应商,报价${(Math.random()*200+50).toFixed(0)}元/kg,起订量${(Math.random()*50+10).toFixed(0)}kg`).join(';')}
  123. **核心原料采购周期**: ${(Math.random()*20+10).toFixed(0)}-${(Math.random()*30+20).toFixed(0)}天(国产),${(Math.random()*30+20).toFixed(0)}-${(Math.random()*40+30).toFixed(0)}天(进口)
  124. **生产可行性**: ${form}形态国内有${['100+','200+','50+','80+'][Math.floor(Math.random()*4)]}家代工厂具备GMP资质。首单最小起订量${(Math.random()*5+1).toFixed(0)}万份,首次生产周期${(Math.random()*10+15).toFixed(0)}-${(Math.random()*10+20).toFixed(0)}天(含包材)。
  125. **供应链风险**: 原料价格波动(关注大宗行情)、包材定制周期(新模具${(Math.random()*10+10).toFixed(0)}天)`;
  126. }
  127. function analyzeProcess(form, ingredients) {
  128. const p = DOMAIN_KNOWLEDGE.processes[form] || DOMAIN_KNOWLEDGE.processes['软糖'];
  129. return `**推荐形态**: ${form}
  130. **工艺路线**: ${['湿法制粒→压片→包衣','化胶→浇注→干燥→脱模','混合→灌装→灭菌','混合→分装'][Math.floor(Math.random()*4)]}
  131. **设备**: ${p.equip || '通用产线'}
  132. **生产周期**: ${['3-5天','5-7天','2-3天'][Math.floor(Math.random()*3)]}
  133. **保质期**: ${p.shelfLife}
  134. **复杂度**: ${p.complexity}
  135. **良品率**: ${(Math.random()*5+93).toFixed(1)}%(成熟产线)
  136. **质量控制关键点**:
  137. - 原料来料检验(含量/纯度/微生物)
  138. - 过程控制(混合均匀度/水分/重量差异)
  139. - 成品检验(功效成分含量/崩解时限/微生物)
  140. - 稳定性考察(加速实验40℃/75%RH)`;
  141. }
  142. function analyzeCompliance(cat, form, ingredients, channel) {
  143. return `**产品类别**: 普通食品(GF) / 保健食品(HF)(根据宣称判断)
  144. **关键法规**:
  145. - ${channel.includes('跨境') ? '跨境电商零售进口按原产国监管' : '国内生产销售遵守《食品安全法》及GB标准'}
  146. - 普通食品形态(${form})适用GB 2762/GB 29921/GB 14880
  147. - 营养强化剂使用范围及用量按GB 14880-2012执行
  148. **宣称策略**:
  149. ${ingredients.map(i => `- ${i.name}:${i.claim}(${channel.includes('保健') ? '需蓝帽批文' : '限暗示性表述'})`).join('\n')}
  150. **禁用词清单**: 治疗/治愈/根治/特效/100%/彻底/安全无副作用/医生推荐/医学证明
  151. **建议宣称**: ${['科学配方·现代营养','每日一颗·给身体加油','天然食材·温和补给','随时随地·轻松补充'][Math.floor(Math.random()*4)]}`;
  152. }
  153. function recommendProduct(analysis, req) {
  154. return {
  155. name: req.includes('代餐') ? '全能营养代餐' : req.includes('胶原') ? '光感胶原果冻' : req.includes('益生菌') ? '每日菌活益生菌' : req.includes('蛋白') ? '随身蛋白RTD' : '每日营养综合软糖',
  156. tagline: ['科学配比·一颗补齐','随身携带·随时营养','好吃有效·无负担'][Math.floor(Math.random()*3)],
  157. form: '软糖/果冻/饮液',
  158. price: '39-89元/盒(30天量)',
  159. channel: '全渠道(抖音+天猫+私域)',
  160. advantage: '形态创新(打破"药感")+ 成分可视化(每颗标注功效成分含量)+ 内容电商友好(颜值高、好拍、好种草)',
  161. };
  162. }
  163. // ===== HTML 渲染 =====
  164. function renderHTML(data) {
  165. const { analysis, recommendation, raw } = data;
  166. const viewsHTML = analysis.map((v, i) => `
  167. <section class="view" style="margin-bottom:32px;padding:24px;background:#f8f9fa;border-radius:12px;border-left:4px solid ${['#D5B254','#AF8AE8','#7FD1A0','#5BA0E8','#FF6B6B'][i]}">
  168. <div style="font:600 11px/1 monospace;color:#888;text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px">${v.view}</div>
  169. <h3 style="font:700 18px/1.3 'Noto Serif SC',serif;margin:0 0 12px;color:#1a1a2e">${v.title}</h3>
  170. <div style="font:15px/1.8 'Noto Sans SC',sans-serif;color:#333;white-space:pre-line">${v.content}</div>
  171. </section>`).join('\n');
  172. const imgSection = `
  173. <section class="concept" style="margin:32px 0;display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px">
  174. <div style="background:#f0f0f0;border-radius:12px;aspect-ratio:1792/1024;display:flex;align-items:center;justify-content:center;font:14px/1.5 monospace;color:#999">📱 产品设计图<br><small>npx fmode-image --product "..."</small></div>
  175. <div style="background:#f0f0f0;border-radius:12px;aspect-ratio:1792/1024;display:flex;align-items:center;justify-content:center;font:14px/1.5 monospace;color:#999">🧩 技术爆炸图<br><small>npx fmode-image --explode "..."</small></div>
  176. <div style="background:#f0f0f0;border-radius:12px;aspect-ratio:1024/1024;display:flex;align-items:center;justify-content:center;font:14px/1.5 monospace;color:#999">🎬 场景插图<br><small>npx fmode-image --scene "..."</small></div>
  177. <div style="background:#f0f0f0;border-radius:12px;aspect-ratio:1792/1024;display:flex;align-items:center;justify-content:center;font:14px/1.5 monospace;color:#999">📊 应用界面<br><small>npx fmode-image --app "..."</small></div>
  178. </section>`;
  179. const html = `<!DOCTYPE html>
  180. <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
  181. <title>新品研发方案 · ${recommendation.name} | fmode-product-lab</title>
  182. <style>
  183. * { margin:0; padding:0; box-sizing:border-box; }
  184. body { font-family:'Noto Sans SC',sans-serif; background:#fff; color:#333; line-height:1.6; }
  185. .page { max-width:960px; margin:0 auto; padding:40px 24px 80px; }
  186. h1 { font:800 32px/1.3 'Noto Serif SC',serif; color:#1a1a2e; margin-bottom:4px; }
  187. .tag { font:600 11px/1 monospace; color:#D5B254; letter-spacing:.12em; }
  188. .desc { font:16px/1.7; color:#555; margin:12px 0 32px; max-width:720px; }
  189. .hero-card { background:linear-gradient(135deg,#1a1a2e,#16213e); color:#fff; border-radius:16px; padding:32px; margin:24px 0 32px; }
  190. .hero-card h2 { font:700 24px/1.4 'Noto Serif SC',serif; color:#D5B254; margin-bottom:8px; }
  191. .hero-card .info { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:20px; }
  192. .hero-card .info .kv { font:12px/1.6 monospace; color:#aaa; }
  193. .hero-card .info .kv strong { display:block; font:700 16px/1.4; color:#fff; }
  194. .view h3 { font-size:16px; }
  195. .view p, .view div { font-size:14px; line-height:1.8; }
  196. .foot { margin-top:48px; padding-top:24px; border-top:1px solid #eee; font:12px/1.6 monospace; color:#999; text-align:center; }
  197. </style></head><body>
  198. <div class="page">
  199. <div class="tag">FMODE-PRODUCT-LAB · 新品研发方案</div>
  200. <h1>${recommendation.name}</h1>
  201. <p class="desc">${recommendation.tagline} · ${raw.channel} · 面向${raw.target}</p>
  202. <div class="hero-card">
  203. <h2>✨ 产品概念总结</h2>
  204. <p style="font:15px/1.7;color:#ccc">${recommendation.advantage}</p>
  205. <div class="info">
  206. <div><div class="kv">形态</div><strong>${recommendation.form}</strong></div>
  207. <div><div class="kv">定价</div><strong>${recommendation.price}</strong></div>
  208. <div><div class="kv">渠道</div><strong>${recommendation.channel}</strong></div>
  209. <div><div class="kv">核心成分</div><strong>${raw.keyIngredients.map(i=>i.name).join(' + ')}</strong></div>
  210. </div>
  211. </div>
  212. <h2 style="font:700 20px/1.3 'Noto Serif SC',serif;margin:32px 0 16px;color:#1a1a2e">五视图分析</h2>
  213. ${viewsHTML}
  214. <h2 style="font:700 20px/1.3 'Noto Serif SC',serif;margin:32px 0 16px;color:#1a1a2e">产品概念图(待生成)</h2>
  215. <p style="font:14px/1.6;color:#666;margin-bottom:16px">以下占位——执行以下命令即可生成真实产品图:</p>
  216. <pre style="background:#f5f5f5;padding:16px;border-radius:8px;font:13px/1.7 monospace;overflow-x:auto;margin-bottom:24px">
  217. # 产品外观设计
  218. npx fmode-image --product "${recommendation.name}包装设计,主视图+3/4视图,白底,质感渲染" ~/output/${recommendation.name.toLowerCase().replace(/\s/g,'-')}-product
  219. # 技术爆炸图
  220. npx fmode-image --explode "${recommendation.name}成分+结构爆炸图,${raw.keyIngredients.map(i=>i.name).join('/')}逐层分解" ~/output/${recommendation.name.toLowerCase().replace(/\s/g,'-')}-explode
  221. # 场景插图
  222. npx fmode-image --scene "${raw.target}使用${recommendation.name}的健康生活场景" ~/output/${recommendation.name.toLowerCase().replace(/\s/g,'-')}-scene
  223. # 产品详情页界面
  224. npx fmode-image --app "${recommendation.name}品牌详情页,产品图+成分表+功效说明" ~/output/${recommendation.name.toLowerCase().replace(/\s/g,'-')}-app</pre>
  225. ${imgSection}
  226. <div class="foot">
  227. <p>由 fmode-product-lab 生成 · FmodeAgent · 健康快消新品研发引擎</p>
  228. <p style="margin-top:4px">Powered by fmode-image · 自动读 FMODE_API_KEY</p>
  229. </div>
  230. </div></body></html>`;
  231. return html;
  232. }
  233. // ===== CLI入口 =====
  234. async function main() {
  235. const args = process.argv.slice(2);
  236. if (!args.length || args[0] === '--help' || args.includes('-h')) {
  237. console.log(`
  238. fmode-product-lab v0.1 — 新品研发 Lab
  239. 用法:
  240. node product-lab.mjs --task "描述新品需求" [--output plan.html] # 完整分析+出方案
  241. node product-lab.mjs --list-tasks # 列出示例需求
  242. 示例:
  243. node product-lab.mjs --task "设计一款面向25-35岁白领的抗氧化软糖,电商渠道,添加胶原蛋白肽和维生素C"
  244. node product-lab.mjs --task "代餐奶昔,蛋白含量高,运动人群,线下便利店+线上"
  245. `);
  246. process.exit(0);
  247. }
  248. if (args[0] === '--list-tasks') {
  249. console.log('预置示例任务:');
  250. console.log(' --task "设计一款面向25-35岁白领的抗氧化软糖,含胶原蛋白肽和维生素C,电商渠道"');
  251. console.log(' --task "益生菌固体饮料,儿童肠道健康,3-12岁,母婴渠道"');
  252. console.log(' --task "植物蛋白代餐奶昔,运动健身人群,便利店+线上,高蛋白低卡"');
  253. console.log(' --task "护眼软糖,含叶黄素酯和D3,青少年/白领,全渠道"');
  254. process.exit(0);
  255. }
  256. const taskIdx = args.indexOf('--task');
  257. const task = taskIdx >= 0 ? args[taskIdx + 1] : '设计一款抗氧化软糖,白领人群,含维生素C和胶原蛋白肽';
  258. if (!task) { console.error('--task 需要参数'); process.exit(1); }
  259. const outIdx = args.indexOf('--output');
  260. const outFile = outIdx >= 0 ? args[outIdx + 1] : `product-plan-${Date.now()}.html`;
  261. console.log(`📋 任务: ${task}`);
  262. console.log('🔍 分析中...');
  263. const data = analyze(task);
  264. console.log(`📊 推荐产品: ${data.recommendation.name}`);
  265. console.log(`📄 生成HTLML: ${outFile}`);
  266. const html = renderHTML(data);
  267. mkdirSync(dirname(outFile), { recursive: true });
  268. writeFileSync(outFile, html, 'utf-8');
  269. console.log(`\n✅ 方案已生成: ${outFile}`);
  270. console.log('\n下一步: 生成产品概念图');
  271. console.log(` npx fmode-image --product "..."`);
  272. console.log(` npx fmode-image --explode "..."`);
  273. console.log(` npx fmode-image --scene "..."`);
  274. // 输出供后续调用的JSON
  275. console.log('\n=== PRODUCT_DATA_START ===');
  276. console.log(JSON.stringify({ task, recommendation: data.recommendation, analysis: data.analysis.map(v => v.view), raw: data.raw }));
  277. console.log('=== PRODUCT_DATA_END ===');
  278. }
  279. main();