1. O que afinal é um agente e por que você precisa dele
Agentes não são parte obrigatória do ChatGPT App: dá para criar quantos apps incríveis você quiser sem usar agentes de LLM. Ainda assim, tenho três bons motivos para falar sobre eles.
Agentes são uma excelente forma de adicionar inteligência ao backend do seu aplicativo. Escolha inteligente de presentes, análise dos desejos textuais do usuário. Cenários complexos de busca, análise, processamento e sumarização — tudo isso fica muito fácil com agentes de LLM.
O ChatGPT lançou sua Agents SDK em TS e Python. Ela é muito boa. A orquestração de agentes vem pronta. Em uma tarefa complexa não trabalhará apenas um agente, mas uma equipe inteira. É uma direção muito promissora.
E há ainda o objetivo educacional. O ChatGPT chama mcp-tools exatamente como agentes de LLM chamam seus tools. Assim que você entender como os agentes de LLM funcionam, ficará claro, por exemplo, como implementar uma máquina de estados no lado do modelo dentro do aplicativo. Além disso, estudar a Agents SDK dá uma noção de como o ChatGPT SDK deve funcionar no futuro.
Então vamos começar.
O que é um agente LLM
Se o ChatGPT App é a “fachada” bonita e prática do seu serviço dentro do ChatGPT, e o servidor MCP é o “motor” com ferramentas e lógica de negócio, então o agente é algo como um despachante inteligente que sabe:
- ler o objetivo;
- decidir por conta própria quais ferramentas chamar e em que ordem;
- pedir dados adicionais quando necessário;
- repetir etapas em caso de erros;
- chegar a um resultado final claro.
Em uma formulação próxima à documentação oficial da Agents SDK, um agente é um programa. Tendo acesso a uma LLM e a um conjunto de ferramentas, ele é capaz de planejar etapas de forma autônoma para atingir um objetivo e executá-las por meio de tool‑calls.
Fazendo um paralelo com o que você já tem:
- No ChatGPT App comum, o modelo do ChatGPT orquestra as chamadas dos seus MCP‑tools diretamente.
- Um agente de LLM no backend também tem a descrição da tarefa, um conjunto de ferramentas e decide por conta própria quais tools chamar, quantas etapas executar, quando parar e qual resultado retornar.
No contexto do nosso GiftGenius isso pode ser assim:
- Aplicativo sem agente: o modelo chama diretamente searchGifts, depois filterByBudget, depois getDetails — pensando do zero a cada vez;
- Aplicativo com agente: o ChatGPT chama um mcp‑tool, e o backend passa ao agente a tarefa: “Encontre o top 5 de presentes para tal perfil”. O agente executa várias etapas: coleta informações adicionais, chama diferentes ferramentas de busca, filtra, ordena, monta os cards finais e retorna uma resposta estruturada pronta.
O ChatGPT e um agente de LLM no backend são como o diretor de uma empresa e um funcionário. O ChatGPT tem muito mais liberdade: ele conversa com o usuário e decide quais tarefas estratégicas iniciar (chamar mcp tools). O agente de LLM trabalha apenas no backend, não interage com o usuário, mas também “pensa” e pode chamar seus tool. Uma espécie de ChatGPT no modo básico.
2. Do que é feito um agente: LLM, instruções, ferramentas e estado
É útil pensar no agente como camadas.
Em primeiro lugar, por baixo do capô temos a mesma LLM. Pode ser a GPT‑5.1 ou outro modelo usado pela Agents SDK. Ela gera texto, planeja etapas, escolhe ferramentas — em suma, cuida do “raciocínio”, mas agora no seu contexto de orquestração.
Em segundo lugar, sobre o modelo vêm as instruções. É o prompt de sistema do agente, que define o papel, os limites, o estilo de comunicação, como usar as ferramentas. Você já fez algo parecido para o ChatGPT App, mas agora isso se aplica a um agente específico.
Em terceiro lugar, há um conjunto de ferramentas do agente. Podem ser:
- funções em TypeScript (function calling clássico);
- ferramentas HTTP/REST;
- wrappers sobre seus MCP‑tools, para que o agente possa acessar o mesmo backend que o ChatGPT App;
- ferramentas “hosted” integradas da própria OpenAI (por exemplo, web‑search, se você as habilitar).
E, por fim, existem regras de trabalho com estado e etapas: como é mantido o estado de sessão (session state), como os resultados intermediários são armazenados, como os loops são limitados. Falaremos mais a fundo sobre isso na próxima aula sobre memória e estado, mas já agora é útil ter em mente que o agente não é uma “requisição única”, e sim um processo potencialmente longo com progresso persistente.
Se você olhar para isso com os olhos de um desenvolvedor TypeScript, mentalmente sai um objeto mais ou menos assim (pseudocódigo, próximo à Agents SDK em TS):
const giftAgent = new Agent({
model: "gpt-5.1",
systemPrompt: giftAgentPrompt,
tools: { searchGifts, filterGifts, checkoutDraft },
// aqui mesmo — configurações de memória, limites de passos etc.
});
Por ora não vamos nos aprofundar no API exato; o importante é a imagem: modelo, instruções, ferramentas e configurações de comportamento em um só lugar.
3. Roles das mensagens: system / user / assistant / tool no mundo do agente
Você já conhece as roles clássicas system, user, assistant e tool do Chat Completions. Na Agents SDK elas são mantidas, mas ganham um sentido um pouco mais aplicado.
A role system define a personalidade e a missão do agente. Por exemplo, para o agente do GiftGenius pode ser: “Você é um agente de recomendação de presentes. Sua tarefa é, no menor número de etapas, selecionar de 3 a 7 opções de presentes relevantes com base no perfil do destinatário e no orçamento, e depois preparar um JSON estruturado para o widget”. Aqui você também descreve as limitações: o que ele não deve fazer (por exemplo, não realizar compras reais sem uma etapa separada) e como deve trabalhar com as ferramentas.
A role user no contexto do agente não é necessariamente “uma pessoa real”. Na maioria das vezes é uma “tarefa” para o agente: um objetivo formulado pelo seu App, serviço ou outro agente. Por exemplo, o ChatGPT App pode chamar o agente com uma mensagem user: “Sugira 5 ideias de presentes para um colega desenvolvedor, orçamento de 50 dólares, ocasião: aniversário”.
A role assistant é o que “fala” o próprio modelo dentro do agente. Aqui podem aparecer tanto raciocínios e planos intermediários quanto a resposta final. Sua tarefa é configurar o prompt de sistema de modo que essas mensagens sejam úteis e, se necessário, registradas em logs.
A role tool (ou seus análogos no SDK específico) descreve os resultados das chamadas de ferramentas: “via MCP foram encontrados 50 produtos”, “a API retornou um erro de timeout”, “o BD devolveu o perfil do usuário”. Essas mensagens, junto com as mensagens de assistant, formam o histórico do run‑ciclo do agente.
É prático resumir isso em uma pequena tabela:
| Role | Quem fala | Exemplo no contexto do GiftGenius |
|---|---|---|
|
Você (como desenvolvedor do agente) | “Você é um agente de recomendação de presentes…” |
|
Chamada externa (App, outro agente) | “Escolha 5 presentes até US$ 50…” |
|
O modelo dentro do agente | “Plano: 1) pedir detalhes…” |
|
Resultado da ferramenta chamada | “searchGifts retornou 20 opções…” |
Essa estrutura é importante porque é exatamente sobre ela que se constrói o run‑ciclo — o protagonista da aula de hoje.
4. Como a LLM chama funções no seu backend
Quando você se acostuma ao modo “pergunta–resposta”, parece que a LLM funciona de maneira simples: chega um texto → o modelo responde com texto. Na verdade, por baixo do capô tudo é um pouco mais complexo e é justamente por isso que o function calling funciona.
O modelo não recebe uma única pergunta, ele recebe uma lista de mensagens — o histórico do diálogo. Lá já estão todas as falas anteriores: instruções de sistema (“quem você é e o que pode/não pode”), suas mensagens, respostas anteriores do modelo, resultados de ferramentas. A cada etapa o modelo olha para toda essa linha do tempo, como um log de chat, e decide: “Qual é a próxima mensagem que deve ser adicionada ao final?”.
Essa é a ideia-chave: a LLM sempre dá um passo por vez — ela acrescenta a próxima mensagem ao final do histórico. Ela não “muda o passado” nem edita mensagens antigas; apenas continua a lista. Você escreve uma pergunta, o modelo responde. Você adiciona a segunda pergunta, o modelo responde de novo, mas levando em conta toda a história do diálogo (todas as mensagens).
O function calling é construído sobre esse mesmo princípio. Em vez de “executar a função” diretamente, o modelo faz o seguinte:
- vê a lista de ferramentas/tools disponíveis e suas descrições junto com o histórico do diálogo;
- decide: “Agora faz mais sentido não apenas responder em texto, mas primeiro chamar tal ferramenta”;
- e como a próxima mensagem adiciona ao histórico não uma resposta textual comum, mas uma mensagem especial no formato “quero chamar tal tool com tais argumentos”.
Depois, não é o modelo, mas seu backend que lê essa nova mensagem no final do histórico, entende que é um pedido para chamar uma função e chama a ferramenta necessária. Em seguida, adiciona ao histórico mais uma mensagem — com o resultado do tool — e envia de novo a lista completa de mensagens ao modelo. O modelo olha novamente para toda a linha do tempo e acrescenta o próximo passo: ou outra chamada, ou já a resposta final legível.
Ou seja:
- para Q&A comum: “próxima mensagem” = resposta em texto;
- para function calling: “próxima mensagem” = instrução para chamar uma função ou resposta após usar a função.
Não existe nenhum “comando mágico separado para chamar função” — é apenas um tipo especial de próxima mensagem que o modelo adiciona ao final da cadeia.
O modelo não chama funções do seu backend via API público. Ele simplesmente “escreve no chat” que quer chamar uma função com parâmetros. E então o seu backend chama a função local e escreve a resposta dela no chat. E tudo recomeça.
5. Run‑ciclo do agente: como ele “pensa” passo a passo
Na prática, um agente de LLM é um certo objeto/algoritmo no seu servidor que executa o run‑ciclo do agente — é o ciclo expandido “pergunta → pensar → possivelmente agir → pensar de novo → … → resposta final”. Na documentação da OpenAI isso às vezes é chamado de agent loop ou padrão ReAct (Reason + Act + Observe).
Nível conceitual: um run do agente se parece com isto:
- O agente recebe a entrada: instruções de sistema, a tarefa (mensagem user), e possivelmente o estado atual.
- O modelo gera um passo: uma resposta em texto, ou um plano e a decisão de chamar uma ou mais ferramentas.
- Se o modelo escolheu um tool‑call, o agente chama a ferramenta correspondente no código (pode ser função local, MCP‑tool, requisição HTTP, acesso a BD etc.).
- Os resultados das ferramentas são adicionados ao histórico como mensagens tool.
- O ciclo volta ao modelo com o novo contexto. O modelo decide o que fazer em seguida: continuar o planejamento, chamar outra ferramenta ou encerrar a tarefa com a resposta final.
- Quando o modelo encerra explicitamente ou pelas condições de parada o run, o agente retorna o resultado final ao chamador.
Em um diagrama simples, isso pode ser mostrado assim:
flowchart TD
A[Início do run: objetivo + system] --> B[Chamada do modelo]
B --> C{O modelo quer
responder em texto
ou chamar um tool?}
C --> D["Resposta em texto
(assistant)"]
D --> E{A tarefa terminou?}
E -->|Sim| F[Resultado final]
E -->|Não| B
C --> G["Tool‑call
(descrição da chamada)"]
G --> H[Chamada de função / MCP / HTTP]
H --> I["Resultado do tool
(mensagem tool)"]
I --> B
Traduzindo isso para um pseudocódigo TypeScript simplificado (distante do API real, mas logicamente correto), fica algo como:
async function runAgent(goal: string) {
let context = buildInitialContext(goal);
while (!isFinished(context)) {
const decision = await callLLM(context); // passo do agente
if (decision.type === "tool_call") { // chamar função?
const toolResult = await callTool(decision.tool, decision.args); // chamamos a função local
context = appendToolResult(context, toolResult); // adicionamos o resultado ao fim da lista
} else {
context = appendAssistantMessage(context, decision.message);
}
enforceLimits(context); // limites de passos/tempo/ciclos
}
return extractFinalResult(context);
}
A Agents SDK cuida de grande parte dessa rotina: armazenamento do histórico, marshalling de tool‑calls, lógica de repetição etc. Você só precisa configurar e implementar as próprias ferramentas.
Run vs step
É importante distinguir dois conceitos:
- run — uma execução do agente para um objetivo: “selecione presentes para esta ocasião”;
- step — um passo do run‑ciclo: uma chamada específica ao modelo, que pode resultar em resposta textual ou em um tool‑call.
No monitoramento você verá justamente muitos passos dentro de um run, e os limites de segurança e custo costumam ser definidos ou “por run” ou “por passo”.
Agora que está claro como o agente vive dentro de um run e caminha pelo run‑ciclo, vamos ver onde faz sentido usar tudo isso e onde ferramentas simples bastam.
5. Onde o agente é necessário no GiftGenius e onde ele é dispensável
Antes de sair escrevendo um agente para tudo, vale a pena fazer uma pergunta honesta: “Ele é realmente necessário aqui?”.
Um bom cenário para um agente é uma tarefa multi‑etapas com ramificações, repetições e lógica que é incômoda de manter apenas em prompts.
No GiftGenius, uma tarefa assim pode ser um “assistente de seleção inteligente de presentes”, que:
- é capaz de perguntar detalhes importantes (gênero do destinatário, hobbies, nível de proximidade);
- pode consultar várias fontes de produtos (diferentes fornecedores via MCP‑tools);
- filtra e ranqueia os resultados;
- em caso de erro nas fontes, repete a tentativa ou segue um caminho alternativo;
- retorna não apenas uma lista de textos, mas uma lista estruturada de candidatos com explicações e links para SKUs do product feed.
Aqui o agente será realmente útil como “orquestrador”, especialmente se depois você quiser complementar com um cenário de voz/Realtime ou comércio complexo (ACP).
Já para uma chamada simples getGiftDetails(giftId) não é necessário agente: um MCP‑tool comum, chamado diretamente pelo ChatGPT, cobre completamente o caso. O mesmo vale para cenários “de uma etapa”, como “descreva este presente a partir do texto da ficha de produto”.
A regra prática é: se o cenário pode ser descrito como “uma ferramenta normal”, provavelmente você não precisa de um agente. Mas se você começa a descrever explicitamente um workflow multi‑etapas com verificações e novas tentativas, é bem provável que um agente vá te agradar.
6. Determinismo: como tornar o comportamento do agente previsível
Determinismo no mundo de agentes de LLM é algo sutil. Teoricamente, com a mesma entrada e as mesmas configurações, você quer obter o mesmo plano de ação e a mesma sequência de tool‑calls. Na prática, o modelo continua estocástico, mas você tem algumas alavancas para controlar a previsibilidade.
Primeiro, o clássico: temperatura e outros parâmetros de geração. Quanto mais baixa a temperatura, menos criatividade e mais “obediência” do modelo. Para um agente de seleção de presentes, provavelmente você vai querer não zero, mas também não alto nível de liberdade, senão o modelo vai inventar toda manhã uma nova forma de chamar a mesma ferramenta.
Segundo, instruções de sistema claras. Se você descreve o comportamento de forma vaga, tipo “você pode chamar ferramentas diferentes e fazer o que quiser”, não se surpreenda se o agente ficar alternando entre APIs ou tentando responder “do nada”. É muito melhor descrever explicitamente quando chamar cada ferramenta, quais parâmetros são válidos, como interpretar erros e em que casos encerrar a tarefa.
Por exemplo, o prompt de sistema do agente do GiftGenius pode incluir o trecho:
Se você não tiver o perfil completo do destinatário (idade, gênero, ocasião, orçamento aproximado),
primeiro faça perguntas de esclarecimento pelo canal voltado ao usuário e aguarde as respostas.
Só depois chame a ferramenta search_gifts com o perfil preenchido.
Não invente produtos: sempre baseie-se nos resultados das ferramentas.
Instruções desse tipo reduzem a variabilidade das decisões e deixam o comportamento mais determinista.
Terceiro, o design das próprias ferramentas. Se você tem três ferramentas que “fazem mais ou menos a mesma coisa” ao buscar presentes, o modelo inevitavelmente vai escolher ora uma, ora outra. É melhor projetar ferramentas com zonas de responsabilidade claras e não sobrepostas — e declarar isso nas descrições.
Por fim, você pode usar guardrails — regras e esquemas que verificam as ações do agente e os resultados do modelo. Na Agents SDK há suporte embutido a checagens e restrições, inclusive sobre a estrutura dos dados de saída. Se o modelo tentar gerar algo fora do esquema, você pode corrigi-lo levemente ou até repetir a etapa.
Mini‑exemplo: fixando o formato do resultado
Suponha que você precise que o agente sempre retorne um JSON com o campo gifts, contendo objetos com id, title e score. Você pode:
- descrever esse esquema no nível do agente;
- indicar que a saída final deve obedecer a ele;
- em caso de violação — repetir a etapa ou retornar um erro seguro.
Pseudocódigo:
const giftResultSchema = z.object({
gifts: z.array(z.object({
id: z.string(),
title: z.string(),
score: z.number().min(0).max(1),
}))
});
// Na configuração do agente
const agent = new Agent({
/* ... */
outputSchema: giftResultSchema,
});
Quando o modelo tentar retornar algo estranho, o runner informará um erro de validação, e você poderá ou pedir ao modelo novamente, ou registrar o incidente.
7. Idempotência: por que o agente pode chamar sua API duas vezes
Se determinismo é “mesmo plano para as mesmas entradas”, idempotência é sobre segurança de repetições. No contexto de agentes, ela é criticamente importante por dois motivos.
Primeiro, surge mais uma camada de retries: não apenas clientes HTTP e balanceadores de carga, mas o próprio agente pode decidir repetir uma chamada de ferramenta se recebeu um erro ou um resultado incompleto. Segundo, em cenários reais de produção entram webhooks, filas, canais de streaming — e você pode acabar processando a mesma etapa lógica mais de uma vez.
Você já discutiu idempotência no nível de MCP‑tools: não fazer cobranças duplas, não criar o mesmo pedido duas vezes, usar idempotency keys nas requisições. Agora é a mesma coisa, mas multiplicada pela natureza multi‑etapas do agente.
Imagine que no GiftGenius surgiu a ferramenta create_checkout_session, que cria um draft de checkout em ACP/Stripe a partir da lista de presentes escolhidos. Se o agente decidir repetir essa chamada por causa de um erro de rede, você definitivamente não quer dois pedidos separados e duas cobranças.
Portanto, é preciso:
- definir uma idempotency key externa para cada ação lógica (por exemplo, runId + stepIndex ou um checkoutDraftId gerado explicitamente);
- passá-la para seu backend/endpoint do ACP;
- no backend, verificar se essa chave já foi processada e, em caso afirmativo, retornar o resultado salvo em vez de executar novamente.
Pseudoexemplo em TypeScript:
async function createCheckoutDraft(runId: string, payload: DraftPayload) {
const key = `gift-checkout-${runId}`;
const existing = await findDraftByKey(key);
if (existing) return existing;
const draft = await stripe.checkout.sessions.create({
/* ... */,
idempotencyKey: key, // ou sua própria camada por cima
});
await saveDraftWithKey(key, draft);
return draft;
}
Agora, mesmo que o agente por algum motivo chame essa ferramenta duas vezes com o mesmo runId, seu código permanecerá idempotente: a mesma etapa lógica → o mesmo resultado efetivo.
“Primeiro verificar, depois agir”
Outro padrão comum de idempotência é verificar o estado antes de agir. Por exemplo, antes de criar um pedido, checar se já não existe um pedido com o mesmo clientReferenceId ou com o mesmo conjunto de parâmetros. Isso é especialmente útil em workflows longos, onde o agente pode “esquecer” que já fez algo em uma etapa anterior.
Safe‑mode/Fake‑mode
Em desenvolvimento, é útil ter um “modo seguro” para ferramentas perigosas: em vez de agir de verdade, elas apenas registram o que teria sido feito e retornam um pseudorresultado. Para agentes, isso é uma forma prática de rodar o run‑ciclo em ambiente de produção sem arriscar dinheiro ou dados.
8. Mini prática: descrevendo o agente do GiftGenius em linguagem humana
Já falamos sobre o run‑ciclo, determinismo e idempotência das ferramentas. Vamos nos afastar do código por um minuto e verificar como tudo isso se encaixa em um cenário real.
Agora vale fazer um pequeno exercício no papel (ou mentalmente), sem código.
Imagine que você descreve um agente simples:
-
: você é um assistente de seleção de presentes; sempre esclarece detalhes importantes, não inventa produtos e usa apenas resultados das ferramentas.system -
: quero um presente para um colega até US$ 50.user
Descreva em palavras quais etapas esse agente deve executar.
Um cenário típico pode ser assim.
- Primeiro, o agente verifica se há informação suficiente. Se não, faz perguntas de esclarecimento: com o que o colega trabalha (designer, desenvolvedor, gerente), se há algum tabu (álcool, presentes de brincadeira), se há restrições de entrega. As respostas vão para o session state ou para os parâmetros da chamada de ferramenta.
- Em seguida, o agente chama a ferramenta search_gifts com o perfil preenchido: “colega desenvolvedor, orçamento 50, categoria — gadgets e escritório”. A ferramenta retorna uma lista de candidatos com preços, categorias e IDs de produto.
- Depois o agente pode chamar uma ferramenta adicional filter_gifts_by_constraints se descobriu que parte dos produtos não pode ser entregue na região desejada, ou filtrar no próprio prompt. Em seguida, ordena as opções por relevância e preço, possivelmente adicionando comentários (“adequado se o colega gosta de café”, “boa opção para trabalho remoto”).
- Por fim, o agente prepara a resposta estruturada final para o ChatGPT App: uma lista de 5–7 presentes com breves descrições, dicas de uso e links para Checkout (ou para a próxima etapa — criação de um draft de checkout).
Onde aqui são necessários tool‑calls? Obviamente, na busca e filtragem de produtos, na verificação de disponibilidade e na criação do draft de checkout. Quais passos devem ser idempotentes? Em primeiro lugar, todas as operações relacionadas a pedidos e dinheiro — criação do draft de checkout e, possivelmente, o registro de histórico no BD.
9. Erros comuns nos primeiros passos com agentes
Erro nº 1: tratar o agente como “um segundo ChatGPT sem limites”.
Às vezes dá vontade de simplesmente dar ao modelo mais um prompt e chamar isso de “agente”. O resultado é algo que gera muito texto, chama ferramentas de forma caótica e é difícil de controlar. Para evitar isso, é importante descrever com clareza o papel do agente em system, limitar a lista de ferramentas e pensar nele como um orquestrador com missão específica, e não como “um segundo universo de geração de texto”.
Erro nº 2: falta de idempotência nas ferramentas.
Desenvolvedores frequentemente levam seus antigos handlers HTTP para o agente “como estão”, sem considerar que agora o runner pode repetir chamadas automaticamente. Em pagamentos e pedidos, isso pode ter consequências bem desagradáveis. A abordagem correta é projetar as ferramentas desde o início para que uma chamada repetida com a mesma chave lógica não provoque uma ação repetida.
Erro nº 3: configurações excessivamente criativas do modelo.
Temperatura alta é ótima para inventar brindes e poemas, mas para um agente que precisa orquestrar de forma confiável processos multi‑etapas, é caminho para comportamento imprevisível: o modelo vai escolher ferramentas diferentes a cada vez, gerar planos distintos e às vezes esquecer que existem tools. Trate agentes como entidades “de serviço” e mantenha-os em modo mais restrito.
Erro nº 4: uma ferramenta “para todas as ocasiões”.
Às vezes surge a ideia de criar um tool universal como execute_any_sql ou do_anything_with_orders e dar isso ao agente. Com a criatividade de uma LLM, isso é quase uma ameaça garantida à segurança. É muito melhor ter várias ferramentas especializadas com contratos e permissões claros do que uma “divina” com poderes totais sobre tudo.
Erro nº 5: falta de critérios explícitos para encerrar o run.
Se você não explicar ao agente quando deve parar, ele pode cair em loops infinitos ou semi‑infinitos: checar resultados mais uma vez, perguntar ao usuário mais uma vez, tentar chamar uma ferramenta novamente para o mesmo erro. Isso frequentemente aparece sob carga, quando alguma dependência está instável. O caminho certo é estabelecer limites para número de passos, tempo de run e quantidade de repetições em caso de erro idêntico, além de descrever em system que o agente deve “desistir honestamente” quando esgotar opções razoáveis.
Erro nº 6: guardar tudo e mais um pouco no estado do agente.
Como a Agents SDK facilita o trabalho com session state, surge a tentação de colocar lá de tudo: documentos grandes, logs crus, dados sensíveis. Isso incha o contexto, aumenta o custo e cria riscos de segurança. O estado do agente deve conter apenas o que realmente é necessário para continuar; todo o restante — no BD, nos logs e em outras camadas, com atenção à privacidade.
Erro nº 7: tentar usar um agente onde um MCP‑tool simples basta.
Às vezes os desenvolvedores começam com um agente mesmo que a tarefa seja apenas chamar uma função e retornar o resultado. Isso adiciona complexidade onde ela não é necessária: aparecem run‑ciclo, estado, logs adicionais e pontos extras de falha. Se o cenário cabe em um tool‑call único sem workflow complexo, mantenha assim — e traga um agente apenas quando surgir a real natureza multi‑etapas.
GO TO FULL VERSION