アクションノード
adk-action crate は、グラフベースのワークフローで使用される14種類のアクションノード型を定義します。各ノード型は、個別の操作(HTTP 呼び出し、データ変換、条件分岐など)を表し、adk-graph の ActionNodeExecutor を介して有向グラフに組み込むことができます。
概要
アクションノードは、ビジュアルおよびプログラムによるワークフローグラフの構成要素です。以下を提供します。
- 型付き操作 — 一般的なワークフローパターンを網羅する14種類のノード型
- StandardProperties — エラー処理、トレーシング、データマッピングのための共有設定
- 変数の補間 — 動的な値のための
{{variable}}構文 - グラフ統合 —
adk-graphのActionNodeExecutorによって実行
インストール
[dependencies]
adk-action = "2.1.0"
# Or specific action features via umbrella crate
adk-rust = { version = "2.1.0", features = ["action"] }
ノード型(14種類)
| ノード | 目的 | カテゴリ |
|---|---|---|
Trigger | エントリーポイント — ワークフローの実行を開始 | 制御 |
HTTP | HTTP リクエスト(GET、POST、PUT、DELETE、PATCH)を作成 | I/O |
Set | ワークフロー変数に値を割り当てる | データ |
Transform | 式またはコードを使用してデータを変換する | データ |
Switch | 式に基づく条件分岐 | 制御 |
Loop | コレクション内を反復する、または条件が満たされるまで反復する | 制御 |
Merge | 複数の分岐を再び結合 | 制御 |
Wait | 指定した時間、またはイベントが発生するまで実行を一時停止 | 制御 |
Code | 任意のコードを実行(Rust;JS/TS は未実装) | 計算 |
Database | データベースにクエリを実行 — 未実装 | 入出力 |
Email | SMTP を介してメールを送信 — 未実装 | I/O |
Notification | 通知を送信(Slack、webhook、push) | I/O |
RSS | RSS/Atom フィードを読み取り、解析 | I/O |
File | ファイルの読み取り、書き込み、変換 | I/O |
利用可能性はグラフの構築時に確認されます
一部のノードタイプは設定を受け付けて検証しますが、そのバックエンドは存在しません。
これらは実行の途中ではなく、StateGraph::compile()によって拒否されます。
| 設定 | 状態 |
|---|---|
Database(任意の種類) | 拒否 — ドライバーが統合されていません |
Email(監視または送信) | 拒否 — IMAP と SMTP は実装されていません |
Code と language: javascript または typescript | 拒否 — サンドボックス化されたランタイムがありません。rust を使用してください |
action-http 機能なしの Http | 拒否 — 機能を有効にしてください |
拒否にはノードと理由が示されるため、実行できないワークフローは、以前のノードがすでに副作用を発生させた後ではなく、組み立て中に失敗します。
カスタムノードに Node::validate を実装すると、同じチェックに参加できます。
StandardProperties
すべてのアクションノードには StandardProperties — 実行動作を制御する共有設定 — が含まれています。
use adk_action::{StandardProperties, ErrorHandling, RetryConfig};
let props = StandardProperties::builder()
// Error handling
.on_error(ErrorHandling::ContinueOnFail)
.retry(RetryConfig {
max_attempts: 3,
wait_between_ms: 1000,
})
// Tracing
.notes("Fetch user profile from API")
// Callbacks
.on_success("notify_complete")
.on_failure("alert_team")
// Execution
.timeout_ms(30_000)
.continue_on_fail(true)
// Input/output mapping
.input_mapping("{{trigger.body.user_id}}")
.output_key("user_profile")
.build();
StandardProperties フィールド
| フィールド | 型 | 説明 |
|---|---|---|
on_error | ErrorHandling | Stop、ContinueOnFail、または RetryThenFail |
retry | Option<RetryConfig> | 再試行回数とその間隔 |
notes | Option<String> | トレース用の人間が読める説明 |
on_success | Option<String> | 成功時に実行するコールバックノード |
on_failure | Option<String> | 失敗時に実行するコールバックノード |
timeout_ms | Option<u64> | 最大実行時間 |
continue_on_fail | bool | 失敗後に下流ノードを実行するかどうか |
input_mapping | Option<String> | 入力データを変換する式 |
output_key | Option<String> | 出力を格納する変数名 |
変数の補間
アクションノードは、ワークフローの状態を参照するための {{variable}} 構文をサポートします:
use adk_action::HttpNode;
let node = HttpNode::builder()
.url("https://api.example.com/users/{{trigger.body.user_id}}")
.method("GET")
.headers(vec![
("Authorization".into(), "Bearer {{env.API_TOKEN}}".into()),
])
.build();
変数のソース
| 接頭辞 | ソース | 例 |
|---|---|---|
trigger | トリガーノードのペイロード | {{trigger.body.email}} |
env | 環境変数 | {{env.DATABASE_URL}} |
nodes | 前のノードからの出力 | {{nodes.fetch_user.json.name}} |
workflow | ワークフローレベルの変数 | {{workflow.run_id}} |
ネストされたアクセスではドット記法を使用します: {{nodes.http_1.json.data[0].id}}
ノードの例
HTTP ノード
use adk_action::{HttpNode, HttpMethod};
let node = HttpNode::builder()
.method(HttpMethod::Post)
.url("https://api.example.com/orders")
.headers(vec![
("Content-Type".into(), "application/json".into()),
])
.body(r#"{"item": "{{trigger.body.item}}", "qty": {{trigger.body.quantity}}}"#)
.properties(StandardProperties::builder()
.timeout_ms(10_000)
.on_error(ErrorHandling::RetryThenFail)
.retry(RetryConfig { max_attempts: 3, wait_between_ms: 2000 })
.output_key("order_response")
.build())
.build();
スイッチノード
use adk_action::{SwitchNode, SwitchCase};
let node = SwitchNode::builder()
.cases(vec![
SwitchCase {
condition: "{{nodes.classify.json.category}} == 'urgent'".into(),
output: "urgent_path".into(),
},
SwitchCase {
condition: "{{nodes.classify.json.category}} == 'normal'".into(),
output: "normal_path".into(),
},
])
.fallback("default_path")
.build();
ループノード
use adk_action::{LoopNode, LoopMode};
let node = LoopNode::builder()
.mode(LoopMode::ForEach {
items: "{{nodes.fetch_users.json.users}}".into(),
item_var: "current_user".into(),
})
.body_nodes(vec!["process_user", "save_result"])
.properties(StandardProperties::builder()
.notes("Process each user in the list")
.build())
.build();
設定ノード
use adk_action::SetNode;
let node = SetNode::builder()
.assignments(vec![
("status".into(), "processing".into()),
("started_at".into(), "{{workflow.timestamp}}".into()),
("user_email".into(), "{{trigger.body.email}}".into()),
])
.build();
adk-graph との統合
アクションノードは adk-graph の ActionNodeExecutor によって実行されます:
use adk_graph::{Graph, ActionNodeExecutor};
use adk_action::{TriggerNode, HttpNode, SetNode};
// Define nodes
let trigger = TriggerNode::webhook("order_received");
let fetch = HttpNode::get("https://api.example.com/inventory/{{trigger.body.sku}}");
let update = SetNode::new(vec![("available", "{{nodes.fetch.json.quantity}}")]);
// Build graph
let graph = Graph::builder()
.node("trigger", trigger)
.node("check_inventory", fetch)
.node("update_status", update)
.edge("trigger", "check_inventory")
.edge("check_inventory", "update_status")
.build()?;
// Execute
let executor = ActionNodeExecutor::new();
let result = executor.run(graph, initial_context).await?;
カスタムノード型の定義
ActionNode trait を実装します:
use adk_action::{ActionNode, ActionContext, ActionResult, StandardProperties};
use async_trait::async_trait;
struct CustomNode {
config: MyConfig,
properties: StandardProperties,
}
#[async_trait]
impl ActionNode for CustomNode {
fn node_type(&self) -> &str { "custom" }
fn properties(&self) -> &StandardProperties { &self.properties }
async fn execute(&self, ctx: &ActionContext) -> ActionResult {
let input = ctx.resolve("{{trigger.body.data}}")?;
// Custom logic...
Ok(serde_json::json!({ "result": "processed" }))
}
}
関連項目
- グラフエージェント — グラフワークフローのオーケストレーション
- Studio アクションノード — ADK Studio のビジュアルノードエディター
- トリガー — ワークフローのトリガータイプ
前へ: ← リトライと振り返り | 次へ: プラグイン →