Você está otimizando o custo da IA do jeito errado
Proteja o que pode ser reutilizado
Prompt caching funciona em cima de prefixos. Se uma parte inicial do contexto continua igual entre chamadas, ela pode ser reutilizada em vez de ser processada novamente como conteúdo novo.
Na implementação da Anthropic, a hierarquia do prefixo segue: tools → system → messages. Alterações em uma parte anterior podem afetar o reaproveitamento das seguintes. A regra é simples: estável na frente, volátil no fim.
Quanto maior a parte estável que continua idêntica entre chamadas, maior a possibilidade de reaproveitamento. Pense em instruções de sistema, definições de ferramentas e outras informações que permanecem iguais durante a tarefa.
Evite mexer nas instruções estáveis durante uma tarefa longa
Rules são instruções persistentes para o agente. Se você altera uma instrução que faz parte da porção estável enviada ao modelo, pode acabar modificando um conteúdo que vinha sendo reaproveitado. Não dá para afirmar que toda Rule do Cursor ocupa uma posição específica no prompt ou que editar uma sempre invalida todo o cache, porque essa implementação interna não é documentada dessa forma.
Ainda assim, quanto menos você modifica as instruções estáveis durante uma execução longa, mais previsível tende a ser o reaproveitamento do contexto. Na prática, prefiro ajustar Rules estruturais entre tarefas ou sessões, não enquanto um fluxo grande já está em andamento.
Sessão fria pode sair mais cara, mas sessão infinita também não é solução
No cache padrão da Anthropic, o TTL é de cinco minutos, com opção de extensão para uma hora. Em uma configuração usando o TTL padrão, interações frequentes conseguem continuar reaproveitando conteúdo já cacheado. Depois de uma pausa longa, a próxima chamada pode precisar processar novamente partes daquele contexto.
Modelos da OpenAI também utilizam mecanismos de reutilização de contexto e otimizações internas que favorecem interações contínuas, embora não exponham TTL de cache da mesma forma. Já no Cursor, o reaproveitamento depende da continuidade da sessão e da forma como o contexto é mantido e atualizado ao longo das interações.
Isso não significa que você deve manter uma conversa infinita só para proteger o cache. Sessões longas acumulam histórico, e chega um momento em que boa parte dele deixa de ser relevante para a tarefa atual. Esse acúmulo não impacta apenas o custo. Ele também pode afetar o desempenho do agente.
Quando o contexto contém muita informação irrelevante, o modelo precisa separar o que importa do que pode ser ignorado. Isso significa mais informação para processar, mais ambiguidade e mais chances de o agente considerar detalhes que não ajudam a resolver o problema. Na prática, ele pode acabar levando em conta arquivos antigos, interpretações já descartadas ou instruções que não se aplicam mais à tarefa atual.
Existe um trade-off:
- Sessão longa: maior possibilidade de reaproveitamento, mas mais contexto acumulado e potencialmente mais ruído.
- Sessão nova: contexto menor e mais limpo, mas possivelmente um novo cold start para informações que antes estavam cacheadas.
Para tarefas completamente independentes, prefiro sessões separadas. Não porque uma sessão nova seja universalmente mais barata, mas porque carregar contexto irrelevante indefinidamente também não faz sentido, tanto do ponto de vista de custo quanto da qualidade das decisões do agente.
O objetivo é: não faça o modelo processar informação que não ajuda a resolver a tarefa atual.
Controle o que entra no contexto
O agente precisa procurar código, abrir arquivos, ler resultados de testes e investigar dependências. O problema não é fazer isso. O problema é deixar que grandes volumes de informação irrelevante entrem no contexto sem necessidade.
Isso acontece mais do que parece. Você cola um log inteiro quando só algumas linhas explicam a falha. Pede para o agente analisar um projeto inteiro quando a mudança está restrita a um módulo. Entrega a saída completa de uma pipeline quando o erro já aponta para um único teste. Ou inclui arquivos gerados, mocks enormes e documentação que não têm relação direta com a tarefa.
Tudo isso aumenta a quantidade de informação que o modelo precisa processar antes mesmo de começar a raciocinar sobre o problema. Por isso, uma das otimizações mais simples é reduzir o escopo antes de aumentar o contexto.
- Se uma pipeline falhou em um teste específico, comece por esse teste e pelo erro associado, não pelo log inteiro da execução.
- Se a tarefa é alterar o fluxo de criação de usuários, direcione o agente para esse domínio antes de deixá-lo explorar o repositório inteiro.
- Se uma saída gerada por uma ferramenta é enorme, permita que o agente investigue primeiro o que falhou e aprofunde apenas quando precisar.
A ideia não é esconder informação do modelo. É disponibilizá-la progressivamente. Comece com o menor contexto suficiente para investigar o problema e expanda conforme surgirem novas perguntas.
Isso também vale para o resultado das ferramentas usadas pelo próprio agente. Um comando que retorna milhares de linhas pode gerar muito contexto sem necessariamente gerar mais informação útil. Sempre que possível, vale preferir execuções mais direcionadas, como rodar apenas o teste que falhou, consultar os logs do serviço envolvido ou restringir uma busca ao domínio em que o problema acontece.
O ganho não vem simplesmente de "mandar menos tokens". Vem de evitar que o modelo precise separar sinal de ruído antes de começar a trabalhar. Em agentes, mais contexto nem sempre significa mais inteligência. Às vezes significa apenas mais coisa para ignorar.
Use a ferramenta mais seletiva para buscar informação
Coding agents têm diferentes formas de encontrar informação, e cada uma funciona melhor para um tipo de pergunta. O Cursor, por exemplo, consegue fazer buscas literais, semânticas e explorar o codebase de forma agentic. O objetivo não deveria ser escolher uma ferramenta favorita, mas evitar buscas mais amplas do que o problema exige.
Se eu quero encontrar todas as ocorrências de UserRepository no código, estou procurando algo exato. Uma busca literal provavelmente resolve rápido. Mas imagine que a pergunta seja: "Em que ponto do fluxo de checkout o valor do frete é recalculado após a aplicação de cupons?" Talvez você não saiba o nome da função, da classe ou sequer o termo usado na implementação. Nesse caso, tentar adivinhar palavras para buscar pode ser menos eficiente do que deixar o agente usar uma busca semântica para localizar o comportamento.
A diferença está no tipo de pergunta:
- Se você sabe o que está procurando, procure diretamente.
- Se você sabe o comportamento, mas não sabe onde ele está implementado, procure semanticamente.
- Se precisa entender como várias partes se conectam, deixe o agente explorar o fluxo.
O princípio é: use a busca com o menor alcance capaz de responder à pergunta atual. Isso evita dois extremos. De um lado, abrir arquivos demais para responder algo simples. Do outro, limitar tanto a busca que o agente precisa fazer várias tentativas até encontrar o que realmente importa.
A otimização não está em escolher uma ferramenta específica. Está em não transformar toda pergunta sobre o código em uma exploração completa do repositório.
Tire o discovery do modelo mais caro
Quando o agente precisa entender um projeto antes de começar uma tarefa, existe outro desperdício possível: usar o mesmo modelo caro que vai resolver o problema para fazer todo o trabalho de descoberta. Nem toda etapa exige o mesmo nível de inteligência.
A parte puramente estrutural do discovery pode ser feita de forma determinística. Um script simples pode percorrer o repositório, identificar diretórios relevantes, arquivos de configuração conhecidos, workspaces, módulos e possíveis entrypoints e devolver um mapa compacto da estrutura. A partir daí, se ainda for necessário interpretar essas informações, um modelo mais barato pode transformar esse mapa em um resumo arquitetural antes de entregar o resultado ao modelo principal.
O fluxo fica mais ou menos assim:
coleta determinística
↓
mapa estrutural
↓
modelo mais barato
↓
resumo do projeto
↓
modelo principal
↓
execução da tarefa
A ideia é separar coleta, síntese e raciocínio. Um script continua sendo uma boa ferramenta para extrair diretamente a estrutura do projeto, como módulos existentes, arquivos de configuração e organização de diretórios. Já perguntas como "qual parece ser a arquitetura deste sistema?", "quais são os principais domínios?" ou "como esses módulos se relacionam?" exigem interpretação. Para isso, pode fazer sentido usar um modelo mais barato para produzir um resumo antes de envolver o modelo principal.
Nesse caso, uma Skill poderia orquestrar o processo:
---
name: project-discovery
description: "Mapeia e resume a arquitetura do projeto antes de tarefas que exigem contexto amplo."
allowed-tools: ["Bash"]
---
1. Execute o script de discovery para gerar o mapa estrutural do repositório.
2. Use o mapa como base para produzir um resumo compacto da arquitetura.
3. Retorne apenas o resumo relevante para a tarefa atual.
4. Aprofunde a leitura apenas nos módulos necessários.
O script não tem custo zero de contexto e o modelo barato também tem custo. O ponto é que você não está usando sua capacidade mais cara para executar todas as etapas do processo. Faça com código o que é determinístico, use modelos baratos para síntese e reserve os modelos mais fortes para decisões em que errar custa caro.
Essa é a mesma lógica de roteamento por etapa aplicada ao contexto. O modelo principal recebe um mapa já interpretado e decide onde aprofundar, em vez de gastar parte da sua execução descobrindo do zero como o projeto está organizado. Isso vai além de economia de tokens. É arquitetura de agente.
Sempre que um modelo caro estiver gastando raciocínio para fazer uma tarefa que código ou um modelo mais barato conseguiriam executar com confiabilidade suficiente, vale perguntar se aquela etapa realmente deveria continuar pertencendo a ele.
Carregue conhecimento sob demanda com Rules e Skills
Existe uma diferença importante entre algo que o agente precisa saber sempre e algo que ele só precisa saber em situações específicas. Uma Rule contém algo que deve influenciar o comportamento do agente de forma recorrente. Uma Skill pode conter um procedimento inteiro que só interessa quando determinada situação acontece.
Agent Skills seguem uma lógica de carregamento progressivo. Inicialmente, informações básicas como nome e descrição permitem que o agente descubra que aquela capacidade existe. Quando a Skill é relevante, suas instruções podem ser carregadas, junto de scripts e referências adicionais conforme a necessidade.
Isso cria uma regra de arquitetura útil:
- Rule para conhecimento curto, estável e recorrente.
- Skill para conhecimento longo, procedural e situacional.
Imagine um conjunto de instruções como convenções de nomenclatura, padrões de commit ou regras de validação específicas do projeto. Algumas dessas orientações, como convenções de nomenclatura, fazem sentido como Rules globais, já que influenciam praticamente qualquer alteração no código. Outras, como padrões de commit, podem ser mais situacionais e não precisam estar presentes em todas as tarefas.
Você pode colocar tudo isso em uma Rule global, fazendo com que qualquer tarefa, até mesmo corrigir um typo, carregue esse conteúdo. Ou pode organizar essas orientações em uma Skill, que só é utilizada quando realmente faz diferença para a tarefa em questão.
Uma Skill boa não deixa de pesar. Ela pesa pouco enquanto está inativa e só ocupa mais contexto quando realmente tem valor para a tarefa. Isso economiza contexto, mas também reduz ruído. Contexto irrelevante não tem apenas custo financeiro. Ele também compete
Comments
No comments yet. Start the discussion.