~ / tutoriais /como-criar-um-agente-de-ia-do-zero $ _

Como criar um agente de IA do zero (com código, não no-code)

Lucas Souza Lucas Souza 11 min de leitura Tutoriais
Como criar um agente de IA do zero (com código, não no-code)

Você digita "como criar um agente de IA" no Google e a primeira página inteira te manda fazer a mesma coisa: criar uma conta numa plataforma, arrastar uns blocos, conectar um gatilho de WhatsApp e clicar em "Publicar". Funciona pra demo. Não funciona pra entender.

O problema não é a ferramenta no-code. O problema é que você termina o tutorial sem saber o que roda por baixo. E quando o agente alucina, entra em loop infinito ou estoura o custo de token, você não tem onde mexer — porque nunca viu o motor.

Neste tutorial você vai aprender como criar um agente de IA do zero, em código Python, escrevendo as três peças que toda plataforma esconde de você: o loop de raciocínio, o tool calling e a memória. Sem framework mágico. Sem arrastar bloco. Cerca de 70 linhas de Python e a API do Claude. No fim, você vai entender o que é um agente de verdade — e vai ter escrito o seu.

TL;DR

  • O que é: um agente de IA real, escrito em Python puro, com loop de raciocínio, tool calling e memória — sem LangChain, sem plataforma no-code.
  • Stack/Modelos: Python 3.11+, SDK oficial anthropic, modelo claude-opus-4-8.
  • Custo/Acesso: requer chave de API paga da Anthropic. O código é seu, roda onde você quiser.
  • Pré-requisito mental: entender que "agente" não é um produto que você compra. É um padrão de arquitetura que você implementa.

O contexto — por que os tutoriais que dominam o Google te deixam na mão

Agente de IA virou palavra de ordem. E como todo termo quente, virou também um mar de tutorial raso. A SERP brasileira pra "como criar um agente de IA com python" está lotada de dois tipos de conteúdo: ou é "monte um bot no n8n em 10 minutos", ou é uma lista genérica mandando você instalar TensorFlow, scikit-learn e spaCy — bibliotecas que não têm nada a ver com agentes baseados em LLM.

Os dois te deixam no mesmo lugar: sem modelo mental.

Aqui vai a definição que importa, e ela é mais simples do que o hype sugere. A própria Anthropic, no Building Effective Agents, define agente como um sistema onde "o LLM direciona dinamicamente seu próprio processo e uso de ferramentas, mantendo controle sobre como realiza a tarefa". Traduzindo pra engenharia: um agente é um LLM dentro de um loop, com acesso a ferramentas, que decide sozinho o que fazer a cada passo até concluir o objetivo.

É isso. Não tem mágica. Tem um while.

Se você quer a definição conceitual destrinchada — a diferença entre um agente de verdade e um if com esteroides — eu já escrevi sobre o que é um agente de IA aqui no blog. Este post é a outra metade: a parte prática, onde a gente constrói um.

O padrão tem até nome acadêmico — ReAct, de Reasoning + Acting — mas a ideia operacional cabe numa frase: o modelo raciocina, escolhe uma ação, você executa a ação, devolve o resultado, e o modelo raciocina de novo. Repete até ele dizer "terminei".

A plataforma no-code roda exatamente esse loop. Ela só não te deixa olhar pra dentro.

Pré-requisitos

Antes de escrever a primeira linha:

  • [ ] Chave de API da Anthropic (ANTHROPIC_API_KEY no ambiente).
  • [ ] Python 3.11+ e o SDK oficial: pip install anthropic.
  • [ ] Saber ler uma função Python e um dicionário. Sério, é só isso.

Nada de GPU, nada de treinar modelo, nada de vector database (ainda). Um agente é orquestração, não treinamento. Você não está construindo o cérebro — está construindo o sistema nervoso ao redor dele.

Mão na massa: como criar um agente de IA passo a passo

Vamos construir um agente que responde perguntas e consegue agir no mundo: consultar o horário atual e fazer contas que o modelo, sozinho, erraria. Cada passo adiciona uma das três peças.

Passo 1: a chamada base (o cérebro, sem corpo)

Antes do agente, o tijolo. Uma chamada ao LLM é stateless: você manda mensagens, recebe uma resposta.

import anthropic

client = anthropic.Anthropic()  # lê ANTHROPIC_API_KEY do ambiente

resposta = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Qual a raiz quadrada de 2.025?"}],
)

print(resposta.content[0].text)

Isso responde. Mas é um chat, não um agente. O modelo não pode consultar nada, não lembra de nada entre chamadas, e se você pedir uma conta difícil ele vai chutar com cara de confiança. Falta corpo.

Passo 2: dar ferramentas (tool calling)

Ferramenta, no contexto de LLM, é uma função sua que o modelo pode pedir pra você executar. Você descreve a função num schema JSON; o modelo, quando acha útil, devolve um bloco tool_use dizendo "execute calcular com esses argumentos". Quem roda o código é você — o modelo só decide quando e com quê.

TOOLS = [
    {
        "name": "calcular",
        "description": "Avalia uma expressão matemática em Python e retorna o resultado. "
                       "Use sempre que precisar de um cálculo exato.",
        "input_schema": {
            "type": "object",
            "properties": {
                "expressao": {
                    "type": "string",
                    "description": "Expressão Python válida, ex: '2025 ** 0.5'",
                }
            },
            "required": ["expressao"],
        },
    },
    {
        "name": "horario_atual",
        "description": "Retorna a data e hora atuais no fuso de São Paulo.",
        "input_schema": {"type": "object", "properties": {}},
    },
]

E as implementações reais — código Python comum, sem nada de especial:

from datetime import datetime
from zoneinfo import ZoneInfo

def calcular(expressao: str) -> str:
    # Em produção, NUNCA use eval() cru. Veja a seção de limitações.
    return str(eval(expressao, {"__builtins__": {}}, {}))

def horario_atual() -> str:
    return datetime.now(ZoneInfo("America/Sao_Paulo")).strftime("%d/%m/%Y %H:%M")

EXECUTORES = {"calcular": calcular, "horario_atual": horario_atual}

Repare na description de cada ferramenta. Ela não é decoração — é a interface. O modelo decide qual ferramenta chamar lendo a descrição. Descrição vaga gera agente que não usa a ferramenta na hora certa, ou usa na hora errada. Seja específico sobre quando usar, não só sobre o que a ferramenta faz.

Passo 3: o loop de raciocínio (o que faz dele um agente)

Aqui está a peça que nenhum tutorial de plataforma te mostra. Sem o loop, você tem uma chamada de função. Com o loop, você tem um agente.

A lógica: chame o modelo. Se ele parou com end_turn, terminou — entrega a resposta. Se ele parou com tool_use, ele quer agir: execute as ferramentas que ele pediu, devolva os resultados, e chame o modelo de novo. Repete.

def rodar_agente(pergunta: str, historico: list) -> str:
    historico.append({"role": "user", "content": pergunta})

    while True:
        resposta = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=2048,
            thinking={"type": "adaptive"},  # deixa o modelo raciocinar antes de agir
            tools=TOOLS,
            messages=historico,
        )

        # Guarda a vez do assistente no histórico (inclui os blocos tool_use)
        historico.append({"role": "assistant", "content": resposta.content})

        # Modelo concluiu — não pediu nenhuma ferramenta
        if resposta.stop_reason != "tool_use":
            return next(b.text for b in resposta.content if b.type == "text")

        # Modelo pediu ferramentas: executa cada uma e devolve os resultados
        resultados = []
        for bloco in resposta.content:
            if bloco.type == "tool_use":
                saida = EXECUTORES[bloco.name](**bloco.input)
                resultados.append({
                    "type": "tool_result",
                    "tool_use_id": bloco.id,
                    "content": saida,
                })

        historico.append({"role": "user", "content": resultados})

Leia esse while com calma, porque ele é o coração de todo agente — do mais simples ao Claude Code. O modelo não executa nada sozinho; ele pede. Seu código é quem decide se a ação acontece. Essa fronteira é exatamente o ponto onde você coloca validação, log, aprovação humana, limite de gasto. A plataforma no-code toma essas decisões por você — e é por isso que você não consegue mudá-las.

Passo 4: memória

Você já viu a memória nascer e nem percebeu: é a lista historico. Como a API é stateless, você é responsável por carregar a conversa inteira a cada chamada. Essa lista é a memória de curto prazo do agente — é o que faz ele lembrar do que você falou três mensagens atrás.

historico = []  # a memória do agente vive aqui

print(rodar_agente("Que horas são e quanto é a raiz quadrada de 2025?", historico))
print(rodar_agente("E o quadrado desse último número?", historico))  # ele lembra

Na segunda pergunta, "esse último número" só faz sentido porque o histórico inteiro viaja junto. Memória de longo prazo — que persiste entre sessões, sobrevive a um restart do processo — é o próximo degrau: você troca a lista em RAM por um banco, um arquivo, ou uma busca semântica com embeddings. Mas o mecanismo é o mesmo: montar o contexto certo antes de chamar o modelo. Memória de agente é engenharia de contexto, não feitiço.

E pronto. Loop de raciocínio, tool calling e memória. Esse é o agente inteiro. Não tem quarta peça secreta.

Limitações e pontos de atenção

O código acima ensina o conceito. Antes de botar algo parecido em produção, encare estas verdades:

  • eval() é uma porta dos fundos. Usei eval pra encurtar o exemplo, e mesmo com __builtins__ bloqueado isso não é seguro. Ferramenta que executa entrada do modelo precisa de sandbox, allowlist ou uma lib de expressão segura. Trate toda entrada do LLM como entrada de usuário hostil — porque com prompt injection, ela pode ser.
  • O loop pode não terminar. Um agente que insiste em chamar ferramenta nunca bate no end_turn. Sempre coloque um teto de iterações (for _ in range(10)) e uma estratégia pra quando ele estourar.
  • Custo escala com o histórico. Cada volta do loop reenvia a conversa inteira. Conversa longa = mais tokens por chamada = conta maior. É aqui que entram prompt caching e compactação de contexto.
  • Tool calling não conserta alucinação, só dá ferramentas. O modelo ainda pode chamar a ferramenta errada ou interpretar mal o resultado. Descrição boa, schema apertado e validação no seu lado são o que segura isso — é o teste dos 3 turnos que separa um brinquedo de um produto.

Esse bloco é o que separa quem leu um tutorial de quem entende o sistema. Não pule.

FAQ rápido

Preciso de LangChain ou de um framework de agente? Não pra aprender, e frequentemente não pra produção. A maioria dos agentes em produção roda em loop escrito à mão, justamente porque o framework esconde o controle que você precisa ter. Aprenda o loop primeiro; adote framework depois, se ele resolver uma dor real.

Isso funciona com OpenAI, Gemini, modelo local? Sim. O padrão — loop, tools, memória — é o mesmo em qualquer LLM que suporte tool calling. Muda o nome dos campos da API e o formato do tool_result. A arquitetura não muda.

Por que eval apareceu se você mesmo disse que é perigoso? Pra deixar o exemplo curto e focado no loop. Em código real, troque por uma avaliação de expressão com sandbox. O ponto do exemplo é o fluxo de tool calling, não a calculadora.

Quanto tempo até um agente de produção? Um protótipo que funciona sai numa tarde. Um agente de produção — com tools bem desenhadas, memória persistente, guardrails, testes e monitoramento — leva semanas. A diferença não é o loop. É tudo que você coloca ao redor dele.

Conclusão

Você acabou de escrever, em Python puro, as três peças que toda plataforma no-code cobra caro pra esconder: o loop de raciocínio que faz o modelo decidir, o tool calling que dá mãos a ele, e a memória que dá continuidade. Esse é o motor. Agora, quando um agente alucinar, entrar em loop ou estourar custo, você sabe exatamente onde abrir e mexer — porque você construiu.

O próximo salto não é arrastar mais blocos. É arquitetar: desenhar a superfície de ferramentas certa, escolher onde colocar validação e aprovação humana, gerenciar contexto e custo numa escala que aguenta produção. É exatamente esse terreno — sair do "loop que funciona na demo" para uma solução de IA que aguenta o mundo real — que a gente abre ao vivo, em código, no Workshop Arquitetando Soluções de IA. Se este post te deu o motor, o workshop é onde a gente projeta o carro.

Construir produto real com IA não começa quando você acha a plataforma certa. Começa quando você entende o que roda por baixo — e decide escrever o seu.

Lucas Souza
Lucas Souza

{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.

Você também pode gostar

VirguIA

beer & code assistant

conectando…

Não foi possível iniciar o chat agora.

tocando