Artigo · Blog
O agente não errou. Ele respondeu exatamente o que você perguntou.
A maioria dos problemas com agentes de IA em produção não é alucinação nem limitação do modelo. É que o engenheiro não percebe que está fazendo a pergunta errada. O modelo entrega o que recebeu. O problema está antes da chamada.
O agente não errou. Ele respondeu exatamente o que você perguntou.
Num projeto que mantive por alguns meses, tinha um agente que classificava intenções de usuário. A tarefa parecia simples: receber a mensagem, identificar o que o usuário queria, rotear para o fluxo certo.
Nos testes, funcionava bem. Em produção, começou a classificar errado em casos que pareciam óbvios. A primeira hipótese foi alucinação. A segunda foi temperatura alta. Ajustamos parâmetros, trocamos o prompt, adicionamos exemplos. O erro continuava.
Levou alguns dias pra entender o que estava acontecendo.
O agente não estava errando. Ele estava respondendo com precisão o que a gente tinha configurado pra ele enxergar.
O problema que parece ser do modelo quase nunca é
Quando um LLM entrega um resultado ruim em produção, a reação natural é ajustar o modelo: trocar o sistema prompt, aumentar os exemplos no few-shot, mudar o modelo base, reduzir a temperatura.
Isso resolve às vezes. Mas resolve o sintoma.
O problema real, na maioria dos casos que já vi, está em três lugares: o que entra no contexto, em que ordem entra, e o que foi excluído porque parecia irrelevante.
No caso do classificador, o agente recebia a mensagem do usuário mas não recebia o histórico da sessão. Pra quem estava de fora, parecia razoável: a mensagem atual continha a intenção. Não precisava do histórico.
Só que o usuário digitava coisas como "quero cancelar". Cancelar o quê? Sem o contexto anterior, qualquer resposta era uma aposta. O agente apostava. Às vezes acertava. Às vezes não.
A solução não foi trocar o modelo. Foi mudar o que chegava até ele.
Contexto não é só o que você passa. É o que você decide não passar.
Essa é a parte que a maioria ignora.
Quando você monta o contexto de um agente, você toma decisões ativas sobre o que incluir. Histórico de mensagens, estado atual da sessão, dados do usuário, metadados do produto. E pra cada coisa que você inclui, tem outra que você deixa de fora, geralmente por parecer redundante, sensível ou cara demais em tokens.
O problema é que o modelo não tem opinião sobre o que está faltando. Ele responde com o que tem. Se o que tem é incompleto, a resposta vai ser incompleta. Mas vai parecer confiante.
Essa é a armadilha. O modelo não diz "não tenho informação suficiente pra responder isso". Ele responde de qualquer forma, com a fluência de sempre, e você só vai descobrir que estava errado quando o usuário reclamar ou quando olhar os logs.
A ilusão do prompt perfeito
Durante muito tempo, eu tratava engenharia de contexto como engenharia de prompt. Eram a mesma coisa na minha cabeça.
Não são.
Prompt é o que você diz pro modelo. Contexto é o ambiente onde ele opera. Você pode ter um prompt impecável e um contexto quebrado. O resultado vai ser ruim de uma forma que o prompt nunca vai resolver.
Exemplo prático: num agente de suporte que trabalhei, tínhamos um sistema prompt bem escrito, com tom de voz definido, instruções claras de escalação e exemplos de boas respostas. O problema era que o agente não recebia o plano atual do usuário. Então quando alguém perguntava sobre um limite ou uma funcionalidade, o agente inventava uma resposta genérica baseada no que o modelo conhecia do produto, não no estado real da conta daquele usuário.
Trocar o prompt não ia resolver isso. O dado simplesmente não estava lá.
O que eu aprendi a fazer diferente
A primeira mudança foi tratar contexto como schema, não como string.
Antes, eu montava o contexto como texto: uma série de mensagens concatenadas, talvez com alguns dados inseridos no meio. Parecia funcionar. Mas era frágil porque qualquer mudança na estrutura podia quebrar a forma como o modelo interpretava aquilo.
Agora eu penso em contexto como um contrato. Que campos existem, o que cada um representa, qual a ordem de prioridade quando o contexto começa a ficar grande demais pra caber na janela. Isso força uma decisão explícita sobre o que é essencial e o que é descartável.
A segunda mudança foi começar a logar o contexto completo que chegava ao modelo em cada chamada de produção. Não só o prompt. Não só a resposta. O pacote inteiro.
Isso parece óbvio, mas a maioria dos sistemas que eu vi em produção não faz isso. E sem isso, quando algo dá errado, você fica debugando no escuro. Você vê o output ruim mas não sabe exatamente o que entrou.
A terceira mudança foi parar de confiar em testes manuais de prompt pra validar comportamento em produção. O modelo pode responder certo em dez variações manuais e errar na décima primeira, que só aparece com dados reais de usuário. Avaliar output de LLM em escala precisa de automação, e automação precisa de estrutura.
O erro mais caro que já cometi nessa área
Construí um pipeline onde o agente recebia contexto de uma ferramenta externa via function calling. A ferramenta retornava um JSON com dados do usuário. O agente usava esses dados pra personalizar a resposta.
O problema: em alguns casos, a ferramenta retornava um JSON parcialmente preenchido quando o dado não estava disponível. Campos nulos, arrays vazios, strings em branco.
O agente interpretava isso como se o dado existisse mas fosse vazio, não como ausência de informação. E aí ele inventava. Não por alucinação aleatória, mas porque o contrato que eu estabeleci implicitamente dizia "esses campos sempre existem". Quando não existiam de verdade, o modelo completava com o que parecia razoável.
A correção foi simples: passar o estado explicitamente. Se o dado não está disponível, dizer isso no contexto. "O campo X não está disponível para este usuário" é fundamentalmente diferente de passar o campo X com valor nulo.
O modelo entende ausência quando você a articula. Ele não consegue inferir ausência a partir de silêncio.
O que ninguém fala sobre escala
Em teste, você controla tudo. Você monta o cenário, escolhe os dados, sabe exatamente o que vai entrar.
Em produção, o contexto é gerado dinamicamente. Usuários distintos, estados distintos, combinações que você nunca testou. A variabilidade do contexto real é ordens de magnitude maior do que qualquer conjunto de testes manuais.
E aqui está o ponto que muda tudo: a qualidade do seu agente em produção é limitada pela qualidade do seu pipeline de contexto, não pelo modelo que você escolheu.
Você pode usar o modelo mais caro do mercado. Se o contexto que chega até ele for inconsistente, incompleto ou mal estruturado, o resultado vai ser inconsistente, incompleto ou mal estruturado.
Trocar de GPT-4 pra Claude não resolve contexto ruim. Resolver contexto ruim resolve contexto ruim.
O agente que quebra em produção quase nunca está errado. Ele está respondendo com precisão o que recebeu. O problema está no que você decidiu passar pra ele, e no que você achou que não precisava passar.
Antes de ajustar qualquer prompt, vale a pena olhar o contexto completo que chegou na última chamada que deu errado. Na maioria das vezes, a resposta está lá.