Saltar al contenido principal

Cómo funcionan los workflows

Un agente termina su ejecución respondiendo con JSON. Cuando esa respuesta trae la clave workflow, la plataforma la ejecuta: una cadena de peticiones HTTP, en orden, contra sus sistemas.

Es lo que convierte "el agente leyó la factura" en "la cuenta a pagar existe en el ERP" — sin que usted consulte nuestra API ni escriba un servicio que escuche webhooks solo para llamarse a sí mismo.

Dónde encaja en el pipeline​

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

De esa posición se desprenden dos cosas, y son todo el diseño:

  • El workflow corre después de que el análisis ya está registrado. El AgentRun está en success y el Email en processed antes de que salga la primera petición. Un destino caído es un fallo del workflow, nunca del agente — usted no pierde el análisis que ya le pagó al modelo.
  • El workflow es un job aparte. Tiene su propio registro (WorkflowRun), su propio status, sus propios eventos. Nada en él bloquea la recepción de correo.

El formato de la respuesta​

{
"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 conserva el significado de siempre y se sigue guardando en Email.agent_metadata. workflow es opcional — un agente que no devuelve workflow se comporta exactamente como antes.

Vea Steps y placeholders para todos los campos.

Modelo de ejecución​

Secuencial. Los pasos corren en el orden del array, uno a la vez. El paso 1 empieza solo cuando el paso 0 terminó.

Un fallo queda aislado. Todos los pasos se intentan, en orden. Un paso que falla queda failed por sí solo; los siguientes siguen ejecutándose. La excepción es un paso que referencia (${{steps.N.…}}) un paso que no tuvo éxito — falló o se saltó: queda skipped, nunca se envía, y su error dice depends on step N, which did not succeed. "Adjunte el documento a la cuenta recién creada" está mal enviarlo cuando la cuenta nunca se creó, así que se salta; una segunda cuenta, independiente, en el mismo workflow se crea igual. La ejecución queda failed si algún paso falló. Ponga primero los pasos independientes que quiere ver ocurrir aunque otros fallen — un paso dependiente solo corre cuando lo que usa salió bien.

Exactamente una vez. No hay reintento automático, ni por paso ni por ejecución. Cada paso es una petición arbitraria a sus sistemas; repetirla podría duplicar una cuenta, una notificación o un cobro. Una ejecución que muere a mitad (reinicio de worker) queda en running y se muestra así, en vez de reproducirse a ciegas — reejecutar es una decisión humana, tomada con POST /v1/emails/{id}/reprocess.

Un paso falla cuando se cumple cualquiera de estas:

Condiciónerror guardado
El status no coincide con expected_status (o no es 2xx cuando está ausente)expected status 201, got 422
El destino no respondió en 30stimeout after 30000ms
Fallo de conexión, de DNS o de TLSECONNREFUSED …, ENOTFOUND …
El destino respondió una redirecciónexpected status 2xx, got 302 — un 3xx nunca se sigue
Un placeholder no pudo resolversesecret `X` is not defined in this workspace
La URL resuelta no está permitidaurl not allowed: private_ip

Lo que la plataforma garantiza​

  • Las credenciales nunca llegan al modelo. El agente escribe ${{secrets.FINANCE_TOKEN}}; el valor se sustituye al enviar, desde el almacén de Secrets.
  • Las credenciales nunca llegan a la base de datos. La petición persistida en cada paso tiene todo valor de secret reemplazado por [REDACTED]. Lo que lee en GET /v1/workflow-runs/{id} no es el texto original, y no hay endpoint que lo devuelva.
  • La URL se verifica después de la sustitución. Solo https:// (fuera de desarrollo), y las direcciones privadas, de loopback, link-local y de metadatos de nube se rechazan — así un secret con una URL base no sirve para apuntar un paso a una red interna.
  • El intento completo queda registrado. Petición tal como se envió, status de la respuesta, cuerpo de la respuesta (hasta 4000 caracteres), duración y el error. Suficiente para diagnosticar sin reejecutar.
  • Un workflow mal formado es ruidoso. Si el agente emite algo que no valida, se registra un WorkflowRun en failed con el motivo (invalid workflow at `0.url`: …). Un agente que quiso disparar tres peticiones nunca puede parecer uno que no quiso disparar ninguna.

Límites​

LímiteValor
Pasos por workflow20
Timeout por paso30s
Respuesta leída por paso1 MiB
Cuerpo de petición/respuesta guardado4000 caracteres
Reintentosninguno

Siguientes pasos​