Skip to content

Python + LangGraph (workflow com revisão humana)

Rascunho de resposta a e-mails com human-in-the-loop: um workflow LangGraph classifica o e-mail, escreve um rascunho, pausa para revisão humana, e só “envia” depois de aprovação explícita.

A estrela do exemplo é o checkpointer em PostgreSQL: quando você liga a app ao serviço postgresql do Coffeece, threads pausados sobrevivem a deploys, restarts e crashes.

Máquina de estados

        ┌────────────┐     ┌───────┐
START ─►│  classify  │ ──► │ draft │ ──► (pausa: aguardando revisão) ──► send ──► END
        └────────────┘     └───────┘            │
                                                ├─ POST /threads/{id}/edit    (re-pausa)
                                                └─ POST /threads/{id}/approve (retoma → send)

Deploy

# 1. Criar a app
tsuru app create maildraft python -o shared-free

# 2. Recomendado: ligar PostgreSQL para que threads pausados sobrevivam a restarts
tsuru service instance add postgresql maildraft-pg db-free
tsuru service instance bind postgresql maildraft-pg -a maildraft

# 3. Chave da Anthropic
tsuru env-set -a maildraft ANTHROPIC_API_KEY=SUA_CHAVE --private

# 4. Deploy
cd python-langgraph-workflow
tsuru app deploy -a maildraft .
Sem o passo 2, a app cai num MemorySaver (logs vão mostrar checkpointer=memory) e threads são perdidos no restart.

Demonstrando a persistência

APP=https://maildraft.coffeece.com

# Cria thread — corre classify+draft, pausa antes de send
TID=$(curl -sX POST $APP/threads \
  -H 'Content-Type: application/json' \
  -d '{"inbound":"Olá, quero reembolso do pedido 42."}' | jq -r .thread_id)

# Veja o rascunho
curl -s $APP/threads/$TID | jq

# *** A graça do exemplo ***
tsuru app restart -a maildraft

# Mesmo rascunho ainda lá — checkpointer PG sobreviveu ao restart
curl -s $APP/threads/$TID | jq

# Aprovar e "enviar"
curl -sX POST $APP/threads/$TID/approve | jq

Variáveis

VariávelPadrãoDescrição
ANTHROPIC_API_KEYObrigatória. Chave da API da Anthropic.
DATABASE_URLInjetada automaticamente pelo bind do postgresql. Quando ausente, app usa MemorySaver.

Onde está o código

coffeece/examples/python-langgraph-workflow no GitHub.