Em uma série de artigos, o cientista de dados Soner Yıldırım construiu um agente stateful com LangGraph que conduz um processo de agendamento de 15 minutos — inspirado em uma conversa real com o atendimento de uma empresa de limpeza. Nas partes anteriores, ele montou o fluxo do agente, envolveu tudo numa interface Streamlit e adicionou um backend com banco de dados. Neste passo, a lição central é: como testar o backend Postgres localmente com Docker ou na nuvem — e por que a persistência muda tudo.
O que o agente faz
O agente orquestra o agendamento completo como um atendente humano: responde dúvidas do cliente, entende as necessidades, calcula o preço, lida com aceite ou recusa, propõe horários otimizados e confirma a reserva. O estado da conversa vive no AgentState do LangGraph e é salvo como checkpoints. Quando o agente oferece horários, ele lê as reservas existentes no banco para não propor um horário já ocupado; quando o cliente confirma, ele grava uma linha de reserva (técnico, horário, endereço e preço). O código-fonte completo está no repositório customer-service-agent no GitHub.
Dois modos de persistência
O agente tem dois modos: em memória (para testes rápidos e demos) e Postgres (para persistência real). Se a variável DATABASE_URL não estiver definida, o app usa InMemoryBookingRepository e MemorySaver — nenhuma tabela é criada e o estado da conversa se perde quando o app reinicia.
Para rodar o teste local com a interface Streamlit, instale as dependências e copie o arquivo de exemplo:
poetry install
cp .env.example .envDefina a OPENAI_API_KEY no .env e deixe a DATABASE_URL vazia para o teste em memória. Em seguida, suba a UI:
poetry run streamlit run customer_service_agent/streamlit_app.pyNo navegador (localhost:8501), você consegue completar uma reserva — mas, como o estado é em memória, tudo desaparece ao reiniciar. Para ter dados de verdade, é preciso usar o banco.
Testando com Docker
O Docker permite testar contra um Postgres real sem instalar banco na sua máquina — e reproduz o mesmo banco que você teria em produção. O projeto inclui um docker-compose.yml que sobe um PostgreSQL 16:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: booking
POSTGRES_PASSWORD: booking
POSTGRES_DB: booking_agent
ports:
- "5432:5432"
volumes:
- booking_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U booking -d booking_agent"]
interval: 5s
timeout: 5s
retries: 10
volumes:
booking_pgdata:Com o Docker Desktop aberto (até ver “Engine is running”), suba o container e aponte a app para ele:
docker compose up -d# no arquivo .env
DATABASE_URL=postgresql://booking:booking@localhost:5432/booking_agentOs dados ficam num volume persistente (booking_pgdata), não em RAM. Reiniciar o Streamlit não apaga as reservas — elas só se perdem se você derrubar e apagar o volume com docker compose down -v.
Testando com Postgres hospedado
Se você já tem Postgres na nuvem (Supabase, RDS, Neon), não precisa do Docker. Basta criar o banco no painel do provedor, copiar a connection string — algo como postgresql://USER:SENHA@HOST:PORTA/DATABASE — e colocá-la no .env como DATABASE_URL. O comportamento do app é idêntico ao do Docker; só muda onde o Postgres roda (agora num host remoto).
Verificação prática
Para confirmar que a persistência funciona, complete uma reserva e abra uma segunda aba do navegador pedindo o mesmo serviço. Desta vez, o agente não oferece o horário que você acabou de reservar — porque agora ele lê as reservas do banco. É a diferença concreta entre demo e produto.
Próximos passos da série
O autor destaca que ainda há trabalho antes de virar um produto de valor real: adicionar outros canais (como WhatsApp), uma camada de segurança para reduzir risco de prompt injection e melhorar o fluxo e a experiência de chat. São exatamente os temas que separam um protótipo funcional de um agente de atendimento pronto para produção.
Descubra mais sobre noticiAI
Assine para receber nossas notícias mais recentes por e-mail.



