Nós de Ação
O crate adk-action define 14 tipos de nós de ação usados em fluxos de trabalho baseados em grafos. Cada tipo de nó representa uma operação discreta (chamada HTTP, transformação de dados, ramificação condicional etc.) que pode ser composta em grafos direcionados por meio de ActionNodeExecutor de adk-graph.
Visão geral
Os nós de ação são os blocos de construção de grafos de fluxo de trabalho visuais e programáticos. Eles fornecem:
- Operações tipadas — 14 tipos de nós que abrangem padrões comuns de fluxo de trabalho
- StandardProperties — Configuração compartilhada para tratamento de erros, rastreamento e mapeamento de dados
- Interpolação de variáveis — Sintaxe
{{variable}}para valores dinâmicos - Integração com grafos — Executados por
ActionNodeExecutordeadk-graph
Instalação
[dependencies]
adk-action = "2.1.0"
# Or specific action features via umbrella crate
adk-rust = { version = "2.1.0", features = ["action"] }
Tipos de nós (14)
| Nó | Finalidade | Categoria |
|---|---|---|
Trigger | Ponto de entrada — inicia a execução do fluxo de trabalho | Controle |
HTTP | Fazer solicitações HTTP (GET, POST, PUT, DELETE, PATCH) | E/S |
Set | Atribuir valores a variáveis de fluxo de trabalho | Dados |
Transform | Transformar dados usando expressões ou código | Dados |
Switch | Ramificação condicional com base em expressões | Controle |
Loop | Iterar sobre coleções ou até que uma condição seja atendida | Controle |
Merge | Reunir várias ramificações novamente | Controle |
Wait | Pausar a execução por uma duração ou até um evento | Controle |
Code | Executar código arbitrário (Rust; JS/TS não implementado) | Computação |
Database | Consultar bancos de dados — não implementado | E/S |
Email | Enviar e-mails via SMTP — não implementado | E/S |
Notification | Enviar notificações (Slack, webhook, push) | E/S |
RSS | Ler e analisar feeds RSS/Atom | E/S |
File | Ler, gravar e transformar arquivos | E/S |
A Disponibilidade É Verificada Quando o Grafo É Construído
Alguns tipos de nó aceitam e validam uma configuração enquanto o backend correspondente não existe.
Eles são recusados por StateGraph::compile(), e não no meio de uma execução:
| Configuração | Status |
|---|---|
Database (qualquer tipo) | Rejeitado — nenhum driver está integrado |
Email (monitorar ou enviar) | Rejeitado — IMAP e SMTP não estão implementados |
Code com language: javascript ou typescript | Rejeitado — nenhum ambiente de execução em sandbox; use rust |
Http sem o recurso action-http | Rejeitado — habilite o recurso |
Uma rejeição identifica o nó e o motivo, portanto um fluxo de trabalho que não pode ser executado falha durante sua montagem, e não depois que os nós anteriores já tiverem causado efeitos colaterais.
Implemente Node::validate em um nó personalizado para participar da mesma verificação.
StandardProperties
Cada nó de ação contém StandardProperties — uma configuração compartilhada que controla o comportamento da execução:
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 Campos
| Campo | Tipo | Descrição |
|---|---|---|
on_error | ErrorHandling | Stop, ContinueOnFail ou RetryThenFail |
retry | Option<RetryConfig> | Tentativas de repetição e intervalo entre elas |
notes | Option<String> | Descrição legível por humanos para rastreamento |
on_success | Option<String> | Nó de callback a ser executado em caso de sucesso |
on_failure | Option<String> | Nó de callback a ser executado em caso de falha |
timeout_ms | Option<u64> | Tempo máximo de execução |
continue_on_fail | bool | Se os nós downstream são executados após uma falha |
input_mapping | Option<String> | Expressão para transformar os dados de entrada |
output_key | Option<String> | Nome da variável para armazenar a saída |
Interpolação de Variáveis
Os nós de ação são compatíveis com a sintaxe {{variable}} para referenciar o estado do fluxo de trabalho:
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();
Fontes de Variáveis
| Prefixo | Origem | Exemplo |
|---|---|---|
trigger | Carga útil do nó de acionamento | {{trigger.body.email}} |
env | Variáveis de ambiente | {{env.DATABASE_URL}} |
nodes | Saída dos nós anteriores | {{nodes.fetch_user.json.name}} |
workflow | Variáveis no nível do fluxo de trabalho | {{workflow.run_id}} |
O acesso aninhado usa a notação de ponto: {{nodes.http_1.json.data[0].id}}
Exemplos de nós
Nó 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();
Nó de alternância
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();
Nó de loop
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();
Nó de configuração
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();
Integração com adk-graph
Os nós de ação são executados por adk-graph's 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?;
Definindo tipos de nós personalizados
Implemente o trait ActionNode:
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" }))
}
}
Relacionados
- Agentes de grafo — Orquestração de fluxos de trabalho em grafo
- Nós de ação do Studio — Editor visual de nós no ADK Studio
- Gatilhos — Tipos de gatilho de fluxo de trabalho
Anterior: ← Tentar novamente e refletir | Próximo: Plugins →