用途
该技能用于指导在 Windmill 平台上编写 R 语言脚本。根据描述,它在编写 R 脚本时「必须使用」。内容属于 Windmill CLI 文档的一部分,围绕脚本的编写、本地预览、元数据同步与部署展开。
主要能力
R 脚本结构
- 使用
<-或=赋值定义main函数,其参数即脚本输入。 - 必须包含
main函数。 - 使用
library()加载包,依赖会被自动解析与安装,不要展示安装说明。 jsonlite始终可用(内部用于参数解析)。- 返回值必须是可 JSON 序列化的。
示例结构:
library(dplyr)
library(jsonlite)
main <- function(x, name = "default", flag = TRUE) {
df <- tibble(x = x, name = name)
result <- df %>% mutate(greeting = paste("Hello", name))
return(toJSON(result, auto_unbox = TRUE))
}
参数与类型映射
- numeric → float/int
- character → string
- logical → bool(使用 TRUE/FALSE)
- list → object/dict
- NULL → null
默认值从函数签名推断:
main <- function(
name, # required string
count = 10, # optional int, default 10
verbose = FALSE # optional bool, default FALSE
) {
# ...
}
资源与变量
使用内置的 Windmill 助手(无需导入):
main <- function() {
# Get a variable
api_key <- get_variable("f/my_folder/api_key")
# Get a resource (returns a list)
db <- get_resource("f/my_folder/postgres_config")
host <- db$host
port <- db$port
return(list(host = host, port = port))
}
输出
从 main 返回任意可 JSON 序列化的值,返回值会成为步骤结果:
main <- function(x) {
# Return a scalar
return(x + 1)
# Or a list (becomes JSON object)
return(list(result = x + 1, status = "ok"))
}
注释注解
#renv_verbose = true— 在依赖解析期间显示详细 renv 输出#renv_install_verbose = true— 在包安装期间显示详细输出#sandbox = true— 在 nsjail 沙箱中运行(需要 nsjail)
使用方式
预览与运行的选择
根据用户意图而非习惯选择命令:
wmill script preview <script_path>— 迭代本地脚本时的默认选择。运行本地文件而不部署。wmill script run <path>— 运行已在工作区部署的脚本。仅当用户明确想测试已部署版本、而非本地修改时使用。wmill generate-metadata— 为已修改的脚本重新生成本地.script.yaml(输入 schema)与.lock(解析后的依赖),并刷新它们在 wmill-lock.yaml 中的内容哈希。仅写本地文件,不是部署。- 部署本地修改到工作区 — 依据仓库接线方式通过 git push 或 wmill sync push 进行。仅当用户明确要求部署/发布/推送时才建议或执行,而不是在他们说「run」「try」「test」时。
判断规则:
- 如果用户说「run the script」「try it」「test it」「does it work」而脚本文件存在本地修改,使用 script preview。不要把脚本推送后再 script run — 推送即部署,为了测试而部署会用未测试的改动覆盖工作区版本。
- 仅在以下情况使用 script run:用户明确说「run the deployed version」/「run what's on the server」;或没有正在编辑的本地脚本(只是调用已有脚本)。
- 仅在用户明确要求部署、发布、推送或上线时使用 sync push;或预览已验证改动且用户希望将其放入工作区。
编辑后保持元数据同步
wmill-lock.yaml 为每个条目跟踪内容哈希。编辑脚本内容(尤其是添加或删除 import 或更改 main 的参数)会使该哈希失效,导致 .lock、.script.yaml 输入 schema 和哈希行过期。此类编辑后运行 wmill generate-metadata(限定到改动范围),使解析后的锁、自动生成的参数 UI(由 .script.yaml 驱动)和 wmill-lock.yaml 都与代码一致。保持过期会在 git-sync 和 CI 中产生虚假差异。
该命令只写本地文件(不是部署),但会重新解析依赖,因此可能提升未固定的版本(与从 UI 部署相同;这是预期行为,不是 bug)。因此默认先提议并在用户同意后运行一次,而不是在每次编辑后静默运行 — 除非项目的 AGENTS.md 选择了自动运行元数据。无论哪种方式,都由执行者运行该命令,而不是用户。运行后,diff 重新生成的 .lock / .script.lock 文件并告知用户哪些依赖版本发生了变化(例如 requests 2.31.0 → 2.32.0),以便在部署前发现不想要的版本提升。在代码中固定版本可保持它们不变。
无路径参数时,generate-metadata 只重新生成内容哈希漂移的条目 — 不是全部。导入会传播:编辑一个被其他脚本导入的脚本会标记每个导入者也过期,因此对共享模块的一行更改可能重新生成许多锁(这是设计使然 — 它们的锁必须反映导入的代码)。如果影响范围超出预期,运行 wmill generate-metadata --dry-run — 它会列出每个过期项及原因(内容变化或 depends on <path>)而不改变任何内容 — 然后用路径参数(wmill generate-metadata f/foo)或 --strict-folder-boundaries 缩小范围。
如果磁盘上的 .lock 和 .script.yaml 已经正确,只是 wmill-lock.yaml 需要刷新哈希(哈希漂移,或引导缺失条目),使用 wmill generate-metadata rehash — 它从磁盘重新记录哈希,无需后端往返,也不改变依赖。
编写后的测试提议
如果用户尚未告诉运行/测试/预览脚本,用一句话作为下一步提议(例如「Want me to run wmill script preview with sample args?」)。不要呈现多选项菜单。
如果用户已在原始请求中要求测试/运行/尝试脚本,跳过提议,直接执行 wmill script preview <path> -d '<args>' — 从脚本声明的参数中选取合理的参数。参数形式因语言而异:代码语言为 main(...),SQL 方言使用自己的占位符语法(PostgreSQL 用 $1,MySQL/Snowflake 用 ?,MSSQL 用 @P1,BigQuery 用 @name 等),Bash 用位置参数 $1、$2、…,PowerShell 用 param(...)。
wmill script preview 不部署,但仍会执行脚本代码并可能产生副作用;当用户要求测试/预览时(或确认执行意图后)运行它。wmill generate-metadata 也不部署 — 它只写本地文件(锁、schema、哈希)— 但运行前先提议(或如果项目的 AGENTS.md 选择自动运行则自动运行)。部署到工作区(git push 或 wmill sync push)是唯一改变远程状态的步骤 — 仅当用户明确要求部署/发布/推送时执行。
若需要可视化地在开发页面打开脚本预览(而非 script preview 的运行并打印结果),使用 preview 技能。
使用 wmill resource-type list --schema 发现可用的资源类型。
适用场景
- 在 Windmill 项目中编写、迭代和测试 R 脚本。
- 需要以资源类型参数安全地传入凭据和配置。
- 需要通过预处理器脚本处理来自 webhook、自定义 HTTP 路由、SQS、WebSocket、Kafka、NATS、MQTT、AMQP、Postgres、GCP Pub/Sub、Azure 或 email 的原始触发数据。
限制
main函数是必需的。- 返回值必须可 JSON 序列化。
#sandbox = true注解需要 nsjail。- 部署相关操作(git push / wmill sync push)是唯一改变远程状态的步骤,仅在明确要求时执行。
- 文档中未提供具体的包版本、定价或平台兼容性的更多细节,这些事实暂未提供。