Hoje você tem dois tipos de agente de IA trabalhando, e eles fazem coisas diferentes.
Um vive no seu editor. Claude Code, Cursor, Copilot, Codex. Lê seu repo e escreve código.
O outro atende seus clientes. Atende o telefone, responde no WhatsApp, consulta um pedido, agenda uma reunião.
Este post é sobre apontar o primeiro para o segundo. Não é você seguir um tutorial com seu agente assistindo. Você cria a conta Zavu e faz login, e a partir daí seu coding agent monta o agente, escreve as tools, deploya, testa, lê os logs e corrige o que encontrar.
Por que seu coding agent não consegue fazer isso hoje
Peça para qualquer coding agent "adicionar WhatsApp no meu app" e você recebe código que parece certo. Parecer certo é justamente o problema.
Ele inventa nomes de endpoint. Ignora a janela de 24 horas do WhatsApp, então o primeiro envio de template falha em produção e não em dev. Escreve um webhook handler sem verificação de assinatura. Escolhe SMS para uma mensagem que leva uma imagem.
Nada disso é o modelo ser fraco. Ele simplesmente nunca viu esta API, e não vai te avisar.
Duas peças resolvem isso, e cada uma faz um trabalho diferente:
| Peça | O que dá ao seu coding agent | Como adicionar |
|---|---|---|
| Skills | Conhecimento: endpoints, regras de canal, error codes, convenções | npx skills add zavudev/zavu-skills |
| CLI | Mãos: scaffold, deploy, test, logs, rodar uma tool local | npx zavudev |
Quem faz o quê
A divisão não é "você faz a parte fácil". É: você faz o que legal, financeira ou fisicamente precisa de uma pessoa.
| Você | Seu coding agent |
|---|---|
| Cria a conta Zavu | Encontra ou cria o sender |
Roda zavu login e autoriza no browser | Monta a function |
| Aprova a compra de um número, se precisar | Escreve defineAgent e cada defineTool |
| Conecta o WhatsApp Business pelo signup da Meta | Define os secrets |
| Lê o diff antes de ir para produção | Deploya, testa, lê logs, corrige, deploya de novo |
A única parte que você digita
bashnpx skills add zavudev/zavu-skills npx zavudev login
O installer pergunta em quais coding agents instalar as skills. São arquivos markdown que se carregam sozinhos quando a tarefa combina, então nada roda até ser relevante. Há suporte para mais de 40, incluindo Claude Code, Cursor, Copilot, Codex, Cline, Gemini CLI, Amp e Warp.
login abre o browser, você entra, escolhe o projeto e clica em Authorize. A key fica em ~/.zavu/credentials.json com permissão 0600 e seu agente usa a partir dali. Numa máquina sem browser, defina ZAVUDEV_API_KEY e pule o passo.
Esse é o setup. Daqui para frente você conversa.
O que as skills colocam na cabeça do modelo
| Skill | O que ensina |
|---|---|
zavu-rules | Sempre carregada. Ecossistema de SDKs, auth, convenções, business rules |
functions | defineAgent, defineTool, deploy, debugging |
ai-agent | Configuração de agentes, providers, flows, tools, knowledge bases |
voice-agent | Agentes de voz, saudações, transferências, limites de chamada |
send-message | Árvore de decisão de canal e todos os message types |
webhook-setup | Verificação de assinatura, retry policy, tratamento de eventos |
whatsapp-templates | Criação de templates, aprovação da Meta, botões OTP |
broadcast-campaign | Criar, revisar, enviar, monitorar |
contacts-management | Contatos multicanal, merge, introspection |
phone-numbers | Busca, compra, requisitos regulatórios |
Depois você descreve o que quer
textConstrua um agente Zavu para a minha pizzaria no WhatsApp. Ele precisa mostrar o cardápio, consultar disponibilidade de mesas e registrar reservas. As reservas ficam no meu Postgres em DATABASE_URL. Use o meu sender atual, faça o deploy, e teste antes de me dizer que funciona.
Não se espera que você conheça os comandos abaixo. Eles estão aqui para você reconhecer o que passa na tela, e para perceber quando seu agente pulou uma etapa.
bashnpx zavudev whoami # qual projeto eu vou mexer npx zavudev senders list # o sender onde ele entra npx zavudev fn init --template restaurant-booking -y npx zavudev fn secrets set SENDER_ID "jn76vnxet8g5nq661by3v06y1581bmmn" npx zavudev fn secrets set DATABASE_URL "postgres://..." npx zavudev deploy
whoami é o que vale olhar. Deployar um agente no projeto errado é o tipo de erro que fica em silêncio por um dia inteiro.
Se preferir que ele parta de algo testado em vez de um arquivo em branco, existe um catálogo:
bashnpx zavudev agents catalog
textid name voice tools category fermi Fermi, Lead Qualification yes 5 sales curie Curie, Customer Support yes 5 support kepler Kepler, Video Call Booking yes 2 frontDesk hopper Hopper, Lead Capture and Booking yes 5 sales aria Aria, Multi-channel concierge yes 3 frontDesk atlas Atlas, Product Expert yes 0 support
Diga "comece pelo kepler" e ele roda agents pull kepler, que baixa TypeScript real e editável, seu, não uma caixa preta. Atlas não tem tools de propósito: ele responde a partir de uma knowledge base, e um agente que só precisa ler a sua documentação não deveria ganhar a capacidade de escrever em lugar nenhum.
Leia o que ele escreveu
Esta é a parte que merece sua atenção, porque é a parte com que você vai conviver.
tsimport { defineAgent, defineTool } from "@zavudev/functions" defineAgent({ senderId: process.env.SENDER_ID!, name: "Bella", provider: "zavu", model: "openai/gpt-4o-mini", channels: ["whatsapp", "sms"], prompt: "Você é a mesa de pedidos da Tony's Pizza. Responda em uma ou duas frases.", }) defineTool({ name: "check_order_status", description: "Busca um pedido. Chame isto antes de responder sobre um.", parameters: { type: "object", properties: { orderId: { type: "string" } }, required: ["orderId"], }, handler: async ({ orderId }) => { const res = await fetch("https://api.example.com/orders/" + orderId) if (!res.ok) return { ok: false, reason: "not_found" } return { ok: true, ...(await res.json()) } }, })
Duas coisas para conferir sempre.
provider: "zavu" é o gateway gerenciado: sem API key própria, sem uma relação de billing à parte, o custo do LLM sai do seu saldo Zavu. Se o seu agente ligou uma key crua da OpenAI no lugar, isso foi uma decisão que ninguém pediu.
O código é a fonte da verdade. Apague a chamada defineAgent e o próximo deploy apaga o agente. Não existe um segundo lugar onde ele também existe e sai de sincronia em silêncio.
Você nunca registrou um webhook nem ligou um trigger, e isso não é um esquecimento. defineAgent({ senderId }) é o vínculo: aquele sender agora entrega cada mensagem recebida a este agente.
Ele publica um agente de voz do mesmo jeito
textO mesmo agente, mas que também atenda o telefone. Saudação em português, transferência para +14155551234 quando pedirem uma pessoa, corte duro aos 12 minutos.
tsdefineAgent({ senderId: process.env.SENDER_ID!, name: "Bella", provider: "zavu", model: "openai/gpt-4o-mini", channels: ["voice", "whatsapp"], voice: { enabled: true, model: "openai/gpt-4o", greeting: "Oi, obrigado por ligar para a Tony's. Como posso ajudar?", greetings: { en: "Hi, thanks for calling Tony's." }, interruptible: true, maxCallDurationMinutes: 12, transferPhoneNumber: "+14155551234", }, prompt: "Você é a mesa de pedidos da Tony's Pizza.", })
interruptible é barge-in: quem liga pode cortar o agente no meio da frase, que é o que faz uma ligação parecer uma ligação. Voz exige um número atribuído ao sender e a feature de Voice Agents habilitada para o seu team.
Ele se debuga sozinho, e esse é todo o ponto
Escrever o agente é a metade fácil. A metade que decide se ele presta é o loop: rodar, ler o que deu errado, corrigir, rodar de novo. Cada passo desse loop é um comando, então seu agente roda o loop em vez de te narrar.
textO agente falou o preço errado para ORD-12345. Rode agents test contra esse pedido, leia fn logs e agents executions, ache onde falhou, corrija e faça o deploy de novo.
O que ele usa:
bashnpx zavudev agents test --sender "$SENDER_ID" --message "onde está o pedido ORD-12345?" npx zavudev fn invoke --tool check_order_status --args '{"orderId":"ORD-1"}' npx zavudev fn logs --tail npx zavudev agents executions --sender "$SENDER_ID" npx zavudev messages list --limit 10
agents test não entrega nada a ninguém, não cobra nada, não registra nada. fn invoke roda um handler na sua máquina em menos de um segundo, contra código sem commit e com os envios mockados, então separa "a tool está quebrada" de "o prompt está errado". Os três últimos são a evidência: seus logs, cada execução do agente com as tools que ele chamou e o custo de cada uma, e cada mensagem que entrou e saiu.
Isso é um loop de verdade. O agente tem conhecimento pelas skills, mãos pelo CLI, e agora evidência.
Você precisa do MCP server?
Existe um, e se o seu coding agent tem terminal você pode pular.
Ele envolve a mesma REST API que o CLI já espelha comando por comando, então te dá uma segunda coisa para autenticar e cobre estritamente menos. Rodar um handler local contra código sem commit não é uma operação de API, então nenhum MCP consegue oferecer isso. Use quando o agente não tem shell.
O que ele não consegue fazer sem você
Três coisas, e cada uma para por um motivo.
Comprar um número gasta o seu dinheiro. O CLI deixa isso atrás de uma confirmação explícita, e deve continuar assim. Um agente que provisiona números sem supervisão é um incidente de billing esperando um loop ruim.
Conectar o WhatsApp Business é o signup da Meta. Uma pessoa passa pelo browser, aceita os termos da Meta e escolhe o negócio. Ninguém automatiza o seu consentimento.
Publicar em produção é decisão sua. deploy é um comando só, que é exatamente por que o diff merece trinta segundos. Leia o que as tools fazem de verdade antes de elas rodarem contra clientes reais.
Como isso é cobrado na Zavu
Nada do que o seu coding agent faz custa dinheiro. As skills, o CLI, os SDKs, deploy e cada redeploy depois são de graça. Você é cobrado por um agente que roda, não por um que é construído.
O plano cobre o funcionamento. Free é $0 com 2.000 mensagens, 3.000 emails e 100.000 unidades de invocação de functions. Hobby é $25 por mês com 100.000 mensagens, 100.000 emails e 1M de unidades, e Standard e Growth sobem esses números. Uma unidade é uma invocação de 128 MB, então uma function de 256 MB gasta 2 por chamada. No plano free a cota de functions é um teto duro: os requests são rejeitados em vez de faturados.
A entrega é por mensagem. Cada canal tem sua tarifa, e o tráfego que passa do allowance do seu plano é cobrado por mensagem: $0.003 no Hobby, $0.002 no Standard, $0.001 no Growth. O overage de email é $0.90 por mil. Os planos pagos ainda depositam um crédito mensal no seu saldo, que é de onde saem os primeiros envios.
O modelo, só se for o nosso. Com provider: "zavu" o LLM é medido por token contra o seu saldo Zavu, e cada cobrança nomeia o modelo e a quantidade de tokens, então dá para ler a conta linha por linha. Se você traz a sua própria key, a Zavu não cobra nada por inferência: você paga a OpenAI ou a Anthropic direto. Nos dois casos você precisa de saldo positivo, porque a resposta que o agente manda é uma mensagem e mensagens custam.
Voz é por minuto conectado. O pipeline gerenciado custa $0.0625 por minuto mais telefonia, contados de quando atendem até desligarem. Os modelos padrão estão cobertos por essa tarifa; um modelo premium soma o próprio custo de tokens. Ao colocar a chamada se reserva uma estimativa curta, liquidada contra a duração real no fim.
O que vale saber antes de começar: o loop de desenvolvimento é grátis. agents test não entrega nada, não registra execução e não cobra. fn invoke roda o handler na sua própria máquina. Seu coding agent pode rodar, ler, corrigir e rodar de novo a tarde inteira sem encostar na conta. A primeira coisa que você paga é um cliente real recebendo uma resposta real.
As tarifas mudam. A página de preços é a que está atualizada.
Três regras que mantêm isso honesto
Um dry run não é prova. agents test exercita o path de texto e imprime warnings sobre o que ele não consegue provar: um agente desabilitado, tools que esse path nunca vai chamar, metadata de contato que só existe numa conversa real. Se o seu agente reporta um teste verde como "funciona", esses warnings são justamente o que ele pulou.
As tools não rodam no path de texto puro. Elas rodam em voz, e dentro do step tool de um flow. O deploy ainda imprime "Tools synced" para um agente só de texto, porque as tools ficam registradas. Registrada não é invocada. Se o seu agente de WhatsApp precisa consultar alguma coisa, esse passo vai num flow.
Nunca devolva um success falso. Um handler que reporta { booked: true } sem ter agendado nada faz o agente dizer a uma pessoa real que a mesa dela existe. Devolva a falha. Essa é a forma mais comum de um agente que passa em todos os testes machucar um cliente, e vale dizer isso explicitamente no seu prompt.
Onde isso te deixa
Um agente que atende seus clientes é um arquivo no seu repo. Ele tem um prompt, algumas tools, um comando de deploy e um log que você consegue ler. O mesmo review, o mesmo version control, o mesmo rollback de tudo o mais que você publica.
Você entrou com a conta e o critério. O agente que já está no seu editor entrou com o resto.