AI AgentsTutorialCLIWhatsApp

Como criar um agente de IA sem escrever o boilerplate

Você instala duas coisas e depois descreve o agente que quer. Seu coding agent escreve, deploya e testa. Seu trabalho é entender os conceitos o suficiente para pedir a coisa certa.

Escrito por: Victor VillalobosRevisado por: Jennifer Villalobos11 de agosto de 202611 min de leitura
Ver como Markdown

Quase todo guia sobre como criar um agente de IA entrega cem linhas para você digitar. Um loop, um dispatcher de tools, um handler de webhook, um store de conversas. Você digita, funciona no seu notebook, e o tutorial se declara concluído.

Esse era o formato certo de guia dois anos atrás. Não é mais, porque você já tem um agente que escreve código dentro do seu editor, e boilerplate é exatamente aquilo em que ele é bom.

Então este guia tem outro formato. Você instala duas coisas. Depois descreve o que quer em linguagem natural, e o seu coding agent faz o scaffolding, deploya, testa e lê os logs. O que você precisa trazer é o que ele não consegue: saber do que um agente é feito, o suficiente para pedir o agente certo e para identificar uma resposta ruim.

O que faz de algo um agente

Vale ser preciso, porque a palavra foi esticada até não significar mais nada, e porque um modelo mental vago produz um prompt vago.

Um prompt é uma chamada. Texto entra, texto sai.

Um agente é um loop. O modelo recebe um objetivo e um conjunto de tools. Ele decide qual tool chamar, vê o resultado e decide de novo. Continua até cumprir o objetivo ou até desistir.

while not done:
    decision = model(conversation, tools)
    if decision.is_final_answer:
        done = True
    else:
        result = run_tool(decision.tool, decision.args)
        conversation.append(result)

Esse loop é a ideia inteira. Os frameworks acrescentam memória, retries, tracing e handoff entre agentes, mas se você desmontar qualquer um deles encontra isso.

Você não vai escrever esse loop. O runtime cuida dele. Você precisa entender porque toda falha que vai debugar é uma falha desse loop: rodou vezes demais, chamou a tool errada, ou nunca chamou nenhuma.

A consequência prática: um agente vale o que valem as tools dele. Um modelo sem tools consegue falar sobre a sua política de trocas. Um modelo com uma tool lookup_order consegue dizer ao cliente onde está o pacote. Quase todo o valor mora nas tools, o que significa que quase todo o seu prompt deveria ser sobre elas.

As cinco decisões antes de pedir qualquer coisa

Essas são as que um coding agent não pode tomar por você, porque são decisões de negócio vestidas de decisões técnicas. Dez minutos aqui economizam uma semana.

1. O que o agente tem permissão de fazer? Escreva a lista de tools primeiro. lookup_order, book_slot, transfer_to_human. Se a lista ficar vazia, você quer um chatbot, não um agente, e vale ler a comparação antes de construir qualquer um dos dois.

2. O que acontece quando ele não tem certeza? Todo agente esbarra numa pergunta que não sabe responder. As duas opções honestas são: dizer isso e parar, ou passar para um humano. Escolha uma agora. A falha que você está evitando é o agente que inventa uma resposta com toda a confiança, e isso é decisão de design, não problema do modelo.

3. Qual canal? Isso define a sua arquitetura, e é a pergunta mais pulada de todas. Está mais abaixo.

4. O que ele nunca pode fazer? Prometer uma data de entrega. Aprovar um reembolso acima de um valor. Dar orientação médica. Isso vira linha do prompt, e se você não disser em voz alta agora, não vai estar lá.

5. Como você vai saber que quebrou? Se a resposta for "algum cliente vai avisar", você não tem plano de observabilidade. Tem fila de reclamação.

Escritas, essas cinco respostas são quase todo o seu prompt. É esse o motivo de escrevê-las.

Escolher o canal

Seus clientes já têm um lugar onde leem mensagens. A pergunta é em qual deles você aparece.

CanalBom paraO detalhe
WhatsAppSuporte, agendamento, qualquer coisa conversacional no Brasil, LATAM, Índia, sudeste asiáticoVerificação de negócio, e você só escreve livremente por 24 horas depois que o cliente escrever
SMSAlcançar qualquer um com celular, alertas, verificaçãoNos Estados Unidos você precisa de registro A2P 10DLC antes de as operadoras entregarem
EmailContexto longo, anexos, threads, B2BDeliverability é uma disciplina à parte: DKIM, SPF e uma reputação de domínio que dá para queimar
VozQuem não vai digitar, público mais velho, mãos ocupadasO orçamento de latência não perdoa. Dois segundos de silêncio soam como ligação caída
Telegram, Instagram, MessengerComunidades e marcas de consumo cujo público já mora aliCada um tem seu modelo de identidade e seus rate limits

O widget de chat no site ficou fora da tabela de propósito. Um widget só alcança quem já está no seu site. Todos os canais acima alcançam a pessoa onde ela já está, e é por isso que um agente no WhatsApp é usado e o mesmo agente atrás de um widget não é.

O setup: dois comandos

terminal
npx skills add zavudev/zavu-skills npx zavudev@latest login

Eles fazem dois trabalhos diferentes, e vale saber qual é qual.

As skills dão conhecimento ao seu coding agent. Peça a qualquer coding agent "adiciona WhatsApp no meu app" sem elas e você recebe código que parece certo. Parecer certo é o problema: ele inventa nomes de endpoint, ignora a janela de 24 horas e aí o primeiro envio em produção falha enquanto em dev nunca falhou, e escreve um handler de webhook sem verificação de assinatura. Isso não é o modelo ser fraco. Ele simplesmente nunca viu essa API, e não vai te avisar. As skills são markdown puro que se carrega sozinho quando a tarefa combina, e o instalador pergunta em quais coding agents instalar. São mais de quarenta suportados, incluindo Claude Code, Cursor, Copilot, Codex, Cline, Gemini CLI, Amp e Warp.

O CLI dá as mãos. Scaffolding, secrets, deploy, teste, logs. O login abre o navegador, você entra, escolhe o projeto e clica em Authorize. A chave fica em ~/.zavu/credentials.json e o seu agente usa dali em diante. Numa máquina sem navegador, defina ZAVUDEV_API_KEY.

Isso é tudo o que você digita. Daqui em diante, você conversa.

O prompt

Agora use as cinco respostas. Um bom prompt para isso não é esperto, é específico:

> Construa um agente de suporte para a minha loja online no WhatsApp.>> Ele deve responder perguntas sobre pedidos. Dê a ele uma tool que busque um pedido por ID em https://api.example.com/orders/{id}, usando STORE_API_KEY dos secrets. Dê uma segunda tool que passe a conversa para um humano, fazendo POST no nosso webhook de plantão.>> Regras: responder em duas frases ou menos, nunca inventar data de entrega, e se não achar um pedido dizer isso e oferecer uma pessoa. Para reembolsos acima de USD 200 sempre usar a tool de handoff em vez de decidir.>> Deploye e teste com "onde está o pedido 4471?"

Seu coding agent vai fazer o scaffolding da function, escrever o agente e as duas tools, definir os secrets, deployar e rodar o teste. Repare no que fez esse prompt funcionar: eram as decisões 1, 2 e 4 da lista acima, ditas em voz alta. Nada ali é sintaxe.

O que ele escreveu, e o que você confere

Isso você não digita. Você lê, porque revisar o diff é a parte que continua sendo sua:

TypeScript
import { defineAgent, defineTool } from "@zavudev/functions" defineAgent({ senderId: process.env.SENDER_ID!, name: "Nora", provider: "zavu", model: "openai/gpt-4o-mini", prompt: Você é a Nora, suporte de uma loja online. Responda em duas frases ou menos. Se não encontrar um pedido, diga isso e ofereça passar o cliente para uma pessoa. Nunca invente uma data de entrega., }) defineTool({ name: "lookup_order", description: "Get the current status of a customer order. Use when the customer mentions an order number or asks where their package is.", parameters: { type: "object", properties: { orderId: { type: "string" } }, required: ["orderId"], }, handler: async ({ orderId }) => { const res = await fetch(https://api.example.com/orders/${orderId}, { headers: { Authorization: Bearer ${process.env.STORE_API_KEY} }, }) return res.json() }, })

Três coisas para olhar, nesta ordem:

As descrições das tools. "Use when the customer mentions an order number or asks where their package is" é o que o modelo lê ao decidir se chama aquilo. Essa é a linha de maior alavancagem do arquivo, e é a que um coding agent escreve de qualquer jeito com mais frequência. Se diz só "busca um pedido", faça dizer quando, e quando não.

Suas regras, de fato presentes. Todo "nunca" que você pediu deveria aparecer na string do prompt. Se faltar um, boa intenção não vai fazer ele valer.

A regra de escalada em dois lugares. A política vai no prompt para o modelo conhecer. O gatilho vai na descrição da tool para o modelo reconhecer o momento. Um agente que "sabe" que deveria escalar mas nunca escala quase sempre está sem o segundo.

O que você não está revisando: o loop, o limite de turnos, o histórico por contato, a verificação de assinatura do webhook, a janela de 24 horas do WhatsApp. O runtime cuida de tudo isso, que é a razão de não haver boilerplate nesse arquivo.

Testar antes que um cliente teste

terminal
npx zavudev agents test --agent <agentId> --message "onde está o pedido 4471?"

Roda o agente real com o prompt real e o knowledge base real, devolve o que ele diria, não entrega nada a ninguém e não cobra nada. Seu coding agent pode rodar isso em loop enquanto itera. Use --json para fazer assert no CI.

Dois detalhes tornam isso mais honesto que a maioria dos previews. Ele devolve warnings com coisas que são verdade sobre o seu agente mas que um dry run não consegue provar: o agente desabilitado, ou tools que existem mas não foram oferecidas ao modelo naquela rodada. E por padrão ele não executa as tools, porque um ensaio que passa o cartão de um cliente não é ensaio. Quando quiser o loop completo, passe executeTools e olhe executedToolCalls para ver o que rodou.

Um teste verde não prova que o agente funciona ao vivo. Prova que o prompt faz o que você acha, que era justamente a sua dúvida.

Iterar é prompar mais

Você não volta para o editor. Você diz o que ficou errado:

> Ele respondeu "seu pedido está a caminho" sem chamar a tool. Aperte a descrição da tool para ela disparar sempre que um pedido for mencionado, redeploye e teste de novo com a mesma mensagem.

Isso funciona porque o resumo do deploy é legível por máquina e o teste é um comando, então o seu coding agent fecha o ciclo sozinho: muda, deploya, testa, lê, muda de novo.

Uma coisa para saber sobre esse resumo. + é criado, ~ é que existia e foi reescrito, = (unchanged) é que nada diferia. Os marcadores descrevem o que o deploy escreveu, não o que o agente agora diz. Para verificar que uma mudança chegou ao modelo, ponha uma palavra distintiva no prompt que você editou e veja se ela volta do agents test. E leia as linhas acima do ✓: os warnings aparecem antes da linha de sucesso, e cobrem os casos em que um deploy verde não fez o que parece.

Partir de algo que já funciona

Costuma ser mais rápido que descrever um agente do nada:

terminal
npx zavudev agents catalog npx zavudev agents pull fermi --sender <senderId>

O catalog lista agentes prontos para suporte, captação de leads e agendamento, com a contagem de tools e se atendem ligação. O pull coloca um deles no seu repositório como código real e editável que é seu, com o prompt e todas as tools já escritas. Depois você aponta o seu coding agent para lá: "mude isso para funcionar numa clínica odontológica e use a nossa API de agendamento".

O npx zavudev agents init roda o processo inteiro como um comando guiado, incluindo a criação do sender.

O que dá errado em produção

Cinco falhas, na ordem em que você vai conhecer cada uma. Cada uma também é um bom prompt para o seu coding agent, porque ele consegue ler os mesmos registros que você.

Responde com confiança e erra. Quase sempre é um prompt que nunca deu a ele permissão de falhar. Adicione a frase explícita: "Se você não sabe, diga que não sabe." Depois confira knowledgeChunksUsed no registro de execução. Zero, num agente com documentos anexados, significa que a resposta não veio do seu conteúdo.

Diz que vai consultar algo e nunca consulta. A resposta parece que chamou uma tool. Nada chegou ao seu endpoint. Confira toolCalls na execução: zero num agente com tools configuradas significa que o modelo respondeu sem chamar nenhuma. Quase sempre a descrição da tool não bate com as palavras que os clientes usam.

Responde duas vezes. Chegam duas mensagens em um segundo, rodam dois loops, os dois respondem. Trate o caso de uma conversa que já está sendo processada.

É lento. Cada tool call é um round trip, e o modelo espera. No WhatsApp você tem alguns segundos antes do silêncio soar como quebrado, então marque a mensagem como lida e mostre o indicador de digitação. Na voz você tem cerca de um segundo, e é por isso que as tools de um voice agent precisam ser rápidas ou parecer rápidas.

Funciona e ninguém sabe explicar por quê. O npx zavudev agents executions dá os tool calls, os argumentos, os resultados e os erros de um agente deployado. Passe essa saída para o seu coding agent e pergunte o que mudou.

Limites honestos

Algumas coisas para as quais um agente não deveria ser a resposta.

Se a tarefa é determinística, peça uma função. Um agente que sempre chama a mesma tool na mesma ordem é um workflow com um imposto de modelo de linguagem em cima.

Se uma resposta errada sai cara, o agente precisa de um humano no caminho de aprovação, não de prompting melhor. Reembolso, orientação médica e qualquer coisa juridicamente vinculante entram nessa categoria.

Se você não tem tools, você tem uma interface de busca sobre os seus documentos. Isso pode ser genuinamente útil. Não é um agente, e chamar de agente cria uma expectativa que você não vai cumprir.

E o limite deste fluxo em específico: o seu coding agent faz tudo o que está na coluna da direita, mas você continua criando a conta, autorizando o login, aprovando a compra de um número, conectando o WhatsApp Business pelo signup da Meta, e lendo o diff antes de ir para produção. Esses são os passos que legal, financeira ou fisicamente precisam de uma pessoa.

Para continuar

Precisa de ajuda? Contate-nos ou junte-se à nossa comunidade Discord para suporte.

Get started

Pronto para começar?

Comece a construir gratuitamente ou agende uma chamada para discutir seu caso de uso específico.

Como criar um agente de IA (guia 2026) | Zavu Blog