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 deprocessouhandle. - 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
querylivre, 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
labelsem descrição é chute; umlabelcom “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:
- Envie as mensagens para o modelo (system + histórico + objetivo).
- O modelo responde com texto ou com um pedido de chamada de ferramenta (tool call).
- Se for uma chamada de ferramenta: execute a função e anexe o resultado como mensagem de ferramenta.
- Volte ao passo 1 com o resultado anexado.
- 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.
- 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. - 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.”
- Loop: o modelo chama
get_issue, depoislist_labels, escolhe uma etiqueta, chamaadd_label, redige um comentário, chamapost_commente termina com um texto de resumo. - Guardrail:
add_labelvalida 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. - 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.