/agent e /coder. Esta página explica o que roda sem você mexer em nada e quais interruptores estão disponíveis quando o comportamento default não serve para o seu workflow.
Todas as otimizações desta página funcionam em todos os provedores suportados (Anthropic direto, Bedrock, OpenAI, xAI, ZAI, MiniMax, Moonshot (Kimi), Google AI, Ollama, Copilot, GitHub Models, OpenRouter, OpenAI Responses, StackSpot). Providers com prompt caching explícito (Anthropic, Bedrock Anthropic) ou auto-caching (OpenAI, xAI) aproveitam ganhos adicionais.
O problema real
Um loop ReAct mal calibrado consegue transformar uma pergunta trivial num consumo absurdo de tokens. Sem as otimizações abaixo, uma query como “resultado do jogo do Flamengo” pode facilmente queimar 20k+ tokens porque:- O system prompt inteiro é re-enviado em cada turno (sem cache).
- As definições de tools (15+ schemas JSON) também vão re-enviadas por turno.
- Nada quebra o loop quando o modelo repete a mesma tool_call sem convergir.
- Bodies grandes do
@webfetchentram crus no contexto.
1. Prompt Caching estruturado
O cache da Anthropic (e o auto-cache de prefixo do OpenAI/xAI) funciona por prefixo: um breakpoint só dá hit quando todos os bytes antes dele são idênticos a uma requisição anterior. A regra de ouro é simples — blocos estáveis primeiro, blocos voláteis no fim. O system prompt é montado exatamente assim: Prefixo estável (cacheado,cache_control: ephemeral):
Sufixo volátil (sem cache marker — muda a cada turno):
Cada bloco estável carrega
cache_control: ephemeral para os providers Anthropic (respeitando o teto de 4 breakpoints, com coalescing automático). Para providers com auto-caching de prefixo (OpenAI, xAI), a ordem estável faz o cache casar naturalmente. O chat segue a mesma lógica de ordenação — e como a exceção da ferramenta de memória do chat carrega o caminho de pull, o chat honra o modo index exatamente como agent/coder (ver seção 7).
Cache nas tool definitions
A última definição de ferramenta enviada para a Anthropic também recebecache_control: ephemeral, o que transforma todo o array de tools num prefixo cacheável. Em uma sessão /coder com 15 ferramentas coder + 2 web tools, isso representa ~19KB que deixam de ser re-tokenizados a cada turno.
Visibilidade do cache
Cached tokens do OpenAI não exigem opt-in — prompt caching é automático em
gpt-4o e mais novos (incluindo o-series e GPT-5), disparado quando o prefixo do prompt tem ≥1.024 tokens, com hits servidos em incrementos de 128 tokens. Para streaming Chat Completions, o ChatCLI envia stream_options: {include_usage: true} para o chunk terminal de usage chegar antes do [DONE]; na Responses API, o usage vem no evento SSE response.completed sem flag adicional./cost — o hit de cache aparece como linha separada. O envelope do chat também mostra N↑ M↓ na borda direita para qualquer provider que reporte usage, incluindo todas as APIs do OpenAI.
2. Detector de estagnação (early-exit)
Quando o modelo entra em reflection loop — emitindo exatamente a mesma batch detool_calls turno após turno sem informação nova — o ChatCLI detecta e quebra o loop.
Como funciona
A cada turno, o fingerprint dastool_calls (nome + args normalizados, order-independent, SHA-256 truncado) é computado. Três turnos consecutivos com o mesmo fingerprint → o loop é encerrado com uma mensagem clara ao usuário.
Parâmetros
3. Smart Routing chat ↔ agent
Nem toda query precisa de um loop ReAct inteiro. Perguntas conversacionais ou factuais (“o que é um mutex?”, “diferença entre slice e array”) são respondidas por um único turno em chat mode. O classificador identifica queries triviais usando sinais léxicos:- Palavras-chave de pergunta (
o que,por que,how does,explain, …) - Ausência de sinais de task (
create,build,run,fix, …) - Ausência de referências ao workspace (
@file,@git, paths, extensões de código) - Tamanho curto + ponto de interrogação
Modos
Exemplo
4. WebFetch com auto-save inteligente
O@webfetch foi calibrado para nunca vomitar páginas gigantes no contexto. Veja também WebFetch & WebSearch para a documentação completa.
Escape hatch
O auto-save sempre persiste o body completo (pré-filtro) em
$CHATCLI_AGENT_TMPDIR, e o retorno contém:
read_file apontando para esse caminho com o start/end apropriado, pagando apenas pelas linhas que importam.
5. System prompts enxutos
Os prompts que acompanham cada modo foram condensados sem perda semântica — todas as regras originais permanecem, apenas redundância e exemplos repetidos foram removidos:
Como esses prompts são cacheados no bloco core, modelos que suportam cache (Anthropic/Bedrock/OpenAI) enxergam a redução só no primeiro turno da sessão. Modelos sem cache ganham a economia em todo turno.
6. Compactação proativa de resultados de tool
Resultados de ferramentas antigas (file reads, search, git-diff, etc.) são progressivamente comprimidos na história para não inflar o payload. Veja Tool Result Management para os detalhes completos. Contabilidade honesta de budget: o gatilho de compactação agora pesa o payload inteiro da requisição, não só o texto das mensagens — argumentos de tool calls nativas, payloads de imagem (via estimador de tokens) e excesso de system-parts contam para o budget. Históricos pesados em tools ou visão disparam a compactação antes de estourar o cap de payload de um proxy. Em agent/coder há também um ciclo de vida de skills no mesmo boundary: blocos de skill mid-loop envelhecem para stubs compactos apósCHATCLI_SKILL_AGE_TURNS turnos (recuperáveis via @recall, re-ativáveis após cooldown) — veja Skill Registry › Budget de injeção de skills.
Os defaults são conservadores para proteger workflows multi-turnos com cross-references (refactors grandes, review sessions). Quem quiser ser mais agressivo pode ajustar:
7. Memória pull-first (índice + recall)
Empurrar a memória inteira no system prompt a cada turno não escala: o custo cresce com o tamanho do store e é re-enviado em todo turno. A partir de agora o ChatCLI usa por padrão um modelo pull: injeta só um digest estável e deixa o agente puxar o detalhe sob demanda via a ferramenta@memory recall.
Controle pela variável CHATCLI_MEMORY_MODE:
O
index é estável (não depende dos hints do turno, sem timestamp), então entra no prefixo cacheado (seção 1) e tem tamanho limitado independente do tamanho do store. O @memory recall usa o stack completo de recuperação (HyDE + busca vetorial por cosseno + extração de keywords), então o detalhe puxado tem a mesma qualidade do antigo push.
O auto-recall proativo (CHATCLI_MEMORY_AUTORECALL, on por padrão) adiciona um bloco minúsculo de top-3 fatos guiado por hints a cada turno, mais uma linha Related (graph): apontando os vizinhos desses fatos no grafo de conhecimento — mas ele viaja na região final não-cacheada junto do contexto de relógio, nunca no digest estável, então o prefixo cacheado permanece byte-idêntico e nada da economia acima é devolvido. Veja Bootstrap e Memória para detalhes.
Impacto medido
Medição num store real com 500 fatos (MEMORY.md ~32KB, índice de fatos ~270KB):
−87,7% no bloco de memória por turno — e, ao contrário do
full (limitado pelo CHATCLI_MEMORY_RETRIEVAL_BUDGET), o índice não cresce conforme a memória cresce.
O chat também honra
index: a exceção da ferramenta de memória do chat (CHATCLI_CHAT_MEMORY, on por padrão) é seu caminho de pull, então o chat tem a mesma economia de digest + recall de agent/coder. Só com essa exceção desabilitada o chat cai em full; off suprime a memória em todos os modos. O modo é exibido em /config memory.Como medir o impacto
Rode sua sessão normalmente e olhe o/cost ao final:
Cache read> 0 e crescendo por turno → caching estruturado está casando o prefixo.- Poucos/nenhum FORMAT ERROR no log → reminders estão segurando o formato nos modelos menores.
- Turnos com
tool_calls = 0seguidos de conclusão rápida → early-exit detectou convergência. - Marker
[auto-saved: response was N bytes]em respostas de@webfetch→ o limite inline está protegendo o contexto.
Resumo das variáveis
Todas as variáveis desta página em um só lugar:Próximos passos
- Native Tool Use — como
cache_control:ephemeralé propagado para Anthropic/Bedrock. - Tool Result Management — detalhes do pipeline de compactação.
- Cost Tracking — como o
/coste o catálogo calculam o valor real de cada turno. - WebFetch & WebSearch — filtros, save_to_file e fallback entre backends.