mcpField
C
carto-create-workflow

carto-create-workflow

github.com/cartodb数据与数据库656 次安装1 周前更新
代码仓库

关于 carto-create-workflow

用于编写和管理可重复运行的定时 CARTO Workflows,涵盖 DAG 设计以及通过命令行或 MCP 操作。还介绍如何用命令行在不同配置间推广工作流。

主要功能

  1. 01规划并构建工作流 DAG
  2. 02检查实时模式和组件
  3. 03验证、运行和安排工作流
  4. 04跨配置复制工作流
  5. 05将工作流发布为 MCP 工具或 API

适用场景

  1. 01创建多步骤数仓转换
  2. 02安排定期工作流运行
  3. 03将工作流从 dev 推广到 prod

MCP 相关

在通过 OAuth 认证的会话中,可使用 MCP 工具创建、验证、运行、安排和发布工作流。令牌认证会话仅开放运行和验证操作;跨配置复制等任务仅支持命令行。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cartodb/agent-skills --skill carto-create-workflow

安装后在 Claude Code 中输入/carto-create-workflow确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
canvas-notes.md
cross-profile-copy.md
mcp-and-api-publish.md
schedule-readd.md
scheduling.md
references/providers/
bigquery.md
databricks.md
snowflake.md

详细介绍

carto-create-workflow

CARTO Workflows 是一款可视化 DAG 编写应用,可将 DAG 编译为数仓 SQL。每个工作流都在已连接的数仓内部运行——执行时不会涉及 CARTO 计算资源。本技能涵盖完整生命周期:构建 DAG(本文的主要内容)、通过 CLI 操作(CRUD、计划),以及跨配置文件复制(dev → prod 晋级、通过 carto workflows copy 实现客户隔离的工作区)——请参阅下方的参考资料。

Workflows 与 Builder 是不同的应用。 本技能针对 Workflows(CARTO 的 DAG/编排应用,URL 中为 /workflows/<id>)。Builder 是单独的地图编写应用(/builder/<id>)。本技能中提到“Workflows 画布”“在 Workflows 中”或“DAG 视图”时,绝不是指 Builder——它们是不同的产品,只共享组织和连接,除此之外毫无关联。工作流输出(包含几何信息的结果表)通常会随后在 Builder 中可视化;这也是这两个应用唯一的关联之处。

对于一次性的临时 SQL,请使用 carto-query-datawarehouse——工作流适用于可重复、按计划运行的多步骤 DAG。

访问路径选择。 交互式生命周期对应经过 OAuth 身份验证的 MCP 会话中的 MCP 工具:create_workflow、update_workflow(method=update|share|unshare|publish|unpublish)、validate_workflow(method=validate|verify|to_sql)、read_workflows(method=list|get|list_mcp_tools|get_mcp_tool)、run_workflow(method=run|status|results)、schedule_workflow(method=add|update|remove),以及 read_workflow_components(method=list|get——组件目录)。以下各阶段适用于两种路径——如果某个步骤指定了 carto workflows 命令,请改用对应的 MCP 工具(例如,将 verify-remote 替换为 validate_workflow method=verify)。脚本编写/CI、Bundle 架构自省(carto workflows schema——MCP 中无对应项)、跨配置文件复制(carto workflows copy——仅 CLI 支持)以及使用日志审计(carto activity query——仅 CLI 支持),请使用 CLI。当服务未连接,或 MCP 会话使用 token 身份验证时,请退回使用 CLI——在这种情况下,编写/管理工具会被隐藏;仅保留 run_workflow 和 validate_workflow。检测信号:carto-basics/references/access-paths.md。

Bundle 结构、组件架构、输入格式和注意事项均可实时获取——通过 CLI(carto workflows schema / components),或在 MCP 路径中通过 read_workflow_components(method=list|get)获取。切勿将其硬编码或想当然。 实时自省才是事实来源。

实时自省(使用任何参考文件之前)。在 MCP 中,read_workflow_components(method=list|get)涵盖组件条目;Bundle/DAG 的 schema 部分仅 CLI 支持。

命令提供的内容
carto workflows schema所有 bundle/DAG 架构部分的索引
carto workflows schema bundle顶层 bundle 结构(id、title、connectionId、config、privacy、tags)。privacy 是一个 $ref——使用 carto workflows schema privacy 获取其结构。最简有效形式:"privacy": { "privacy": "private" }(内部字符串不是单独的 "private"——enums 列出了该内部字段允许的值)。
carto workflows schema config完整的 DAG 配置(schemaVersion、connectionProvider 枚举、nodes、edges、variables、viewport、useCache、executionSettings、schedule)
carto workflows schema node[.source|.customsql]通用节点结构(data.version、data.title 与 data.label);.source 添加 data.id == data.inputs[0].value 不变量;.customsql 提供完整的 customsql 规范
carto workflows schema customsql可复制粘贴的 customsql 节点模板(含 version: "2.0.0")
carto workflows schema edge / schema handlesEdge 结构;以及edge 句柄命名参考(按节点类型、运算符、组件区分的 sourceHandle/targetHandle——对创建有效 edge 至关重要)
carto workflows schema variable变量(参数)结构——{ order, name, type, value, public }
carto workflows schema schedule / schema enums声明式 schedule 元数据;以及所有有效枚举值(节点类型、提供程序、隐私级别、schedule 频率)
carto workflows components list | get <names> --connection <conn> --json组件目录;各组件的 inputs、outputs、notes。在 get 中添加 --input-formats,可获取输入类型的 format、examples、pitfalls。MCP:read_workflow_components。
carto workflows --help完整命令参考,包括各引擎的 schedule 表达式方言

参考资料(仅涵盖实时自省未提供的内容):

  • references/canvas-notes.md — 使用 type: "note" 节点记录画布,包括包围所描述节点的分区容器。实时自省不会提供 note 的架构;可见卡片使用 data.width/data.height(节点级的宽/高为 data + 160/+ 128)——若将其反向处理,每张卡片都会变得过小。
  • references/providers/ — 各数据仓库的详细信息(BigQuery、Snowflake、Databricks):标识符引用、列名大小写、AT 路径。
  • references/scheduling.md — add 与 update 的语义、bundle 级 schedule 警告、活动日志验证。
  • references/mcp-and-api-publish.md — 将工作流发布为 MCP 工具或可调用的 API 端点(MCP:update_workflow method=publish):bundle 要求(native.mcptooloutput + 作用域变量 + 草稿描述)、{{@var}} 与 @var 替换语法、Number → FLOAT64 的 LIMIT 注意事项、发布后验证。
  • references/cross-profile-copy.md — workflows copy 的机制(仅 CLI)、连接映射、--skip-source-validation,以及副本为何总是新工作流。
  • references/schedule-readd.md — schedule 不会随 workflows copy 一起迁移;如何重新添加,包括源引擎与目标引擎不同时的方言转换。

connectionProvider 必须与连接匹配。 config.connectionProvider(schema enums 中的枚举值)必须与连接的实际提供程序匹配——不匹配会生成错误的 SQL 方言,并在运行时出错。可使用 carto connections list --search <name> --json(CLI)或 MCP 路径上的 explore_data(method=list_connections|get_connection)查询。


开发流程

**每个工作流请求都必须按顺序遵循以下 6 个阶段。**不得跳过或调整顺序。

第 1 阶段 — 收集信息
  1. 确定数据源。 如果用户指定了表,请记下。否则,查找可用的数据源 — CLI carto connections list / carto connections describe <connection> "<fqn>",或 MCP explore_data(method=list_connections|list_resources|describe)。

  2. 明确目标。 要进行什么转换?输出是什么?有哪些筛选条件?

  3. 确定连接并记下其 provider(bigquery / snowflake / databricks)— 下一步需要用到。CLI carto connections list 或 MCP explore_data method=list_connections。

  4. 阅读提供商参考文档。

    编写任何节点之前,你 MUST 打开 `references/providers/.md`(例如 `references/providers/bigquery.md`)并从头到尾阅读。这是不可妥协的要求。

    其中包含标识符引用规则、列名大小写行为、Analytics Toolbox 路径、调度表达式方言,以及 customsql $a/$b 占位符要求;这些问题无法通过 validate 检查。它们只有在后续的 verify-remote 失败或运行时 SQL 出错时才会显现,也是后期返工最常见的原因。

    即使接下来的阶段看起来很具体,也不要跳过这一步。不要依赖之前运行时的记忆 — 提供商文件可能会变化。

  5. 获取组件目录 — carto workflows components list --connection <connection> --json(CLI),或 read_workflow_components method=list(MCP)。这是组件名称的唯一真实来源。

第 2 阶段 — 设计方案
  1. 从获取的目录中选择组件。
  2. 获取计划使用的每个组件的架构。 CLI carto workflows components get <name1>,<name2> --connection <connection> --json(或 MCP read_workflow_components method=get)会返回 inputs、outputs 和 notes。仔细阅读 notes 数组 — 其中包含容易忽略的问题。
  3. 获取输入类型格式。 CLI carto workflows components get <component1>,<component2> --connection <connection> --input-formats --json 会返回每种输入/输出类型的 format、examples 和 pitfalls。传入组件名称(例如 native.buffer),而不是输入类型名称。
  4. 设计原则:
    • 全程保留标识符列和空间列。
    • 优先使用原生组件,而不是 native.customsql。这不是可有可无的偏好。 参见原生优先规则。
    • H3/Quadbin 列无需提取几何数据即可用于可视化。
    • 可视化使用标准名称:geom、h3、quadbin。
第 3 阶段 — 提交计划、指出缺项并确认

提交工作流计划(组件、数据流、决策),然后在构建前明确列出所有缺项:

  • 尚未确定的参数 — 阈值、半径、筛选值、时间范围、k-NN 中的 k、聚合列、输出表名称等。
  • 留待用户决定的分析事项 — 显著性水平、距离度量、连接类型、空值处理、去重键、CRS、H3/quadbin 分辨率。
  • 请求中的歧义 — 任何需要你猜测意图的内容。

对于每项缺项,提出合理的默认值并说明理由(例如:“p 值阈值:建议使用 0.05 — 常见的显著性水平”;“缓冲距离:建议使用 1000m — 与输入数据的街区尺度相符”),并询问用户确认或修改。绝不要擅自为面向用户的分析参数选定数值。构建前等待确认。

第 4 阶段 — 构建工作流
  1. 创建工作流文件。通过 carto workflows schema [section] 获取 bundle/node/edge/variable 的结构(从 bundle 开始,然后是 node、node.source、node.customsql、edge、handles)。对于 customsql 节点,请复制 carto workflows schema customsql 中的模板。 如果设置可选的顶层 privacy,它必须是一个对象,而不是字符串:"privacy": { "privacy": "private" }(字段名需要嵌套)。如果不需要,完全省略该字段——"privacy": "private" 会导致 validate 失败。

    源节点(type: "source")——像对待其他组件一样处理 ReadTable:运行 carto workflows components get ReadTable --connection <conn> --json 获取规范的 inputs[*].title 和 inputs[*].description。(ReadTable 因归类为 __internal 而隐藏在 components list 中,但 get 可以正常返回它。)get 无法告诉你的两个仅适用于源节点的规则,都来自 schema node.source:

    • 画布显示名称位于 data.label,而非 data.title。通用节点使用 title;源节点使用 label。
    • data.id 和 data.inputs[0].value 必须是相同的 FQN。

    画布布局与命名——每个节点、每个工作流都要遵循。 这些都不会影响执行,但用户会在 Workflows 中打开 DAG,杂乱的画布会显得质量低下。这些数值简单且固定;直接照做即可。

    • 网格间距为 16 px。 每个 x 和 y 都必须满足 % 16 == 0;偏离网格的值与用户移动过的元素相邻时,会显得略微错位。
    • 按节点类型设置卡片宽度: 源节点为 192 px(12 个单元格),通用组件为 64 px(4 个单元格)。高度固定: 每张卡片高 80 px(5 个单元格),下方有 16 px 的标签(标签位于与下一张卡片之间的间隙中,而非卡片内部)。
    • 卡片间规范间距(右边缘 → 下一张卡片左边缘): 紧凑/线性排列时为 80 px(5 个单元格);扇入时为 128 px(8 个单元格),即连接节点的左侧输入处,来自另一行的边需要留出空间。间距是固定值;左边缘的 Δx 会因卡片宽度而异——通用组件→通用组件线性排列 = Δx 144(9 个单元格),源节点→通用组件 = Δx 272(17 个单元格),通用组件→通用组件扇入排列 = Δx 192(12 个单元格)。
    • 规范垂直间距(卡片主体底部 → 下一张卡片主体顶部): 80 px(5 个单元格)= 16 px 标签 + 64 px 空白。因此,垂直堆叠步骤的顶部到顶部 Δy = 160 px(10 个单元格)。
    • 布局。 源节点堆叠在最左侧列,x 相同,Δy = 144 px(9 个单元格)。主流程位于源节点各行的 y 中线处(源节点位于 y=80 和 y=224 → 流程位于 y=160),这样连接节点接收两路输入时是对称的。
    • data.title 和 data.label 是不同字段——绝不要重复填写。title = 简短且针对实例的动作描述(≤ 15 个字符),说明此节点的用途("Rank"、"Join to score"、"To H3")。label = 新添加节点时该组件的规范类型名称("Join"、"Create Column")——从 components get <name> --json → components[0].title 读取。源节点只会渲染 data.label(表的简短别名:"Candidates"、"Score grid C")。
  2. 每次写入文件后都运行 validate。 它无需联网、速度快,能立即发现结构错误——使用 CLI carto workflows validate workflow.json --json,或 MCP validate_workflow method=validate:

    carto workflows validate workflow.json --json
    

    任何未经 validate 通过检查的保存都应视为有问题——修复后再继续处理下一个节点/边。

    validate 具有权威性。 如果 components get 返回的组件架构与 validate 接受的内容不一致,以 validate 为准,并调整 bundle 以满足它。如果 bundle 已通过验证,不要为了匹配架构而“修复”它。

  3. 在分支边界运行 verify,而不是每次保存后都运行。它会访问数仓(速度较慢,需要身份验证),因此只在整个子 DAG 的结构通过验证且无误后运行一次,并在最后呈现前再运行一次——使用 CLI verify-remote,或 MCP validate_workflow method=verify:

    carto workflows verify-remote workflow.json --connection <connection-name> --json
    

    verify 可以捕获列类型不匹配、缺少表和 AT 解析等问题——这些是 validate 无法发现的。 读取响应。 首先查看 deep.errors——其中的任何内容都会阻止运行时执行。deep.warnings 则更加细分:COMPONENT_INVALID 项描述运行时问题(引擎无法识别的选项、可能导致失败的列引用);SCHEMA_TRACE_SKIPPED 和 VERIFY_SKIPPED 属于诊断信息(静态检查器跳过了此节点,并不表示它有问题)。顶层的 valid 汇总了错误和警告,因此即使工作流仍能成功上传(deep.valid: true 且 deep.errors 为空),它也可能显示为 false。将 deep.errors 为空视为上传的门槛;将顶层 valid: false 视为“需要仔细检查,但通常不会阻止上传”。

  4. 静默修复错误——不要向用户透露实现细节。

  5. 反复迭代,直到完成,且 validate 和最终的 verify 均无问题。

阶段 5 — 呈现结果

总结构建的内容。确认验证成功。等待用户确认。

阶段 6 — 上传到 CARTO
  1. 询问用户是否要上传。
  2. 上传并提供 URL——使用 CLI carto workflows create,或 MCP create_workflow:
    carto workflows create --file workflow.json --verify
    
    连接信息来自 bundle 中的 connectionId——此处不要使用 --connection 标志。
  3. 确认上传时输入没有被静默丢弃。 创建后立即读取已保存的工作流(carto workflows get <id> --json 或 read_workflows method=get),并将 config.nodes[*].data.inputs 与上传的 bundle 进行比较。当输入验证失败时,引擎会在保存时静默拒绝相应的值(最常见的情况是 Selection 输入接收了显示标签,而不是 wire 值——参见获取组件和输入信息中的“显示标签与 wire 值”)。发生这种情况时,validate、verify(当 deep.valid: true 且只有 deep.warnings 时)和 create 都会报告成功;首次打开时,Workflows 会在该节点上显示红色错误指示标记。任何在本地存在但服务器上缺失的 value 都已被静默拒绝——修复源 bundle 并重新上传(不要尝试在服务器上编辑)。
  4. 除非用户明确要求,否则不要自动执行。

原生优先规则

native.customsql 是最后才考虑的工具,而非首选。在编写 customsql 节点之前,先尝试使用原生节点链。仅当满足以下至少一项时,才回退到 customsql:

  • 要表达相同逻辑,原生节点链需要超过约 4-5 个节点。
  • 某项特定操作完全没有对应的原生节点(通过 carto workflows components list 验证)。
  • 表达式确实需要原始数据仓库 SQL(例如 ST_UNION_AGG、LOGICAL_OR、ML.PREDICT、最近 N 项窗口计算)。

常见操作及其对应的原生节点——请先尝试使用这些节点:

如果你会编写类似这样的 SQL……使用原生节点
WHERE x = … / 多条件筛选native.where(谓词)、native.wheresimplified(基于表单的筛选 UI)、native.spatialfilter(按几何匹配/不匹配拆分)、native.select(列投影)
SELECT a, b, c FROM t(多列投影 / 重命名 / 多表达式)native.select(一个节点,自由格式 SELECT 主体)
SELECT ..., expr AS c FROM t(添加一个计算列)native.selectexpression(每个节点添加一列和一个表达式)
GROUP BY k, SUM(x), AVG(y), COUNT(*)(单键)native.groupby——groupby 输入是单个 Column,而非多列。多键分组请使用 native.customsql。
JOIN ... ON a.k = b.k(任意联接类型)native.joinv2
JOIN ... ON ST_INTERSECTS / ST_CONTAINS / ST_WITHINnative.spatialjoin
对两个表执行 MIN(ST_DISTANCE(a.geom, b.geom))native.distance(就地扩充主表,添加 nearest_id + nearest_distance——如果要对两个参考表串联两个 native.distance 节点,请按数据源分别重命名这些列)
ST_BUFFER(geom, d)native.buffer
H3 分箱 / 边界 / 中心 / 多边形填充native.h3frompoint、native.h3boundary(输出几何列名为 <h3col>_geo,例如 index_geo——不是 geom)、native.h3center、native.h3polyfill
ORDER BY ... LIMIT nnative.orderby + native.limit
z 分数 / 标准化native.normalize
加权综合评分native.spatialcompositeunsupervised(加权/PCA)、native.spatialcompositesupervised(目标驱动)
Getis-Ord Gi*、GWR、等值线native.getisord、native.gwr、native.isolines
将最终节点保存到表native.saveastable

以下迹象表明你过早地使用了 customsql——请停下来改为寻找原生节点链:

  • customsql 只包含一个 WHERE 子句、一个 JOIN、包含一两个聚合函数的 GROUP BY,或列投影。
  • 它只封装了一个数据仓库函数(ST_BUFFER、H3_FROMGEOGPOINT 等),而该函数有专用的原生节点。
  • 它唯一的用途是投影/重命名/重新转换列类型——多列请使用 native.select(自由格式 SELECT 主体,一个节点);native.selectexpression 用于添加单个计算列。
  • 你在多个 customsql 节点之间串联 customsql 输出——请改为串联原生节点。

确实应该使用 customsql 时,各数据仓库 SQL 方言容易踩坑之处请参见对应的 references/providers/*.md(BigQuery 反引号、Snowflake 大小写规则、Databricks 标识符)。

Customsql 架构追踪级联——误导性的“使用了表 X,但未提供”错误。 如果 verify-remote 针对 customsql 节点报告 Table "X" used in statement but not provided,而其 sourcea / sourceb 明确已连接,那么根本原因几乎总是上游节点的架构追踪失败——即使上游节点只有警告级别的 COMPONENT_INVALID,也足以中断级联,并在下游 customsql 节点上引发错误。请先修复上游节点;下游错误会随之消失。在上游问题解决之前,不要花时间重写 SQL、更换反引号或尝试别名。


获取组件和输入信息

不要依赖记忆中的组件架构或输入格式。 始终实时获取信息 — carto workflows components list | get <names> [--input-formats] --connection <conn> --json(CLI),或在 MCP 路径上调用 read_workflow_components(method=list|get)(参见上方的内省表)。

请留意响应中的以下内容:

  • 组件 notes — 注意事项:不明显的行为、已弃用状态、输出列命名。
  • 输入 format — 描述预期值形态的文字。
  • 输入 examples — 展示正确用法的具体 JSON 代码片段。
  • 输入 pitfalls — 常见错误、求值顺序、格式特殊情况。
  • 组件 version — 原样复制到所编写节点的 data.version(字符串)中。缺少此字段的通用节点会在 Workflows 中被标记为 OUTDATED。
  • 输入 options(Selection / Enum) — 引擎会精确匹配值。逐字复制每个选项字符串 — 保留大小写,绝不改写措辞或改为标题式大小写(例如,spatialjoin 的 jointype 接受 "inner",不接受 "Inner")。
  • 显示标签与线缆值。 一些组件(例如 native.isolines.mode)带有单独的 optionsText 字段,用于提供便于人类阅读的标签,而 components get --json 可能会在 options 键下显示这些标签。如果 verify-remote 拒绝你填写的“原样”值,并通过 Valid options: <list> 列出大小写相反的选项,则 CLI 提供的是显示标签 — 请通过 carto workflows get <id> --json 与已知可用的工作流交叉核对,找到真实的线缆值。小写或蛇形命名形式(walk、public_transport)在 v2 组件中很常见。
  • verify-remote 可能会同时运行多个组件版本。 如果错误和警告针对同一输入列出互相矛盾的“有效选项”(例如,一个接受 "Walk",另一个接受 "walk"),引擎可能同时对你的节点运行了 v1 和 v2 校验器。请以从 components get 复制的版本为准,并通过上传仅含单个节点的测试工作流进行确认。

对于可能随时间变化的值(组件版本、捆绑包/配置默认值、枚举选项列表),请将 CLI 的 components get / schema 输出视为唯一事实来源 — 切勿在自己的模板中硬编码值。具体来说:

  • config.schemaVersion — 通过 carto workflows schema config --json → properties.schemaVersion.default 读取当前默认值。目前为 "1.0.0"(字符串),但应在编写时解析,以便未来升级时无需更新技能。

提供商专属说明

不同数据仓库使用不同的 SQL 方言、表命名惯例和列大小写规则 — 请始终查看对应的提供商指南(bigquery、snowflake、databricks)。输入类型的格式(Table、Column、ColumnsForJoin、SelectColumnAggregation 等)以及各组件的注意事项(包括“AT 组件需要 verify,而非 validate”这一规则)均来自实时内省 — 请参阅获取组件和输入信息。


运行工作流(构建完成后)

在 CARTO 中创建工作流后,两种方式都支持 CRUD、运行和日程管理。MCP:read_workflows(list|get)、update_workflow(update|share|unshare|publish|unpublish)、run_workflow(run|status|results)、schedule_workflow(add|update|remove)、delete kind=workflow。CLI 快速参考:

carto workflows list --json                                   # list / inspect
carto workflows get <id>
carto workflows update <id> --file workflow.json              # update (replaces whole DAG)
carto workflows schedule add <id> --expression "every day 08:00"
carto workflows schedule remove <id>

始终适用的指南:

  • 工作流在连接所使用的数据仓库上运行。 使用 BigQuery 连接的工作流无法使用 Snowflake 专属 SQL。
  • 日程表达式语法取决于引擎——BQ/CARTO DW 使用自然语言("every day 08:00"),Snowflake/Postgres 使用 cron("0 8 * * *"),Databricks 使用 Quartz cron("0 0 8 * * ?")。请参阅 references/scheduling.md。选错语法类型会导致添加日程时失败。
  • 跨配置文件复制工作流(dev → prod、按客户隔离的工作区)仅支持 CLI——请参阅 references/cross-profile-copy.md。日程不会随之迁移——请参阅 references/schedule-readd.md。
  • 删除工作流不会删除其输出。 工作流在数据仓库中创建的表/视图会保留;如有需要,可使用 carto sql job(或 MCP execute_query)清理。
  • update 会替换整个 DAG。 不支持按节点单独修补。务必先 get,再编辑,最后执行 update。
  • 工作流执行状态记录在活动日志中(事件类型为 WorkflowRun、WorkflowExecutionComplete)。如需监控已安排工作流的运行状况,请通过 carto-query-datawarehouse 查询该日志——参阅该技能中的 references/activity-queries.md。

评论

支持 Markdown