Skill: 1688aiinfra/report-to-visualization (version 0.1.0)

--- name: report-to-visualization description: 将文本报告转换为可视化组件流。当用户需要将报告数据可视化或提到"可视化报告"、"用图表展示"、"图文并茂"时使用。 --- # 报告转可视化组件流 ## 任务目标 将文本报告数据转换为可视化组件配置，输出严格的MODULE格式。 ## 输入格式 用户需提供以下变量： - `${moduleData}`: 报告数据内容 ## 图表库规范 ### 1. 折线图 (Chart.Line) **使用条件**: 展示数据趋势，需至少5个连续、真实的时间点原始观测值 **数据格式**: ```json { "type": "Chart.Line", "data": [{"name": "时间标签，≤6字", "value": 数值, "category": "系列名称，≤8字"}], "config": {"xField": "name", "yField": "value", "title": "图表标题，≤12字"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - 禁止基于平均值、最高/最低值、总计等聚合统计量推测或填充时间序列数据 - `value` 必须为 number 类型（如 `78.5`），禁止使用字符串（如 `"78.5"`） ### 2. 柱状图 (Chart.Column) **使用条件**: 展示数据对比，一个或多个维度有不低于2个具体数值 **数据格式**: ```json { "type": "Chart.Column", "data": [{"name": "分类标签，≤8字", "value": 数值, "category": "指标名称，≤8字"}], "config": {"xField": "name", "yField": "value", "seriesField": "category", "isGroup": true, "title": "图表标题，≤12字"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - `value` 必须为 number 类型（如 `78.5`），禁止使用字符串（如 `"78.5"`），字符串会导致图表排序和轴刻度异常 - 如果原文给出范围值（如"60%-85%"），应拆分为两个数据点（如"线下摆摊(低) 60"和"线下摆摊(高) 85"），或改用 KeyValueCard 展示 - ❌ `{"name": "线下摆摊", "value": "60-85"}` → ✅ 拆分为 `{"name": "摆摊(低)", "value": 60}` 和 `{"name": "摆摊(高)", "value": 85}` - **禁止混合量纲**：同一个柱状图中所有数据点的 value 必须属于同一量纲（如全部是百分比，或全部是绝对数值）。禁止将绝对数值（如曝光量 9500、成交金额 7800）与百分比（如点击率 2.3%、转化率 0.8%）放在同一个图表中，否则百分比的柱子会因数量级差异完全不可见。应拆分为两个独立的 Chart.Column，或将百分比指标改用 DataCard 展示 - ❌ 曝光量(9500) + 点击率(2.3) + 成交金额(7800) 放在同一柱状图 → ✅ 拆分为"流量与销售"柱状图（绝对数值）+ "转化效率"DataCard 或柱状图（百分比） ### 3. DataCard (数据卡片) **使用条件**: 展示核心指标值和环比数据，**不低于4个指标** **数据格式**: ```json { "type": "DataCard", "data": [{"desc": "指标名称，≤12字", "value": "指标值", "cycle": "环比变化值或null"}], "config": {"title": "卡片标题，≤10字"}, "layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - `cycle` 字段**仅用于**填写环比/同比的数值变化（如 `"-0.26%"`、`"+5.3%"`），或填 `null` - 禁止在 `cycle` 中填入描述性文字（如"下降""行业第一""占比47.2%"） - 如果某指标没有环比/同比数据，`cycle` 必须为 `null` - ❌ `{"desc": "斯凯奇份额", "value": "16.8%", "cycle": "行业第一"}` → ✅ `{"desc": "斯凯奇份额", "value": "16.8%", "cycle": null}` ### 4. 饼图 (Chart.Pie) **使用条件**: 展示数据占比，不低于2个指标，value值求和应为100（百分比）或1（小数） **数据格式**: ```json { "type": "Chart.Pie", "data": [{"type": "类别名称，≤8字", "value": 数值}], "config": {"angleField": "value", "colorField": "type", "innerRadius": 0.6, "statistic": {"title": false, "content": false}, "title": "图表标题，≤12字"}, "layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - `value` 必须为 number 类型，禁止字符串 - **禁止推算补全**：如果原文只给出一个占比数据而缺少互补项（如仅提到"35-55岁占61.3%"），不得自行用 100%-61.3%=38.7% 推算出其他类别的占比。应改用 DataCard 或 KeyValueCard 展示已有数据 - ❌ `{"type": "其他年龄", "value": 38.7}` ← 原文无此数据，系推算捏造 ### 5. 表格 (Chart.List) **使用条件**: 当内容满足以下**全部**条件时，**必须**使用 Chart.List 而非 TextCard/KeyValueCard： 1. 有 **3 个以上的对比对象**（如 5 个品牌、4 款产品、6 个成本项） 2. 每个对象需要展示 **3-4 个维度**（如品牌 + 定位 + 优势 + 数据） 3. 需要**横向对比阅读** **数据格式**: ```json { "type": "Chart.List", "data": [{"list": [{"key": "列名，≤10字", "value": "列值，≤20字"}, {"key": "列名", "value": "列值"}]}], "config": {"title": "分组标题，≤10字"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **典型场景**: - ✅ 竞争品牌格局（5 个品牌 × 4 个维度）→ Chart.List - ✅ 成本结构明细（6 个成本项 × 3 个维度）→ Chart.List - ❌ 品牌格局用 TextCard 描述 → 违规 **约束（总计行表达）**: - 如果表格需要展示总计/合计行，总计行的 key-value 结构必须与明细行保持一致，**第一列的 key 不变，value 填"总计/合计"**，后续列正常填写汇总数据 - ❌ `{"list": [{"key": "成本项", "value": "约111.1元/双"}, {"key": "成本", "value": "-"}, {"key": "备注", "value": "含原材料25-40元"}]}` ← 把金额塞进第一列，第二列留空，读者无法理解 - ✅ `{"list": [{"key": "成本项", "value": "总计"}, {"key": "成本", "value": "约111.1元/双"}, {"key": "备注", "value": "含原材料25-40元"}]}` ← 第一列标明"总计"，后续列正常填写数据 ### 6. 文本卡片 (TextCard) **使用条件**: 展示数据总结、趋势洞察、运营建议等定性内容，不少于2个标题 **数据格式**: ```json { "type": "TextCard", "data": [{"title": "标题，≤10字", "text": "内容，尽量2行，30-45字"}], "config": {"title": "卡片标题，≤10字"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束（元素数量）**: - data 数组必须包含 **至少 2 个元素**（即至少 2 个 `{"title": "...", "text": "..."}` 对象），仅 1 个元素时应从原文上下文中提取更多观点/结论来补充，若确实无法补充则考虑将内容合并到相邻的组件中 - ❌ `"data": [{"title": "可行性结论", "text": "..."}]` ← 仅 1 个元素，卡片单薄，信息密度过低 - ✅ `"data": [{"title": "可行性结论", "text": "..."}, {"title": "核心优势", "text": "..."}]` ← 至少 2 个元素，内容充实 **约束（内容聚合原则）**: - **同一主题下的多个子观点必须放在同一个 TextCard 的 data 数组中**，禁止拆分成多个 TextCard - 如果某个大主题下有 2-5 个紧密相关的子主题 → 使用一个 TextCard，data 数组包含多项 - ❌ 将"国家政策的 4 个方面"拆成 4 个独立的 TextCard - ❌ 将"产品创新的 4 个趋势"拆成 2-3 个 TextCard **约束（内容丰富度）**: - TextCard 每项的 `text` 字段内容**尽量保持 2 行左右（30-60 字）**，避免内容过于单薄 - 如果原文信息不足以撑满 2 行，应从原文上下文中提取补充信息（如具体数据、应用场景、代表案例等）进行丰富 - ❌ `"text": "北欧极简、无性别设计"` ← 仅 1 行，信息密度过低 - ✅ `"text": "北欧极简、无性别设计成为主流趋势，通勤休闲轻运动场景无缝切换，满足全年龄段穿搭需求"` ← 约 2 行，信息丰富 ### 7. 键值对卡片 (KeyValueCard) **使用条件**: 展示不低于2个分组，每个分组不低于2个指标 **数据格式**: ```json { "type": "KeyValueCard", "data": [{"title": "分组标题，≤8字", "list": [{"key": "指标名称，≤10字", "value": "格式化后的指标值，≤15字"}]}], "config": {"title": "卡片主标题，≤10字"}, "layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - data 数组必须包含 **至少 2 个分组**（即至少 2 个 `{"title": "...", "list": [...]}` 对象），仅 1 个分组时应改用 DataCard 或 TextCard - 每个分组的 list 数组应包含 **至少 2 个指标** - ❌ `"data": [{"title": "唯一分组", "list": [...]}]` ← 仅 1 个分组独占一整张卡片，信息密度过低 ### 8. 阶段卡片 (PhaseCard) **使用条件**: 展示分阶段的内容规划或执行步骤 **数据格式**: ```json { "type": "PhaseCard", "data": [{"phaseNumber": "阶段序号，≤5字", "phaseName": "阶段名称，≤6字", "focusPoints": [{"label": "重点项标签，≤6字", "content": "重点项内容，≤50字"}]}], "config": {"title": "卡片标题，≤10字", "theme": "主题色，如'blue'"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - 阶段数控制在 **3-5 个**，避免过度拆分导致信息碎片化 - 每个阶段应包含 **2-3 个 focusPoints**，体现该阶段的多维度工作内容 - 可将相关性强的建议合并为同一阶段（如"产品定位+技术创新"合并为"产品升级"阶段） - ❌ 将 6 条建议拆成 6 个阶段，每阶段仅 1 个 focusPoint → ✅ 合并为 3-4 个阶段，每阶段 2-3 个 focusPoints ### 9. 时间轴 (TimelineCard) **使用条件**: 展示时间轴内容，如里程碑规划，**不低于3个时间节点** **数据格式**: ```json { "type": "TimelineCard", "data": [{"month": "月份，≤6字", "title": "里程碑标题，≤8字", "description": "详细描述，≤40字", "target": "目标值，≤12字", "status": "completed或in-progress"}], "config": {"title": "标题，≤10字", "orientation": "horizontal或vertical"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - data 数组必须包含 **至少 3 个时间节点**，少于 3 个节点无法体现时间线的连续感和阶段递进关系 - 仅 1-2 个时间节点时，应从原文上下文中提取更多里程碑/阶段来补充，若确实无法补充则改用 PhaseCard 或 TextCard 承载 - ❌ `"data": [{"month": "1月", ...}]` ← 仅 1 个节点，无法构成时间轴 - ❌ `"data": [{"month": "1月", ...}, {"month": "6月", ...}]` ← 仅 2 个节点，时间线过于稀疏 - ✅ `"data": [{"month": "1月", ...}, {"month": "3月", ...}, {"month": "6月", ...}]` ← 至少 3 个节点，时间线完整 ### 10. 警告卡片 (AlertCard) **使用条件**: 展示警告内容，如风险提示、注意事项，**不低于2条警告** **数据格式**: ```json { "type": "AlertCard", "data": [{"issue": "问题描述，≤25字", "consequence": "后果，≤40字", "suggestion": "建议，≤30字", "level": "warning或info或error或success"}], "config": {"title": "卡片标题，≤10字", "showIcon": true}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - data 数组必须包含 **至少 2 条警告**，仅 1 条警告时应从原文上下文中提取更多风险/注意事项来补充，若确实无法补充则改用 TextCard 承载 - ❌ `"data": [{"issue": "唯一的风险提示", ...}]` ← 仅 1 条警告，信息密度过低，卡片单薄 - ✅ `"data": [{"issue": "风险1", ...}, {"issue": "风险2", ...}]` ← 至少 2 条，信息充实 ### 11. 影响卡片 (InfluenceCard) **使用条件**: 展示不同程度的影响内容，如关键转化杠杆、机会优先级 **数据格式**: ```json { "type": "InfluenceCard", "data": [{"name": "因素名称，≤10字", "influenceLevel": 1-5, "influenceLabel": "影响力标签，≤4字", "focusPoints": [{"label": "关注点标签，≤6字", "content": "关注点内容，≤50字"}], "warnings": [{"icon": "warning或info", "label": "警告标签，≤6字", "content": "警告内容，≤40字"}], "priority": 1-3}], "config": {"title": "主标题，≤12字"}, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ``` **约束**: - 每个影响因素应包含 **2-3 个 focusPoints**，从不同维度（如技术/商业/用户/风险）展示影响 - 如果原文对某个因素只有一句话描述，应从原文上下文中提取补充信息，而非仅用 1 个 focusPoint - ❌ 每个因素仅 1 个 focusPoint，信息密度过低 → ✅ 每个因素 2-3 个 focusPoints ## 输出格式 按报告章节分模块输出，所有模块统一组织在一个 JSON 对象的 `modules` 数组中，并使用 ` ```seller-report ` 代码块包裹。**最终输出必须严格遵循以下结构，不允许在代码块外输出任何额外内容**： ```seller-report { "modules": [ { "components": [ { "type": "Title", "content": "<章节子标题，≤8字，禁止以\"模块一\"、\"##\"等字符开头，应体现该章节的核心主题>" }, { "type": "<图表组件类型，如 Chart.Column / DataCard / KeyValueCard 等>", "data": [ ... ], "config": { ... }, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" }, { "type": "<图表组件类型>", "data": [ ... ], "config": { ... }, "layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto" } ] }, { "components": [ { "type": "Title", "content": "<下一章节子标题>" }, { "type": "<图表组件类型>", "data": [ ... ], "config": { ... }, "layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto" } ] } ] } ``` **分模块规则**： 1. 每个原文一级标题（## 级别）对应 `modules` 数组中一个独立的模块对象（即一个 `{"components": [...]}`） 2. 每个模块的第一个组件**必须**是 `{"type": "Title", "content": "<章节子标题>"}`，用于标识该模块的核心主题（如"消费者需求""竞争格局""政策环境"），而非整个报告的标题；`Title` 组件不参与布局编号，无需 `layoutRow`/`layoutCol`/`data`/`config` 字段 3. 每个模块的 `components` 数组中，除首个 `Title` 外的其他组件仅承载该章节相关的内容 4. `layoutRow` 在每个模块内独立编号，从 r1 重新开始（`Title` 组件不占用行号） 5. 整个输出必须是**单个合法 JSON 对象**，被 ` ```seller-report ... ``` ` 包裹；JSON 中不允许出现注释、尾随逗号等非标准语法 ## 布局规范（强约束） **核心规则**: 布局只能是一行一个组件或一行两个不同组件，不允许一行放两个相同组件。 ### 组件分类 **基础图表类**（可两两组合）: Chart.Line、Chart.Column、Chart.Pie、DataCard、KeyValueCard **整行展示类**（必须独占一行）: Chart.List、TextCard、PhaseCard、TimelineCard、AlertCard、InfluenceCard ### 布局分配原则 1. 整行展示类组件必须独占一行 2. 基础图表类组件优先考虑两两组合（如 Column+Pie、Column+KeyValueCard、DataCard+KeyValueCard） 3. layoutRow 从 r1 开始递增，rowSize/colSize 统一用 "auto" 4. **禁止浪费**：如果某个模块内存在两个或以上的基础图表类组件各自独占一行，视为布局浪费，必须合并到同一行 5. **布局自检**（生成每个模块后必须检查）：该模块内是否有基础图表类组件可以组合？layoutRow 是否从 r1 连续递增？ 6. **禁止连续使用同一图表类型**：在同一个模块内（不计 `Title` 组件），相邻的两个组件不得使用相同的 `type`。如果内容需要多个同类型组件，必须在中间插入一个不同类型的组件来间隔，或将内容合并到同一个组件中 - ❌ 同一模块内第 1 个组件是 TextCard，第 2 个组件也是 TextCard → 违规，应合并为一个 TextCard 或在中间插入其他类型组件 - ❌ 同一模块内连续两个 Chart.List → 违规，应合并为一个 Chart.List 或用其他组件间隔 - ✅ TextCard → KeyValueCard → TextCard（中间有不同类型间隔） ## 完整性规则（强约束） **报告的每一个章节都必须在可视化输出中有对应的组件体现，禁止跳过任何章节。** 1. **定性内容必须可视化**：产品定位、使用场景、竞争分析等非数字内容，应使用 TextCard、KeyValueCard 等组件承载，不得因"没有数字"而跳过 2. **章节覆盖与组件数量**：总组件数不得少于原文一级标题（## 级别）数量的 1.5 倍（如 8 个一级标题至少 12 个组件）。每个一级标题至少有一个组件与之对应 ## 组件选型优先级（强约束） 当内容符合以下条件时，**必须**使用对应组件，禁止用 TextCard/KeyValueCard 替代： | 内容特征 | 必须使用的组件 | 判断标准 | |---------|--------------|---------| | 有风险提示、问题警示 | AlertCard | 内容包含"问题 - 后果 - 建议"结构 | | 有执行步骤、阶段规划 | PhaseCard | 内容包含"第一步/第二步"或"阶段 1/阶段 2" | | 有影响力分级、优先级排序 | InfluenceCard | 内容包含"高/中/低影响"或"优先级 1/2/3" | | 有 3+ 对象的多维度对比 | Chart.List | 内容有 3 个以上对象需要对比多个维度 | | 有时间节点、里程碑 | TimelineCard | 内容包含具体时间点或时间序列 | ## 工作流程 1. **阅读反例约束**（强制前置步骤）: 使用 read_file 工具阅读 `reference/anti-patterns.md` 文件，理解跨组件的通用反例约束。**此步骤不可跳过。** 2. **内部规划**（不输出给用户）: 在内部完成以下规划步骤，**不要将规划过程输出给用户**： - 仔细阅读 `${moduleData}`，逐一列出所有一级标题和二级标题，形成章节清单 - 识别报告核心主体，规划第一个模块的 KeyValueCard 内容 - 为每个章节选择最合适的组件类型，确保不违反"禁止连续使用同一图表类型"约束 - 逐一对照章节清单，确认覆盖率和组件数量满足要求 - 按布局分配原则执行布局规划 3. **生成输出**: **最终只输出被 ` ```seller-report ... ``` ` 包裹的单个 JSON 对象**，不输出任何分析过程、章节清单、规划说明等中间内容。用户看到的应该只有这一个 ` ```seller-report ` 代码块。 ## 重要约束 - 内容严格来自报告数据，禁止捏造数据 - 对于表现不佳的数据，避免"立即暂停""彻底下架""完全停止"等极端措辞，采用"诊断—优化—再决策"的渐进式策略 - 如果报告数据未提供有效信息，直接返回"暂无内容" - **禁止裸数字**（全局约束，适用于所有组件）：任何展示给用户的数值都必须附带含义标注，让用户无需上下文即可理解该数值代表什么。具体要求： - 数值必须包含单位或含义前缀/后缀（如"销量倍数 ×2.1"而非"×2.1"，"毛利率 35%"而非"35%"） - 如果字段本身的 key/label 已经明确了含义（如 `"desc": "毛利率", "value": "35%"`），则 value 中无需重复标注 - 但如果数值出现在缺乏语义上下文的字段中（如 TimelineCard 的 `target`、DataCard 的 `value`），必须在数值中内嵌含义 - ❌ `"target": "×2.1"` ← 无法理解 2.1 是什么的倍数 - ✅ `"target": "搜索量×2.1"` 或 `"target": "销量增长2.1倍"` - ❌ `"value": "9500"` ← 不知道 9500 是什么 - ✅ `"value": "9500次曝光"` 或配合 `"desc": "曝光量"` 使用


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