Preparação para entrevista
RefatoraçãoOperação

Mover para Execução Durável

Move to Durable Execution

Mover para Execução Durável (Move to Durable Execution) é uma refatoração de IA para sistemas com LLM, do grupo Operação. Salvar o estado a cada etapa para retomar depois de queda, espera ou aprovação.

Elemento
35/35
Nível
Avançado
Leitura
5 min
Atualizado
Nesta página 8
  1. 01Problema
  2. 02Solução
  3. 03Antes e depois
  4. 04Por que funciona
  5. 05Passo a passo seguro
  6. 06Riscos
  7. 07Desafio
  8. 08Teste seu entendimento
  9. ··Perguntas rápidas

Problema

Um processo que dura horas ou dias (esperando documentos, aprovações, respostas de outros sistemas) vive na memória de um processo ou num histórico de conversa. Uma queda, um deploy ou uma espera longa fazem perder o estado. É o smell Prompt Máquina de Estados, na sua forma de longa duração.

Solução

Rode o processo num mecanismo de execução durável: cada passo é registrado, o estado é persistido entre passos, esperas viram eventos que retomam a execução, e uma falha retoma do último passo concluído, sem repetir o que já foi feito.

Antes e depois

-def onboarding(customer_id):
-    data = ask_for_documents(customer_id)            # pode levar dias; processo em memória
-    if not validate(data):
-        ask_again(customer_id)
-    approval = wait_for_compliance(customer_id)      # se o servidor reiniciar, perdeu
-    create_account(customer_id)
+@workflow
+def onboarding(customer_id):
+    docs = workflow.wait_for_signal("documents_received", timeout=days(7))
+    result = workflow.step(validate_documents, docs)          # resultado gravado
+    while not result.ok:
+        workflow.step(send_whatsapp, customer_id, result.missing)
+        docs = workflow.wait_for_signal("documents_received", timeout=days(7))
+        result = workflow.step(validate_documents, docs)
+    approval = workflow.wait_for_signal("compliance_decision", timeout=days(3))
+    if approval.approved:
+        workflow.step(create_account, customer_id, idempotency_key=workflow.id)

Antes: o estado vive na memória.

flowchart LR
  S(["1. Início"]):::io --> W["2. Espera dias por documento"]:::tool
  W --> X{"3. Servidor reiniciou?"}
  X -->|sim| L(["4. Estado perdido"]):::io

Depois: cada passo gravado, esperas como eventos.

flowchart LR
  S(["1. Início"]):::io --> P1["2. Passo gravado"]:::tool
  P1 --> J[("3. Histórico do workflow")]:::store
  J --> W{"4. Espera por sinal"}
  W -->|"documento chegou"| P2["5. Próximo passo"]:::tool
  P2 --> J
  J -->|"falha ou deploy"| R["6. Retoma do último passo"]:::tool
  1. O processo começa como um workflow com identificador.
  2. Cada passo com efeito é executado e o resultado é gravado.
  3. O mecanismo guarda o histórico de passos e o estado.
  4. Esperas (documento, aprovação, prazo) são eventos; nenhum processo fica parado esperando.
  5. Quando o evento chega, a execução continua de onde estava.
  6. Se algo cai, o workflow retoma com os resultados já gravados, sem repetir passos concluídos.

Exemplo trabalhado

Uma fintech abre conta PJ pelo WhatsApp. O cliente manda o contrato social, o comprovante e uma selfie. Compliance leva até três dias úteis. No desenho antigo, um processo Node fica em await esperando. Um deploy na sexta apaga quem estava no meio. Na segunda, o cliente ouve “pode mandar os documentos de novo”.

No desenho durável, o identificador do workflow é o customer_id. O passo validate_documents grava um resultado com ok falso e a lista do que falta, por exemplo o comprovante. O passo send_whatsapp manda essa lista, com chave wf.id + ":ask:" + n. A espera vira um sinal documents_received com prazo de 7 dias.

Na terça o comprovante chega. O motor acorda o workflow, lê o resultado já gravado da validação anterior e roda a validação de novo. Ninguém pergunta o CNPJ outra vez. Se o servidor cair no meio da criação da conta, a chave de idempotência workflow.id impede uma conta duplicada.

O modelo continua no lugar certo: ler o PDF, dizer o que falta, escrever a mensagem no tom da fintech. Ele não guarda “já estamos na etapa 4”. Isso mora no histórico do workflow.

Checagem +20 XP de primeiraO onboarding espera o comprovante com await sleep(7 * 24 * 3600) num processo Node. Um deploy acontece no dia 2. O que acontece com os clientes no meio do fluxo?

Por que funciona

Um processo longo tem dois inimigos: o tempo e as falhas. Processos em memória não sobrevivem a nenhum dos dois. Um mecanismo de execução durável grava o resultado de cada passo e reconstrói o estado a partir desse registro, então uma queda ou um deploy viram uma pausa, não uma perda.

O modelo continua com o papel dele: entender mensagens, extrair dados, escrever respostas. O fluxo (o que vem depois, o que espera o quê) fica no código do workflow, testável e visível. E o identificador do workflow serve como chave de idempotência natural para as ações com efeito. Os padrões de destino são o Workflow Durável e o Checkpoint e Retomada.

Replay: por que o modelo não pode ficar no corpo do workflow

Motores como Temporal reexecutam o código do workflow do começo para reconstruir o estado. Eles não “continuam da linha 47”. Eles replayam os passos gravados e só então rodam o que ainda não rodou.

Se você chama o modelo no corpo do workflow, cada replay dispara uma chamada nova. A resposta muda, o ramo do if muda, e o histórico gravado deixa de bater com o código. O motor acusa não determinismo.

A regra é simples. Tudo que não é determinístico (modelo, relógio, aleatório, HTTP) entra num workflow.step. O corpo do workflow só lê resultados já gravados e decide o próximo passo.

Passo a passo seguro

  1. Meça. Levante quantos processos se perdem hoje (quedas, deploys, timeouts) e quanto tempo cada etapa espera.
  2. Desenhe o fluxo como passos e esperas explícitos.
  3. Escolha o mecanismo: um motor de workflow durável, uma fila com estado em banco, ou a solução da sua plataforma.
  4. Transforme cada efeito num passo registrado, com chave de idempotência.
  5. Transforme cada espera num evento (sinal, timer), com prazo e o que fazer quando o prazo vence.
  6. Mantenha as chamadas ao modelo dentro de passos, para que o resultado seja gravado e não seja refeito numa retomada.
  7. Teste a retomada: derrube o processo no meio e confira que ele continua sem repetir efeitos.
  8. Meça de novo: processos concluídos, retomadas bem-sucedidas, efeitos duplicados (zero).

Quando um checkpoint em banco basta

Um motor de workflow é peça a mais: versão de fluxo, replay, visibilidade. Para um job de 20 minutos com três passos e sem espera humana, um registro em banco com status, step e idempotency_key pode ser suficiente.

A linha que pede o motor é a espera longa (horas ou dias), o volume de processos parados, e a necessidade de ver cada um. Se você tem mil onboarding abertos esperando documento, um sleep em mil processos não escala. Um sinal por processo escala.

Riscos

  • Código não determinístico no workflow. Mecanismos de execução durável costumam reexecutar o código do workflow para reconstruir o estado. Chamadas ao modelo, horários e aleatoriedade precisam estar dentro de passos registrados.
  • Mudanças no fluxo com processos em andamento. Uma versão nova do workflow pode não bater com o histórico dos antigos. Versione o workflow.
  • Complexidade. Um motor de workflow é mais uma peça. Para processos de minutos, um checkpoint simples em banco pode bastar.

Erro comum: o prompt como máquina de estados

O time descreve as etapas no system prompt (“não pule a etapa 3”) e acha que o histórico da conversa é o checkpoint. O smell Prompt Máquina de Estados é exatamente isso. O cliente manda CPF e comprovante na mesma mensagem, o modelo perde a conta, e o fluxo pula.

Execução durável não substitui o modelo. Ela tira dele a obrigação de lembrar em que etapa o processo está. O código sabe. O modelo só preenche o passo atual.

Checagem +20 XP de primeiraO código do workflow chama llm(EXTRACT_PROMPT, pdf) direto no corpo, fora de workflow.step. Depois de um crash, o motor faz replay. Qual é o risco?

Desafio

Um processo de cobrança envia um lembrete, espera 3 dias, envia outro, espera mais 3 dias e, se não houver pagamento, abre um chamado para o time financeiro. Hoje isso é um script com sleep. O que pode dar errado, e como fica a versão durável?

Ver solução

Com sleep, qualquer reinício perde todos os processos em espera; um retry do script pode mandar o mesmo lembrete duas vezes; e não dá para ver em que etapa cada cobrança está. Na versão durável:

workflow cobranca(invoice_id):
    step send_reminder(invoice_id, n=1, key=wf.id+":1")
    paid = wait_for_signal("paid", timeout=days(3))
    if paid: return
    step send_reminder(invoice_id, n=2, key=wf.id+":2")
    paid = wait_for_signal("paid", timeout=days(3))
    if not paid: step open_finance_ticket(invoice_id, key=wf.id+":ticket")

O pagamento envia o sinal paid, e cada passo tem chave própria.

Teste seu entendimento

Checagem +20 XP de primeiraO passo create_account não tem chave de idempotência. O workflow cai depois de criar a conta, mas antes de gravar o passo. Na retomada, o que acontece?

Checagem +20 XP de primeiraVocê muda o onboarding: depois da selfie, passa a exigir um comprovante de endereço. Há 400 workflows no meio, alguns já na etapa de compliance. O que você faz?

Checagem +20 XP de primeiraUm job classifica 200 notas fiscais em 15 minutos, uma após a outra, sem espera humana. Vale um motor de workflow durável?

Checagem +20 XP de primeiraO cliente escreve no WhatsApp: 'já mandei o comprovante ontem'. No desenho durável, quem decide se a etapa está cumprida?

Perguntas rápidas

O que é Mover para Execução Durável?

Mover para Execução Durável (Move to Durable Execution) é uma refatoração de IA para sistemas com LLM, do grupo Operação. Salvar o estado a cada etapa para retomar depois de queda, espera ou aprovação.

Que problema Mover para Execução Durável resolve?

Trata Prompt Máquina de Estados.

Aonde Mover para Execução Durável leva?

Ao padrão de projeto Workflow Durável e Checkpoint e Retomada.

Para ir além

Relações

Buscar