动作节点

非LLM程序化节点,用于确定性工作流操作。动作节点通过处理数据转换、API集成、控制流和自动化逻辑来补充LLM agents。

概述

动作节点与LLM agent nodes在视觉上有所不同——它们使用独特的颜色和图标,使工作流易于浏览。每种节点类型处理特定类别的操作,从HTTP请求到数据库查询再到条件分支。

所有动作节点都共享一组标准属性,用于错误处理、追踪、执行控制和I/O映射。它们支持字符串字段中的{{variable}}插值,并自动接收前驱节点的输出。

动作节点工作流

可用节点

节点图标颜色描述
触发器🎯靛蓝色工作流入口点(手动、webhook、计划、事件)
HTTP🌐蓝色向外部 APIs 发出 HTTP 请求
设置📝紫色定义和操作工作流状态变量
转换⚙️粉色使用表达式或内置操作转换数据
切换🔀琥珀色基于条件进行条件分支
循环🔄翠绿色迭代数组或重复操作
合并🔗青色将多个分支合并回单个流
等待⏱️灰色暂停工作流一段时间或等待条件满足
代码💻红色在沙盒运行时中执行自定义 JavaScript
数据库🗄️青绿色数据库操作 (PostgreSQL, MySQL, SQLite, MongoDB, Redis)
电子邮件📧玫瑰色通过 SMTP 发送电子邮件或通过 IMAP 监控
通知🔔橙色发送到 Slack, Discord, Teams, 或 webhooks
RSS📡酸橙色监控 RSS/Atom feed 以获取新条目
文件📁天蓝色本地或云存储 (S3, GCS, Azure) 上的文件操作

标准属性

每个动作节点都继承这些共享属性:

身份

属性类型描述
idstring唯一标识符
namestring显示名称
descriptionstring?可选的工具提示描述

错误处理

Mode行为
stop在错误时停止工作流(默认)
continue记录错误并继续到下一个节点
retry使用可配置的重试次数(1-10)和延迟(毫秒)进行重试
fallback在错误时使用备用值

追踪

属性类型描述
enabledboolean启用详细执行跟踪
logLevelnone | error | info | debug日志详细程度

执行控制

属性类型描述
timeoutnumber超时时间,单位为 ms (默认值: 30000)
conditionstring?如果表达式评估为 false,则跳过节点

输入/输出映射

属性类型描述
inputMappingRecord<string, string>?将状态字段映射到节点输入
outputKeystring结果存储在工作流状态中的键

节点参考

触发器节点 🎯

工作流入口点。每个工作流都从触发器节点开始。有关完整详细信息,请参阅专门的触发器指南

触发类型描述
手动用户通过聊天输入启动
WebhookHTTP 端点 (POST/GET) 可选认证
定时基于 Cron 的定时,支持时区
事件外部系统事件,支持 JSONPath 过滤

HTTP Node 🌐

进行 HTTP 请求到外部 APIs,并提供完整的认证、请求头、请求体和响应处理。

配置:

属性类型描述
methodGET, POST, PUT, PATCH, DELETEHTTP 方法
urlstringURL 带 {{variable}} 插值
authobject认证 (无, bearer, 基本, api_key)
headersRecord<string, string>请求头
bodyobject请求体 (无, json, form, raw)
responseobject响应处理 (json, text, binary) 带可选的 JSONPath 提取
rateLimitobject?Rate limiting (每个窗口的请求数)

示例:

{
  "type": "http",
  "name": "Fetch User Data",
  "method": "GET",
  "url": "https://api.example.com/users/{{userId}}",
  "auth": {
    "type": "bearer",
    "bearer": { "token": "{{API_TOKEN}}" }
  },
  "headers": { "Accept": "application/json" },
  "body": { "type": "none" },
  "response": { "type": "json", "jsonPath": "$.data" },
  "errorHandling": { "mode": "retry", "retryCount": 3, "retryDelay": 1000 },
  "mapping": { "outputKey": "userData" }
}

设置节点 📝

定义和操作工作流状态变量。支持字面值、表达式和秘密。

配置:

属性类型描述
mode设置, 合并, 删除变量操作
variablesVariable[]要设置的变量列表
envVarsobject?从 .env 文件加载,带可选前缀过滤器

变量类型: string, number, boolean, json, expression

标记为 isSecret: true 的变量在日志和用户界面中被遮蔽。

转换节点 ⚙️

使用表达式或内置操作转换数据。

转换类型:

类型描述
jsonpathJSONPath 表达式
jmespathJMESPath 表达式
template带插值的字符串模板
javascriptJavaScript 表达式

内置操作: pick, omit, rename, flatten, sort, unique

类型强制转换目标: string, number, boolean, array, object

Switch 节点 🔀

具有多个输出端口的条件分支。每个条件都映射到节点上的一个独立输出端口。

Switch 属性面板

配置:

属性类型描述
evaluationModefirst_match | all_match在第一次匹配时停止或评估所有条件
conditionsSwitchCondition[]带有输出端口的条件列表
defaultBranchstring?当没有条件匹配时的输出端口

条件运算符: eq, neq, gt, lt, gte, lte, contains, startsWith, endsWith, matches, in, empty, exists

示例:

{
  "type": "switch",
  "evaluationMode": "first_match",
  "conditions": [
    { "id": "ok", "name": "Success", "field": "status", "operator": "eq", "value": "success", "outputPort": "success" },
    { "id": "err", "name": "Error", "field": "status", "operator": "eq", "value": "error", "outputPort": "error" }
  ],
  "defaultBranch": "unknown"
}

循环节点 🔄

迭代数组,重复固定次数,或在条件满足时循环。

循环类型:

类型描述
forEach从状态中迭代数组
while当条件为真时循环
times重复 N 次

并行执行: 启用 parallel.enabled,可选地使用 batchSizedelayBetween 进行并发迭代。

结果聚合:results.collect 为真时,迭代结果将聚合到一个数组中,位于 results.aggregationKey

合并节点 🔗

将多个并行分支合并回单个流。具有多个输入端口。

合并模式:

模式行为
wait_all等待所有传入分支
wait_any当第一个分支完成时继续
wait_n在 N 个分支完成后继续

组合策略: array, object, first, last

可选超时,具有 continueerror 行为。

等待节点 ⏱️

暂停工作流执行。

等待类型:

类型描述
fixed等待固定时长(毫秒、秒、分钟、小时)
until等待直到特定时间戳
webhook等待传入的 webhook
condition按间隔轮询条件

代码节点 💻

在一个沙盒化的 boa_engine runtime 中执行自定义 JavaScript。图状态作为全局 input 对象注入。

配置:

属性类型描述
languagejavascript, typescript代码语言
codestring要执行的代码
sandboxobject安全限制(网络、文件系统、内存、时间)

沙盒默认值:

限制默认值
网络访问
文件系统访问
内存限制128 MB
时间限制5000 ms

数据库节点 🗄️

使用连接池和参数化查询执行数据库操作。

支持的数据库:

数据库驱动特性
PostgreSQLsqlx (postgres)异步连接池, 参数化查询, 行到-JSON
MySQLsqlx (mysql)异步连接池, 参数化查询, 行到-JSON
SQLitesqlx (sqlite)异步连接池, 参数化查询, 行到-JSON
MongoDBmongodb原生 BSON, 查找/插入/更新/删除
RedisredisGET, SET, DEL, HGET, HSET, LPUSH, LRANGE

连接字符串被视为秘密并在日志中被屏蔽。

电子邮件节点 📧

通过 SMTP 发送电子邮件或通过 IMAP 监控传入电子邮件。

发送模式 (SMTP):

  • TLS/SSL 支持
  • 身份验证
  • 收件人/抄送/密送收件人
  • HTML 或纯文本正文
  • 主题和正文中的 {{variable}} 插值
  • 来自状态的文件附件

监控模式 (IMAP):

  • 文件夹选择(默认:INBOX)
  • 过滤器:发件人、主题、日期范围、仅未读
  • 处理后标记为已读

通知节点 🔔

向消息平台发送通知。

渠道: Slack, Discord, Microsoft Teams, 自定义 webhook

消息格式: 纯文本、markdown、平台特定块(Block Kit, Embeds, Adaptive Cards)

RSS 节点 📡

监控 RSS/Atom 订阅源以获取新条目。

  • 可配置的轮询间隔
  • 关键词、作者、类别和日期过滤器
  • 已查看项目跟踪以避免重复
  • 可选的完整内容或仅摘要

文件节点 📁

本地或云存储上的文件操作。

操作: 读取、写入、删除、列出

云提供商: Amazon S3, Google Cloud Storage, Azure Blob Storage

文件格式: JSON, CSV, XML, 文本, 二进制(带 CSV 解析选项,用于分隔符、标题、引用)


变量插值

操作节点中的所有字符串字段都支持 {{variable}} 语法以实现动态值:

https://api.example.com/users/{{userId}}
Bearer {{API_TOKEN}}
Hello {{user.name}}, your order {{orderId}} is ready.

变量在执行时从工作流状态中解析。点表示法 (user.name) 访问嵌套值。

多端口节点

两种节点类型具有动态端口计数:

  • Switch — 每个条件一个输出端口,外加一个可选的默认端口
  • Merge — 多个输入端口,每个传入分支一个

这些端口在节点上以可视化方式表示,并连接到不同的下游/上游节点。


代码生成

操作节点与 LLM agents 一起编译为生产 Rust 代码。依赖项会自动检测并添加到生成的 Cargo.toml 中。

节点Crate生成内容
HTTPreqwest异步 HTTP 请求,支持认证、请求头、请求体、JSONPath 提取
数据库sqlx / mongodb / redis连接池、参数化查询、Redis 命令
电子邮件lettre / imapSMTP 发送,支持 TLS;IMAP 监控,支持搜索过滤器
代码boa_engine嵌入式 JavaScript 执行,将图状态作为 input 对象
设置原生变量赋值(字面量、表达式、密钥)
转换原生映射、过滤、排序、归约、扁平化、分组、选取、合并、模板
合并原生分支组合 (waitAll, waitAny, append)

所有生成的代码都使用 adk-graph FunctionNode 闭包并使用 GraphError::NodeExecutionFailed 进行错误处理。

生成的代码示例(HTTP 节点):

let http_node = FunctionNode::new("fetch_data", |ctx| async move {
    let client = reqwest::Client::new();
    let resp = client.get("https://api.example.com/data")
        .bearer_auth(&ctx.get("API_TOKEN").unwrap_or_default())
        .send().await
        .map_err(|e| GraphError::NodeExecutionFailed {
            node: "fetch_data".into(),
            message: e.to_string(),
        })?;
    let body: serde_json::Value = resp.json().await?;
    Ok(NodeOutput::new().with_update("apiData", body))
});

生成的代码示例(代码节点):

let code_node = FunctionNode::new("process", |ctx| async move {
    let mut js_ctx = boa_engine::Context::default();
    // Graph state injected as global `input` object
    // User code executed in thread-isolated sandbox
    Ok(NodeOutput::new().with_update("result", output))
});

上一页← Studio | 下一页触发器 →