首页
/ DeerFlow chart-visualization 技能解析:从 26 种图表智能选型到 Node.js 渲染管线

DeerFlow chart-visualization 技能解析:从 26 种图表智能选型到 Node.js 渲染管线

2026-09-06 14:57:56作者:裴锟轩Denise

本篇技术文章基于 DeerFlow 仓库中的 skills/public/chart-visualization 技能包展开,完整讲解该技能“智能选图 → 参数提取 → 脚本生成 → 结果回传”的四步工作流,深入剖析 scripts/generate.js 的图表类型映射、服务端环境变量与地图类图表的特殊调用链,并结合 references/ 目录下的字段规范说明如何构造可复制、可运行的生成载荷。读完本文,你将能够在 DeerFlow 中准确使用这一技能完成数据可视化,并理解其在技能加载体系中的位置。

1. 技能定位与整体工作流

chart-visualization 是 DeerFlow 内置的公共技能之一,位于 skills/public/chart-visualization/SKILL.md。它的元数据声明如下(来自 SKILL.md 的 frontmatter):

name: chart-visualization
description: This skill should be used when the user wants to visualize data.
  It intelligently selects the most suitable chart type from 26 available
  options, extracts parameters based on detailed specifications, and
  generates a chart image using a JavaScript script.
compatibility:
  nodejs: ">=18.0.0"

从 frontmatter 可以看出三点关键事实:该技能面向“用户想要可视化数据”的场景触发;提供 26 种可选图表类型;运行依赖 Node.js >= 18.0.0(脚本使用了原生 fetch API,这也是要求 Node 18+ 的原因)。

技能的整体目录结构为:

skills/public/chart-visualization/
├── SKILL.md                 # 技能主文档,定义四步工作流
├── references/              # 26 份图表字段规范文档(每种图表一个 .md)
│   ├── generate_line_chart.md
│   ├── generate_bar_chart.md
│   ├── generate_district_map.md
│   └── ...
└── scripts/
    └── generate.js          # 图表生成执行脚本

SKILL.md 定义的标准工作流分为四步:智能图表选型(Intelligent Chart Selection)→ 参数提取(Parameter Extraction)→ 图表生成(Chart Generation)→ 结果回传(Result Return)。下文按该骨架逐节展开。

2. 第一步:智能图表选型——26 种类型的数据特征匹配

选型阶段的核心逻辑是“分析数据特征,匹配最合适的图表类型”。SKILL.md 给出了六大类匹配指南,这也是 Agent 决策时的依据:

数据特征 推荐图表类型
时间序列 generate_line_chart(趋势)或 generate_area_chart(累积趋势);两个不同量纲用 generate_dual_axes_chart
对比类 generate_bar_chart(类别)或 generate_column_chart;频率分布用 generate_histogram_chart
部分与整体 generate_pie_chartgenerate_treemap_chart(层级结构)
关系与流向 generate_scatter_chart(相关性)、generate_sankey_chart(流量)、generate_venn_chart(重叠)
地图 generate_district_map(行政区)、generate_pin_map(点位)、generate_path_map(路线)
层级与树状 generate_organization_chart(组织图)或 generate_mind_map(思维导图)

除上述六类外,SKILL.md 还列出了 11 种专用图表:

  • generate_radar_chart:多维对比
  • generate_funnel_chart:流程阶段转化
  • generate_liquid_chart:百分比/进度
  • generate_word_cloud_chart:文本词频
  • generate_boxplot_chartgenerate_violin_chart:统计分布
  • generate_network_graph:复杂节点-边关系
  • generate_fishbone_diagram:因果分析
  • generate_flow_diagram:流程图
  • generate_spreadsheet:表格/透视表,用于结构化数据的交叉汇总

值得注意的是,references/ 目录下 26 个规范文件与上述 26 种图表工具一一对应,例如 references/generate_line_chart.mdreferences/generate_district_map.md。这种“文档即 Schema”的组织方式让 Agent 在选图之后可以按需读取单一规范文件,而无需一次性加载全部 26 份规范。

3. 第二步:参数提取——以 references 为字段的 Single Source of Truth

选型完成后,SKILL.md 要求读取对应图表的 reference 文档来确认必填/可选字段,再把用户输入的数据映射为期望的 args 格式。以折线图为例,references/generate_line_chart.md 定义了:

必填字段

  • data: array<object>,每条记录包含 time(string)与 value(number),多系列时附带 group(string)

可选字段

  • style.lineWidth: number,自定义折线线宽
  • style.backgroundColor: string,背景色
  • style.palette: string[],指定系列颜色
  • style.texture: string,默认 default,可选 default/rough
  • theme: string,默认 default,可选 default/academy/dark
  • width: number,默认 600height: number,默认 400
  • titleaxisXTitleaxisYTitle: string,默认空字符串

此外该文档还给出使用建议:所有系列的时间点应对齐,时间建议按 ISO 格式(如 2025-01-012025-W01),高频数据应先聚合到日/周粒度避免过密。

再看两个有代表性的规范差异:

条形图references/generate_bar_chart.md)引入了两个互斥的分组开关:group(默认 false,并排展示,要求 stack=false)与 stack(默认 true,堆叠展示,要求 group=false),二者均要求数据中包含 group 字段。构造载荷时若同时开启两者,语义上是矛盾的,应按需只保留其一。

电子表格/透视表references/generate_spreadsheet.md)则展示了同一工具内的模式切换:必填仅 data(每行为一个对象,键即列名),但当提供 rowsvalues 字段时自动渲染为数据透视表(交叉表),columns 用于指定列顺序或列分组。

饼/环图references/generate_pie_chart.md)的关键可选参数是 innerRadius(范围 [0,1],默认 0,设为 0.6 即生成环图),并建议在类别数超过 6 个时聚合为“其它”。

行政区地图references/generate_district_map.md)是所有图表中约束最强的:title 必填且不超过 16 字;data.name 必须是中国境内精确到省/市/区/县的行政区关键词;可选字段包括 data.colors(色带,默认 10 色列表)、data.dataTypenumber/enum 决定颜色映射方式)、data.subdistricts[](下钻子区域,需同时开启 showAllSubdistricts);宽高默认值为 1600×1000(大于普通图表的 600×400)。该文档还指出:地图只支持中国境内且依赖高德数据;若配置了 SERVICE_ID 环境变量,生成记录会同步到“我的地图”小程序。

4. 第三步:图表生成——generate.js 源码级剖析

生成阶段调用 scripts/generate.js,载荷格式与执行命令在 SKILL.md 中定义为:

{
  "tool": "generate_chart_type_name",
  "args": {
    "data": [...],
    "title": "...",
    "theme": "...",
    "style": { }
  }
}
node ./scripts/generate.js '<payload_json>'

深入源码可以看到以下实现细节:

(1)图表类型映射表。 脚本开头定义了 CHART_TYPE_MAP,将 25 个 generate_* 工具名映射为服务端识别的短类型名,例如 generate_line_chart → "line"generate_district_map → "district-map"generate_spreadsheet 不在其中——因为地图与表格类走不同的分支逻辑。源码注释标明该映射“consistent with src/utils/callTool.ts”,说明它是与上游 chart-visualization 项目共享的契约。

(2)服务端与鉴权环境变量。 脚本支持两个环境变量:

  • VIS_REQUEST_SERVER:图表生成服务地址,未设置时默认回退到脚本内内置的 AntV 公共服务端点;
  • SERVICE_ID:服务标识,仅在地图类调用链中作为 serviceId 随请求发送,用于生成记录归属(对应行政区地图文档中“我的地图”的同步行为)。

(3)普通图表与地图的两条请求路径。 这是源码中最值得注意的分支:

  • 普通图表generateChartUrl):将 args 展开为请求体,附加 type(短类型名)与 source: "chart-visualization-creator",POST 后校验 data.success,成功则直接返回 data.resultObj——即一张图表图片的 URL
  • 地图类工具generate_district_mapgenerate_pin_mapgenerate_path_map,由 isMapChartTool 列表判定):走 generateMap 分支,请求体结构不同(携带 serviceIdtoolinput),响应结构也更深:脚本会遍历 result.content,把 type === "text" 的条目逐条打印,而非直接输出 URL。这解释了为什么地图类工具在返回形态上与其他 25 种图表不一致。

(4)单条与批量两种输入。 main() 入口允许第一个参数是 内联 JSON 字符串JSON 文件路径(通过 fs.existsSync 判断);解析后的 spec 若为数组则视为批量任务,逐个执行。每个 spec 缺少 tool 字段或工具名无法映射时仅打印错误并 continue,不会中断后续任务;单个图表生成失败也只记录错误(Error generating chart for ${tool})而不影响其他图表。这种“容错式批处理”设计适合 Agent 一次性生成多张图的场景。

(5)可测试性。 脚本末尾通过 module.exports 导出 generateChartUrlgenerateMaphttpPostCHART_TYPE_MAP,便于单元测试对 HTTP 层进行 mock。

// 批量生成的最小示例(内联 JSON,两个 spec)
node ./scripts/generate.js '[
  {"tool":"generate_line_chart","args":{"title":"月度销售","data":[{"time":"2025-01","value":120},{"time":"2025-02","value":150}]}},
  {"tool":"generate_pie_chart","args":{"data":[{"category":"华东","value":40},{"category":"华南","value":35}], "innerRadius":0.6}}
]'

5. 第四步:结果回传与 _meta.spec

按 SKILL.md 约定,脚本成功后标准输出图表图片 URL,Agent 需要向用户同时返回两项内容:图片 URL完整的 args(即用于生成的规格说明)。各 reference 文档的“返回结果”一节进一步说明:服务端在响应的 _meta.spec 字段中回传完整输入规格,供后续编辑与复用——这意味着 Agent 在拿到 URL 后,可以把 _meta.spec 作为可追溯、可再生的“图表源码”一并展示给用户,而不只是给出一张静态图片。

6. 在 DeerFlow 技能体系中的位置

chart-visualization 属于 skills/public/ 下的公共技能目录,与 deep-researchppt-generationdata-analysis 等技能并列。从后端源码结构看,公共技能的目录即技能清单的来源,测试用例 backend/tests/test_skill_catalog.py 中即以 chart-visualization 作为技能目录的样例数据,并验证了按关键词(如输入 chart)能匹配到 chart-visualization 这一条目,说明技能选择是“按名称模糊匹配 + 描述信息”驱动的——这也解释了为什么 SKILL.md 的 description 字段要精确描述触发场景(“user wants to visualize data”)。前端文档 frontend/src/content/zh/harness/skills.mdx 与英文版 en/harness/skills.mdx 也提及该技能,作为技能体系的介绍示例。

因此,一次完整的调用链为:用户提出可视化需求 → Agent 依据 SKILL.md 的选型指南选定工具并读取对应 reference 提取参数 → 在技能目录下执行 node ./scripts/generate.js '<payload_json>'(要求 Node.js >= 18)→ 脚本 POST 到 VIS_REQUEST_SERVER 指向的服务 → 脚本打印图片 URL → Agent 将 URL 与完整 args 一并返回用户。

7. 使用要点与限制小结

  1. 运行环境:需要 Node.js >= 18(SKILL.md frontmatter 的 compatibility 声明),脚本依赖原生 fetch
  2. 26 种工具与 references 一一对应:选图后务必读取对应 references/generate_*.md 确认必填字段,尤其注意行政区地图的强约束(标题 ≤16 字、行政区名精确到省/市/区/县、仅支持中国境内);
  3. 分组参数互斥:条形图的 groupstack 语义互斥,不能同时开启;
  4. 网络依赖:生成动作本身是远程服务调用(默认 AntV 公共端点,可用 VIS_REQUEST_SERVER 覆盖),失败时脚本以 HTTP <status>errorMessage 形式抛出;
  5. 地图类返回结构不同:三种地图工具走 generateMap 分支,输出为 content 文本条目而非裸 URL,展示时需要相应处理;
  6. 可复用性:利用 _meta.spec 回传的完整规格,可对同一图表做二次调整(改主题、改配色、改尺寸),而无需重新提取参数。

综上,DeerFlow 的 chart-visualization 技能通过“SKILL.md 定流程、references 定 Schema、generate.js 定执行”的三层结构,把 26 种图表能力封装为一条可被 Agent 稳定复用的可视化管线:选型有指南、参数有规范、生成有脚本、结果可追溯。

登录后查看全文
热门项目推荐
相关项目推荐