动作节点
非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) 上的文件操作 |
标准属性
每个动作节点都继承这些共享属性:
身份
| 属性 | 类型 | 描述 |
|---|---|---|
id | string | 唯一标识符 |
name | string | 显示名称 |
description | string? | 可选的工具提示描述 |
错误处理
| Mode | 行为 |
|---|---|
stop | 在错误时停止工作流(默认) |
continue | 记录错误并继续到下一个节点 |
retry | 使用可配置的重试次数(1-10)和延迟(毫秒)进行重试 |
fallback | 在错误时使用备用值 |
追踪
| 属性 | 类型 | 描述 |
|---|---|---|
enabled | boolean | 启用详细执行跟踪 |
logLevel | none | error | info | debug | 日志详细程度 |
执行控制
| 属性 | 类型 | 描述 |
|---|---|---|
timeout | number | 超时时间,单位为 ms (默认值: 30000) |
condition | string? | 如果表达式评估为 false,则跳过节点 |
输入/输出映射
| 属性 | 类型 | 描述 |
|---|---|---|
inputMapping | Record<string, string>? | 将状态字段映射到节点输入 |
outputKey | string | 结果存储在工作流状态中的键 |
节点参考
触发器节点 🎯
工作流入口点。每个工作流都从触发器节点开始。有关完整详细信息,请参阅专门的触发器指南。
| 触发类型 | 描述 |
|---|---|
| 手动 | 用户通过聊天输入启动 |
| Webhook | HTTP 端点 (POST/GET) 可选认证 |
| 定时 | 基于 Cron 的定时,支持时区 |
| 事件 | 外部系统事件,支持 JSONPath 过滤 |
HTTP Node 🌐
进行 HTTP 请求到外部 APIs,并提供完整的认证、请求头、请求体和响应处理。
配置:
| 属性 | 类型 | 描述 |
|---|---|---|
method | GET, POST, PUT, PATCH, DELETE | HTTP 方法 |
url | string | URL 带 {{variable}} 插值 |
auth | object | 认证 (无, bearer, 基本, api_key) |
headers | Record<string, string> | 请求头 |
body | object | 请求体 (无, json, form, raw) |
response | object | 响应处理 (json, text, binary) 带可选的 JSONPath 提取 |
rateLimit | object? | 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 | 设置, 合并, 删除 | 变量操作 |
variables | Variable[] | 要设置的变量列表 |
envVars | object? | 从 .env 文件加载,带可选前缀过滤器 |
变量类型: string, number, boolean, json, expression
标记为 isSecret: true 的变量在日志和用户界面中被遮蔽。
转换节点 ⚙️
使用表达式或内置操作转换数据。
转换类型:
| 类型 | 描述 |
|---|---|
jsonpath | JSONPath 表达式 |
jmespath | JMESPath 表达式 |
template | 带插值的字符串模板 |
javascript | JavaScript 表达式 |
内置操作: pick, omit, rename, flatten, sort, unique
类型强制转换目标: string, number, boolean, array, object
Switch 节点 🔀
具有多个输出端口的条件分支。每个条件都映射到节点上的一个独立输出端口。

配置:
| 属性 | 类型 | 描述 |
|---|---|---|
evaluationMode | first_match | all_match | 在第一次匹配时停止或评估所有条件 |
conditions | SwitchCondition[] | 带有输出端口的条件列表 |
defaultBranch | string? | 当没有条件匹配时的输出端口 |
条件运算符: 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,可选地使用 batchSize 和 delayBetween 进行并发迭代。
结果聚合: 当 results.collect 为真时,迭代结果将聚合到一个数组中,位于 results.aggregationKey。
合并节点 🔗
将多个并行分支合并回单个流。具有多个输入端口。
合并模式:
| 模式 | 行为 |
|---|---|
wait_all | 等待所有传入分支 |
wait_any | 当第一个分支完成时继续 |
wait_n | 在 N 个分支完成后继续 |
组合策略: array, object, first, last
可选超时,具有 continue 或 error 行为。
等待节点 ⏱️
暂停工作流执行。
等待类型:
| 类型 | 描述 |
|---|---|
fixed | 等待固定时长(毫秒、秒、分钟、小时) |
until | 等待直到特定时间戳 |
webhook | 等待传入的 webhook |
condition | 按间隔轮询条件 |
代码节点 💻
在一个沙盒化的 boa_engine runtime 中执行自定义 JavaScript。图状态作为全局 input 对象注入。
配置:
| 属性 | 类型 | 描述 |
|---|---|---|
language | javascript, typescript | 代码语言 |
code | string | 要执行的代码 |
sandbox | object | 安全限制(网络、文件系统、内存、时间) |
沙盒默认值:
| 限制 | 默认值 |
|---|---|
| 网络访问 | 否 |
| 文件系统访问 | 否 |
| 内存限制 | 128 MB |
| 时间限制 | 5000 ms |
数据库节点 🗄️
使用连接池和参数化查询执行数据库操作。
支持的数据库:
| 数据库 | 驱动 | 特性 |
|---|---|---|
| PostgreSQL | sqlx (postgres) | 异步连接池, 参数化查询, 行到-JSON |
| MySQL | sqlx (mysql) | 异步连接池, 参数化查询, 行到-JSON |
| SQLite | sqlx (sqlite) | 异步连接池, 参数化查询, 行到-JSON |
| MongoDB | mongodb | 原生 BSON, 查找/插入/更新/删除 |
| Redis | redis | GET, 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 | 生成内容 |
|---|---|---|
| HTTP | reqwest | 异步 HTTP 请求,支持认证、请求头、请求体、JSONPath 提取 |
| 数据库 | sqlx / mongodb / redis | 连接池、参数化查询、Redis 命令 |
| 电子邮件 | lettre / imap | SMTP 发送,支持 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))
});