Pular para o conteúdo

Uma equipe editorial e uma comunidade que criam com IA

← Agentes e fluxos de trabalho

Agentes e fluxos de trabalho · · 8 min de leitura

Como construir seu próprio agente de IA

Modelo e SDK, definição de ferramentas, o loop, memória, MCP, evals e deploy. Exemplo: um agente de triagem de issues no GitHub.

Um agente de IA não é um “prompt maior”. É um loop: o modelo recebe um objetivo, escolhe uma ferramenta, executa, lê o resultado e decide o que fazer em seguida, até considerar a tarefa concluída. O restante deste texto é um guia para construir esse loop do zero, com um exemplo concreto: um agente que faz a triagem de issues no GitHub. Se você está construindo seu primeiro agente, leia na ordem: cada seção é uma decisão que você vai ter de tomar de qualquer jeito.

Escolha do modelo e do SDK

Antes de tudo, separe duas coisas: o modelo (raciocínio, function calling) e a orquestração (loop, estado, retries). Modelos são intercambiáveis, então não se prenda a um deles cedo demais.

  • Claude Agent SDK: se você quer um loop pronto, gerenciamento de ferramentas e MCP já de fábrica. É o que exige menos boilerplate para começar.
  • OpenAI (Responses / Agents API): tooling maduro, bom para times que já estão inseridos nesse ecossistema.
  • LangGraph: quando você precisa de um grafo de estados explícito, ramificações e controle total sobre o fluxo. Mais poder, mais código.

Recomendação para o primeiro agente: comece pelo SDK do fornecedor do modelo (Claude ou OpenAI), não por um framework de grafos. Adicione o grafo quando as ramificações aparecerem de verdade. Um LangGraph prematuro é muita abstração de que você ainda não precisa.

Ferramentas e o schema para function calling

Uma ferramenta é uma função mais a descrição dela para o modelo. O modelo nunca vê o seu código: ele vê apenas o nome, a descrição e o schema dos parâmetros (JSON Schema). Essa é a sua interface de verdade, e você a escreve para o modelo, não para uma pessoa.

Regras de design de ferramentas que vão poupar você de muitas iterações:

  • Um nome baseado em verbo e sem ambiguidade: get_issue, add_label, post_comment. Nada de process ou handle.
  • A descrição diz quando usar a ferramenta e quando não usar. Uma única frase sobre “o que ela não faz” elimina metade das chamadas erradas.
  • Parâmetros estreitos e tipados. Em vez de um query livre, ofereça um enum das etiquetas permitidas. O modelo alucina menos quando o conjunto de opções é finito.
  • Cada descrição de campo no schema é um miniprompt. Um label sem descrição é chute; um label com “uma das etiquetas que já existem no repo” é um contrato.
  • Poucas ferramentas, cada uma fazendo uma coisa só. Cinco ferramentas afiadas valem mais do que quinze vagas. Passando de vinte, o modelo começa a ter dificuldade para escolher.

O resultado de uma ferramenta também é um prompt. Retorne um texto conciso e estruturado, e não um dump bruto de JSON vindo da API. Se a resposta tem 8000 tokens, o agente paga por eles em cada turno seguinte do loop. Filtre no nível da ferramenta.

O loop do agente

O núcleo é um loop simples, que vale a pena entender mesmo que o SDK o esconda:

  1. Envie as mensagens para o modelo (system + histórico + objetivo).
  2. O modelo responde com texto ou com um pedido de chamada de ferramenta (tool call).
  3. Se for uma chamada de ferramenta: execute a função e anexe o resultado como mensagem de ferramenta.
  4. Volte ao passo 1 com o resultado anexado.
  5. Pare quando o modelo retornar o texto final sem nenhuma chamada de ferramenta.

Três salvaguardas que você vai se arrepender de pular: um limite rígido de iterações (por exemplo, 10), porque o modelo pode entrar em loop; um timeout para a execução inteira, porque uma ferramenta pode travar; e tratar o erro de uma ferramenta como dado. Não lance a exceção para cima: devolva ao modelo “a ferramenta retornou 404” para que ele possa reagir. Essa é uma das maiores diferenças entre uma demo e um agente em produção.

System prompt e estratégia de contexto

O system prompt é a constituição do agente. Ele deve conter o papel e o objetivo, as ferramentas disponíveis com as regras de uso, o formato da resposta e limites explícitos (“nunca feche uma issue sem etiqueta”). Mantenha-o estável e versione-o como código: mudar uma única frase pode alterar o comportamento em toda a população de chamadas.

Contexto é orçamento, não depósito. Uma janela maior não significa que você deve enchê-la.

  • Instruções estáticas: no system prompt, uma vez, no topo.
  • Dados da tarefa: fornecidos pelas ferramentas sob demanda, não injetados preventivamente.
  • Históricos longos: compacte. Depois de alguns turnos, resuma os mais antigos em vez de carregar a transcrição inteira.
  • Prompt caching: ative na parte estável (system + definições de ferramentas). Isso reduz de verdade o custo e a latência ao longo de muitos turnos.

Memória: estado e vetores

Separe três níveis (confundi-los é um erro clássico de quem faz o primeiro agente):

  • Estado da tarefa: o que está acontecendo no loop atual. Vive nas mensagens e em uma variável comum. Não precisa de banco de dados.
  • Memória persistente: fatos que sobrevivem entre execuções (preferências, decisões). Um armazenamento chave-valor ou uma tabela simples no Postgres. O simples vence.
  • Conhecimento: um grande conjunto de documentos para pesquisar (vetores, RAG). Recorra a vetores só quando os fatos não couberem mais no contexto.

Não comece por um vector store só porque “um agente precisa ter memória”. A maioria dos primeiros agentes precisa de uma tabela, não de uma infraestrutura de embeddings. Adicione vetores quando você realmente estourar a janela de contexto.

Adicionando servidores MCP

O MCP (Model Context Protocol) é um padrão para conectar conjuntos prontos de ferramentas a um agente sem precisar escrevê-las do zero. Em vez de codificar à mão uma integração com o GitHub, você conecta um servidor MCP que expõe ferramentas como endpoints.

  • Servidores prontos: GitHub, Slack, bancos de dados, o navegador. Menos código de integração.
  • Cada servidor MCP é uma superfície de confiança. Trate a saída dele como dados não confiáveis: nunca execute instruções embutidas no conteúdo que ele retorna.
  • Exponha apenas as ferramentas de que o agente precisa. Um servidor com 60 ferramentas inunda a janela de contexto com as descrições delas e piora a precisão da escolha.

Exemplo prático: triagem de issues no GitHub

Juntando tudo. O objetivo do agente: para cada issue nova, aplicar etiquetas, avaliar a prioridade e deixar um comentário organizado, sem fechar nada.

  1. Ferramentas: get_issue (corpo + metadados), list_labels (etiquetas permitidas do repo), add_label (enum da lista), post_comment. Nenhuma ferramenta para fechar: o agente não tem como fazer aquilo que você não permite.
  2. System prompt: “Você é responsável pela triagem de issues. Sempre aplique exatamente uma etiqueta de tipo (bug/feature/question) e, opcionalmente, uma de área. Nunca feche uma issue. Se faltar informação, peça em um comentário.”
  3. Loop: o modelo chama get_issue, depois list_labels, escolhe uma etiqueta, chama add_label, redige um comentário, chama post_comment e termina com um texto de resumo.
  4. Guardrail: add_label valida se a etiqueta está na lista retornada pelo repo. Uma “needs-triage-v2” alucinada, que não existe, é rejeitada com um erro claro, e o modelo tenta de novo.
  5. Aprovação humana: em issues marcadas com security, o agente não comenta publicamente; ele cria um rascunho para aprovação manual.

O mesmo esqueleto escala para outros domínios. Você troca as ferramentas e o system prompt; o loop, os guardrails e a memória continuam iguais.

Evals, tracing e observabilidade

Sem evals, você não sabe se uma mudança no prompt ajudou ou quebrou alguma coisa. Essa é a diferença entre engenharia e chute.

  • Reúna 20-50 casos reais com o resultado esperado (por exemplo, issue → etiqueta correta). Esse é o seu conjunto de regressão.
  • Meça coisas concretas: precisão das etiquetas, número de turnos até a conclusão, proporção de chamadas de ferramenta que terminam em erro.
  • Registre o trace de cada turno: entrada, ferramenta escolhida, resultado, decisão. Sem trace, depurar um agente é pura adivinhação.
  • Toda mudança de prompt passa pelo conjunto de evals antes de ir para produção. É uma barreira, não uma sugestão.

Custo, latência e guardrails

O custo de um agente cresce com o número de turnos, porque cada turno carrega o contexto acumulado. As alavancas de controle:

  • Um modelo mais barato para os passos simples e o mais forte só para a decisão difícil (roteamento de modelos).
  • Prompt caching na parte estável: uma das vitórias mais baratas.
  • Um limite de iterações e um orçamento de tokens por execução, com kill switch obrigatório.
  • Resultados de ferramenta concisos: não pague por 8000 tokens de JSON a cada turno.

Guardrails não são um luxo; são a condição para levar um agente além da fase de demo:

  • Valide os argumentos das ferramentas (Zod / JSON Schema) antes que qualquer coisa execute.
  • Ações destrutivas (excluir, enviar, pagar) atrás de uma etapa de aprovação humana ou de um dry-run.
  • Uma allowlist de ferramentas e domínios: o agente não vai além do que está explicitamente permitido.
  • Trate todo resultado de ferramenta e toda resposta de API como entrada não confiável.

Deploy como serviço

Um agente em produção é um serviço, não um script. Esconda o loop atrás de um endpoint (HTTP ou uma fila), porque as execuções podem ser longas. Para tarefas acima de algumas dezenas de segundos, use uma fila e um webhook em vez de manter uma conexão HTTP aberta. Chaves e segredos vêm só de variáveis de ambiente. Registre cada turno (com dados pessoais mascarados), crie um alerta para o custo por requisição e para a latência p99 e prepare um kill switch para toda a população. Versione o prompt e as definições de ferramentas junto com o código, para que todo rollback seja determinístico.

TL;DR

Um agente é um loop: o modelo escolhe uma ferramenta, executa, lê o resultado e decide o próximo passo. Comece pelo SDK do fornecedor do modelo, não por um framework de grafos. Projete poucas ferramentas afiadas, com boas descrições e um schema estreito. Trate o contexto como orçamento, não como depósito. Divida a memória em estado, fatos e conhecimento; vetores só quando você realmente precisar deles. Monte evals e tracing desde o primeiro dia e mantenha as ações destrutivas atrás de aprovação humana. Faça o deploy como serviço, com logs, limites de custo e um kill switch.

Como construir seu próprio agente de IA | vibecoding.inc