Pular para o conteúdo principal

Como os workflows funcionam

Um agente termina sua execução respondendo com JSON. Quando essa resposta traz a chave workflow, a plataforma a executa: uma cadeia de requisições HTTP, em ordem, contra os seus sistemas.

É isso que transforma "o agente leu a nota" em "o pagamento existe no ERP" — sem você ficar consultando nossa API nem escrever um serviço que escuta webhooks só para chamar você mesmo de volta.

Onde entra no pipeline​

SES ──▶ Email (received)
│
├─ filtros ──▶ rejected
│
▼
approved ──▶ AgentRun (chamada ao LLM) ──▶ Email processed
│ │
│ resposta = { result, workflow }
│ │
└──────────────────▶ WorkflowRun ──▶ step 0 ──▶ step 1 ──▶ …
│
workflow.run.succeeded | failed

Duas coisas decorrem dessa posição, e elas são o desenho inteiro:

  • O workflow roda depois que a análise já está registrada. O AgentRun está success e o Email está processed antes de a primeira requisição sair. Um destino fora do ar é falha do workflow, nunca do agente — você não perde a análise que já pagou ao modelo.
  • O workflow é um job separado. Tem registro próprio (WorkflowRun), status próprio, eventos próprios. Nada nele bloqueia o recebimento de e-mails.

O formato da resposta​

{
"result": { "supplier": "ACME", "amount": 1250.5, "due_date": "2026-10-01" },
"workflow": [
{
"type": "request",
"method": "POST",
"url": "https://erp.example.com/payables",
"headers": { "Authorization": "Bearer ${{secrets.FINANCE_TOKEN}}" },
"body": { "supplier": "ACME", "amount": 1250.5, "email_id": "${{kobana.email_id}}" },
"expected_status": 201
},
{
"type": "request",
"method": "POST",
"url": "https://erp.example.com/payables/${{steps.0.response.body.data.id}}/attachments",
"headers": { "Authorization": "Bearer ${{secrets.FINANCE_TOKEN}}" },
"form": { "file": "${{email.attachments.0}}" }
}
]
}

result mantém o significado de sempre e continua guardado em Email.agent_metadata. workflow é opcional — um agente que não devolve workflow se comporta exatamente como antes.

Veja Steps e placeholders para todos os campos.

Modelo de execução​

Sequencial. Os passos rodam na ordem do array, um por vez. O passo 1 só começa depois que o passo 0 terminou.

Uma falha fica isolada. Todos os passos são tentados, em ordem. Um passo que falha fica failed sozinho; os seguintes continuam rodando. A exceção é um passo que referencia (${{steps.N.…}}) um passo que não teve sucesso — falhou ou foi pulado: ele fica skipped, nunca é enviado, e seu error diz depends on step N, which did not succeed. "Anexe o documento ao pagamento recém-criado" é errado de enviar quando o pagamento nunca foi criado, então é pulado; um segundo pagamento, independente, no mesmo workflow continua sendo criado. A execução fica failed se algum passo falhou. Coloque primeiro os passos independentes que você quer ver acontecer mesmo se outros falharem — um passo dependente só roda quando o que ele usa deu certo.

Exatamente uma vez. Não há retentativa automática, nem por passo nem pela execução inteira. Todo passo é uma requisição arbitrária aos seus sistemas; repeti-la poderia duplicar um pagamento, uma notificação ou uma cobrança. Uma execução que morre no meio (restart de worker) permanece running e é exibida assim, em vez de ser reexecutada às cegas — reexecutar é decisão humana, feita com POST /v1/emails/{id}/reprocess.

Um passo falha quando qualquer uma destas é verdadeira:

Condiçãoerror gravado
Status não corresponde a expected_status (ou não é 2xx, quando ele está ausente)expected status 201, got 422
O destino não respondeu em 30stimeout after 30000ms
Falha de conexão, de DNS ou de TLSECONNREFUSED …, ENOTFOUND …
O destino respondeu um redirecionamentoexpected status 2xx, got 302 — 3xx nunca é seguido
Um placeholder não pôde ser resolvidosecret `X` is not defined in this workspace
A URL resolvida não é permitidaurl not allowed: private_ip

O que a plataforma garante​

  • Credenciais nunca chegam ao modelo. O agente escreve ${{secrets.FINANCE_TOKEN}}; o valor é substituído na hora do envio, a partir do cofre de Secrets.
  • Credenciais nunca chegam ao banco. A requisição persistida em cada passo tem todo valor de secret trocado por [REDACTED]. O que você lê em GET /v1/workflow-runs/{id} não é o texto original, e não existe endpoint que o devolva.
  • A URL é checada depois da substituição. Só https:// (fora de desenvolvimento), e endereços privados, de loopback, link-local e de metadados de nuvem são recusados — então um secret com uma URL base não serve para apontar um passo para uma rede interna.
  • A tentativa inteira é registrada. Requisição como enviada, status da resposta, corpo da resposta (até 4000 caracteres), duração e o erro. Suficiente para diagnosticar sem reexecutar.
  • Um workflow malformado é barulhento. Se o agente emite algo que não valida, um WorkflowRun é gravado como failed com o motivo (invalid workflow at `0.url`: …). Um agente que quis disparar três requisições nunca pode parecer um agente que quis disparar nenhuma.

Limites​

LimiteValor
Passos por workflow20
Timeout por passo30s
Resposta lida por passo1 MiB
Corpo de requisição/resposta guardado4000 caracteres
Retentativasnenhuma

Próximos passos​