报告转可视化组件流
任务目标
将文本报告数据转换为可视化组件配置,输出严格的MODULE格式。
输入格式
用户需提供以下变量:
${moduleData}: 报告数据内容
图表库规范
1. 折线图 (Chart.Line)
使用条件: 展示数据趋势,需至少5个连续、真实的时间点原始观测值 数据格式:
{
"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个具体数值 数据格式:
{
"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个指标 数据格式:
{
"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(小数) 数据格式:
{
"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:
- 有 3 个以上的对比对象(如 5 个品牌、4 款产品、6 个成本项)
- 每个对象需要展示 3-4 个维度(如品牌 + 定位 + 优势 + 数据)
- 需要横向对比阅读 数据格式:
{
"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个标题 数据格式:
{
"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个指标 数据格式:
{
"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)
使用条件: 展示分阶段的内容规划或执行步骤 数据格式:
{
"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个时间节点 数据格式:
{
"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条警告 数据格式:
{
"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)
使用条件: 展示不同程度的影响内容,如关键转化杠杆、机会优先级 数据格式:
{
"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 代码块包裹。最终输出必须严格遵循以下结构,不允许在代码块外输出任何额外内容:
{
"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"
}
]
}
]
}
分模块规则:
- 每个原文一级标题(## 级别)对应
modules数组中一个独立的模块对象(即一个{"components": [...]}) - 每个模块的第一个组件必须是
{"type": "Title", "content": "<章节子标题>"},用于标识该模块的核心主题(如"消费者需求""竞争格局""政策环境"),而非整个报告的标题;Title组件不参与布局编号,无需layoutRow/layoutCol/data/config字段 - 每个模块的
components数组中,除首个Title外的其他组件仅承载该章节相关的内容 layoutRow在每个模块内独立编号,从 r1 重新开始(Title组件不占用行号)- 整个输出必须是单个合法 JSON 对象,被
```seller-report ... ```包裹;JSON 中不允许出现注释、尾随逗号等非标准语法
布局规范(强约束)
核心规则: 布局只能是一行一个组件或一行两个不同组件,不允许一行放两个相同组件。
组件分类
基础图表类(可两两组合): Chart.Line、Chart.Column、Chart.Pie、DataCard、KeyValueCard
整行展示类(必须独占一行): Chart.List、TextCard、PhaseCard、TimelineCard、AlertCard、InfluenceCard
布局分配原则
- 整行展示类组件必须独占一行
- 基础图表类组件优先考虑两两组合(如 Column+Pie、Column+KeyValueCard、DataCard+KeyValueCard)
- layoutRow 从 r1 开始递增,rowSize/colSize 统一用 "auto"
- 禁止浪费:如果某个模块内存在两个或以上的基础图表类组件各自独占一行,视为布局浪费,必须合并到同一行
- 布局自检(生成每个模块后必须检查):该模块内是否有基础图表类组件可以组合?layoutRow 是否从 r1 连续递增?
- 禁止连续使用同一图表类型:在同一个模块内(不计
Title组件),相邻的两个组件不得使用相同的type。如果内容需要多个同类型组件,必须在中间插入一个不同类型的组件来间隔,或将内容合并到同一个组件中- ❌ 同一模块内第 1 个组件是 TextCard,第 2 个组件也是 TextCard → 违规,应合并为一个 TextCard 或在中间插入其他类型组件
- ❌ 同一模块内连续两个 Chart.List → 违规,应合并为一个 Chart.List 或用其他组件间隔
- ✅ TextCard → KeyValueCard → TextCard(中间有不同类型间隔)
完整性规则(强约束)
报告的每一个章节都必须在可视化输出中有对应的组件体现,禁止跳过任何章节。
- 定性内容必须可视化:产品定位、使用场景、竞争分析等非数字内容,应使用 TextCard、KeyValueCard 等组件承载,不得因"没有数字"而跳过
- 章节覆盖与组件数量:总组件数不得少于原文一级标题(## 级别)数量的 1.5 倍(如 8 个一级标题至少 12 个组件)。每个一级标题至少有一个组件与之对应
组件选型优先级(强约束)
当内容符合以下条件时,必须使用对应组件,禁止用 TextCard/KeyValueCard 替代:
| 内容特征 | 必须使用的组件 | 判断标准 |
|---|---|---|
| 有风险提示、问题警示 | AlertCard | 内容包含"问题 - 后果 - 建议"结构 |
| 有执行步骤、阶段规划 | PhaseCard | 内容包含"第一步/第二步"或"阶段 1/阶段 2" |
| 有影响力分级、优先级排序 | InfluenceCard | 内容包含"高/中/低影响"或"优先级 1/2/3" |
| 有 3+ 对象的多维度对比 | Chart.List | 内容有 3 个以上对象需要对比多个维度 |
| 有时间节点、里程碑 | TimelineCard | 内容包含具体时间点或时间序列 |
工作流程
- 阅读反例约束(强制前置步骤): 使用 read_file 工具阅读
reference/anti-patterns.md文件,理解跨组件的通用反例约束。此步骤不可跳过。 - 内部规划(不输出给用户): 在内部完成以下规划步骤,不要将规划过程输出给用户:
- 仔细阅读
${moduleData},逐一列出所有一级标题和二级标题,形成章节清单 - 识别报告核心主体,规划第一个模块的 KeyValueCard 内容
- 为每个章节选择最合适的组件类型,确保不违反"禁止连续使用同一图表类型"约束
- 逐一对照章节清单,确认覆盖率和组件数量满足要求
- 按布局分配原则执行布局规划
- 仔细阅读
- 生成输出: 最终只输出被
```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": "曝光量"使用