IA

WhatsApp como ferramenta no LangChain e no CrewAI (Python)

Para usar o WhatsApp como ferramenta no LangChain ou no CrewAI, você escreve uma função Python que chama a API do ZapZap (por exemplo POST /send/text), a registra com o decorador tool e a entrega ao agente. O ponto crítico é o que cercar essa função: validação do número, lista permitida, limite de volume e aprovação humana. Abaixo estão os dois frameworks com código, nas versões atuais em 27/10/2026.

Publicado em · 6 min de leitura

Este artigo também está disponível em: English · Español

Como um agente usa a API do WhatsApp como ferramenta

Em frameworks de agentes, uma ferramenta (tool) é uma função com nome, descrição e esquema de parâmetros. O modelo de IA lê a descrição, decide se a ferramenta ajuda na tarefa e devolve os argumentos; o framework executa a função e devolve o resultado ao modelo. Para o WhatsApp, as funções são finas: cada uma chama um endpoint da API.

Duas consequências de projeto. A descrição da ferramenta é parte do prompt: escreva-a como instrução clara, dizendo o que faz, o formato do número (DDI, só dígitos) e quando não usar. E a função é o lugar das travas: o modelo pode errar ou ser induzido por texto malicioso, então a validação não pode depender dele.

Versões e estado do ecossistema

Estado conferido no PyPI em 27/10/2026: langchain 1.4.7, langchain-core 1.7.0 e crewai 1.15.30. Os dois projetos mudam rápido e já tiveram quebras entre versões maiores; os exemplos usam create_agent do LangChain 1.x e o decorador tool do CrewAI 1.x. Se você usa outra versão, confira a documentação dela antes de copiar.

Não existe, nesta data, um pacote do ZapZap para LangChain ou CrewAI nem um servidor MCP próprio; o que existe é a API REST e o OpenAPI. Por isso as ferramentas abaixo são código seu, sobre a API. Para o caminho via MCP, veja o guia de servidor MCP de WhatsApp.

Camada compartilhada: um cliente Python com travas

Escreva primeiro um módulo que fala com a API e aplica as regras. Os dois frameworks reutilizam. Ele valida o formato do número, restringe a destinatários permitidos, limita o tamanho do texto e conta envios por hora. Isso fica fora do prompt de propósito.

As credenciais vêm de variáveis de ambiente. Instale com pip install requests langchain crewai e defina ZAPZAP_INSTANCE_ID, ZAPZAP_API_KEY, ZAPZAP_API_SECRET, ZAPZAP_ALLOWED (números separados por vírgula) e, para liberar o envio real, ZAPZAP_ENABLE_SEND=true.

Python (zapzap_tools.py)

import os
import re
import time

import requests

BASE = "https://api.zapzapapi.com/api/v1/" + os.environ["ZAPZAP_INSTANCE_ID"]
HEADERS = {
    "Content-Type": "application/json",
    "x-api-key": os.environ["ZAPZAP_API_KEY"],
    "x-api-secret": os.environ["ZAPZAP_API_SECRET"],
}
ALLOWED = {n for n in os.environ.get("ZAPZAP_ALLOWED", "").split(",") if n}
SEND_ENABLED = os.environ.get("ZAPZAP_ENABLE_SEND") == "true"
MAX_PER_HOUR = 20
_sent = []


def _post(path, body):
    r = requests.post(BASE + path, json=body, headers=HEADERS, timeout=30)
    r.raise_for_status()
    return r.text


def status_instancia():
    r = requests.get(BASE + "/instance/status", headers=HEADERS, timeout=30)
    r.raise_for_status()
    return r.text


def verificar_numeros(numeros):
    if not numeros or len(numeros) > 50 or not all(re.fullmatch(r"\d{10,15}", n) for n in numeros):
        raise ValueError("invalid numbers: use country code and digits only")
    return _post("/chat/check", {"numbers": numeros})


def enviar_texto(numero, texto):
    if not SEND_ENABLED:
        return "sending disabled (safe mode)"
    if not re.fullmatch(r"\d{10,15}", numero):
        raise ValueError("invalid number: use country code and digits only")
    if numero not in ALLOWED:
        raise PermissionError("number not in the allowed list")
    if not texto or len(texto) > 1000:
        raise ValueError("text empty or too long")
    agora = time.time()
    _sent[:] = [t for t in _sent if agora - t < 3600]
    if len(_sent) >= MAX_PER_HOUR:
        raise RuntimeError("hourly limit reached")
    _sent.append(agora)
    return _post("/send/text", {"number": numero, "text": texto})

LangChain: registrar as funções como ferramentas e criar o agente

No LangChain, o decorador tool (de langchain_core.tools) transforma a função em ferramenta; a docstring vira a descrição e as anotações de tipo viram o esquema. create_agent monta o agente com o modelo, as ferramentas e o prompt de sistema. O modelo vem do provedor que você configurar (a string no formato provedor:modelo é preenchida por você), e o custo desse provedor é separado.

A invocação recebe uma lista de mensagens e devolve o estado com as mensagens finais. Para exigir aprovação humana antes do envio, o LangChain oferece mecanismos de interrupção (middleware e checkpointer); como a API varia por versão, o exemplo mantém o envio desativado por padrão e deixa a aprovação por sua conta, conforme a documentação da sua versão.

Python (LangChain)

from langchain.agents import create_agent
from langchain_core.tools import tool

import zapzap_tools as zap


@tool
def status_whatsapp() -> str:
    """Mostra se a instancia de WhatsApp esta conectada."""
    return zap.status_instancia()


@tool
def verificar_numeros_whatsapp(numeros: list[str]) -> str:
    """Verifica quais numeros tem WhatsApp. Use DDI e so digitos, ex: 5511999999999."""
    return zap.verificar_numeros(numeros)


@tool
def enviar_whatsapp(numero: str, texto: str) -> str:
    """Envia uma mensagem de texto. Use so quando o usuario pedir explicitamente. Numero com DDI e so digitos."""
    return zap.enviar_texto(numero, texto)


agente = create_agent(
    "SEU_PROVEDOR:SEU_MODELO",
    tools=[status_whatsapp, verificar_numeros_whatsapp, enviar_whatsapp],
    system_prompt="Voce ajuda a equipe com tarefas de WhatsApp. Nunca envie mensagem sem pedido explicito. Se faltar dado, pergunte.",
)

resultado = agente.invoke(
    {"messages": [{"role": "user", "content": "Veja se a instancia esta conectada e se 5511999999999 tem WhatsApp."}]}
)
print(resultado["messages"][-1].content)

CrewAI: agentes, tarefas e a mesma camada de travas

No CrewAI, o decorador tool (de crewai.tools) cria a ferramenta a partir da função e do nome. Você define um Agent com papel, objetivo e história, uma Task com descrição e saída esperada, e uma Crew que junta os dois. kickoff executa. O modelo é configurado conforme a documentação do CrewAI para o provedor que você usar.

CrewAI brilha quando há mais de um papel, por exemplo um agente que redige a mensagem e outro que revisa o tom antes do envio. Para WhatsApp, vale um desenho em que o agente de envio só recebe texto já revisado e que a Task de envio exige confirmação humana (parâmetro human_input da Task, conforme a documentação da versão).

Python (CrewAI)

from crewai import Agent, Crew, Task
from crewai.tools import tool

import zapzap_tools as zap


@tool("verificar_numeros_whatsapp")
def verificar_numeros_whatsapp(numeros: list[str]) -> str:
    """Verifica quais numeros tem WhatsApp. Use DDI e so digitos, ex: 5511999999999."""
    return zap.verificar_numeros(numeros)


@tool("enviar_whatsapp")
def enviar_whatsapp(numero: str, texto: str) -> str:
    """Envia uma mensagem de texto para um numero da lista permitida."""
    return zap.enviar_texto(numero, texto)


operador = Agent(
    role="Operador de WhatsApp",
    goal="Executar tarefas de WhatsApp com seguranca e sem enviar nada que nao tenha sido pedido",
    backstory="Voce cuida do canal de WhatsApp da empresa e segue as regras da lista permitida.",
    tools=[verificar_numeros_whatsapp, enviar_whatsapp],
)

tarefa = Task(
    description="Verifique se o numero 5511999999999 tem WhatsApp e informe o resultado. Nao envie mensagens.",
    expected_output="Uma frase dizendo se o numero tem WhatsApp.",
    agent=operador,
)

crew = Crew(agents=[operador], tasks=[tarefa])
print(crew.kickoff())

Quais travas manter, independentemente do framework

TravaOnde ficaPor quê
Lista permitida de númerosNa função, não no promptO modelo pode errar ou ser induzido
Validação de formatoNa funçãoEvita número inválido e injeção em campos
Limite por horaNa função ou na filaContém erro de laço do agente
Aprovação humanaNo framework ou no seu fluxoÚltima barreira antes do envio real
Modo seguro por padrãoVariável de ambienteDesenvolvimento sem enviar de verdade
Log de toda chamadaNa funçãoAuditoria e depuração
Instância dedicadaNa contaIsola o risco do número principal

Agentes entram em laço, repetem ferramenta e se confundem. Defina um número máximo de passos no framework e trate qualquer exceção da função como resultado legível para o modelo, sem expor credenciais. Mensagens recebidas que o agente lê são entrada não confiável: um cliente pode escrever instruções para o modelo, e a lista permitida e a aprovação são o que impede o dano.

Do protótipo à produção: limites do canal e próximos passos

A ferramenta é só o braço; o canal continua com as regras dele. O envio automatizado está sujeito aos Termos do WhatsApp, e nenhum agente reduz o risco de restrição do número; ele pode aumentá-lo se começar conversas frias em volume. Use o agente para responder a quem escreveu primeiro, apoiar a equipe e executar tarefas internas. O guia de anti-bloqueio e a LGPD valem aqui como em qualquer envio.

Para receber as mensagens que o agente vai tratar, configure o webhook da instância (veja webhook e o guia de mídia pelo webhook) e entregue o evento ao agente por uma fila. A referência de rotas está em API de WhatsApp, e o passo a passo da conta no início rápido.

Resumo rápido

  • Uma ferramenta de agente é uma função Python que chama um endpoint da API; a docstring é a descrição que o modelo lê.
  • No LangChain 1.x use tool e create_agent; no CrewAI 1.x use o decorador tool com Agent, Task e Crew.
  • Coloque as travas na função: lista permitida, validação, limite por hora e modo seguro por padrão.
  • Exija aprovação humana antes do envio real e trate mensagens lidas como entrada não confiável.
  • Não existe pacote ou servidor MCP próprio do ZapZap para esses frameworks em 27/10/2026; a base é a API REST.

Perguntas frequentes

Existe um plugin do ZapZap para LangChain ou CrewAI?

Não, em 27/10/2026. O que existe é a API REST com referência por endpoint e arquivo OpenAPI, e um pacote de nós para n8n. Os exemplos do guia são código seu sobre a API, usando o decorador tool de cada framework.

Como impedir que o agente envie mensagem para qualquer número?

Coloque a lista permitida dentro da função da ferramenta, não no prompt, e valide o formato do número. Some limite por hora, modo seguro por padrão e aprovação humana antes do envio real.

Qual framework escolher: LangChain ou CrewAI?

LangChain atende bem um agente único com várias ferramentas e fluxos controlados. CrewAI é mais natural quando há papéis distintos (redigir, revisar, enviar). Para WhatsApp, a decisão pesa menos que as travas e a aprovação humana.

O agente pode receber mensagens do WhatsApp?

Sim, pelo webhook da instância: registre uma URL, ative o evento messages e entregue cada evento ao agente por uma fila, filtrando mensagens suas e eventos duplicados. As ferramentas cobrem o envio e as consultas.

Preciso de um modelo específico de IA?

Não. Os frameworks aceitam vários provedores; use o que você tem credencial. Teste com conversas reais e prefira modelos bons em chamar ferramentas, medindo custo e latência no seu caso.

Dê ao seu agente um canal de WhatsApp

Crie a conta, verifique o telefone e receba o crédito de boas-vindas, sem depositar (um por telefone, sujeito à campanha vigente). Conecte um número por QR code e teste as ferramentas em modo seguro.