Saltar para o conteúdo

Contexto de ferramentas e cache de prompts

Há duas coisas verdadeiras em cada pedido que o harness integrado faz: as definições das ferramentas são o maior custo fixo do pedido e quase nenhuma delas chegará a ser usada. Esta página explica o que o Control Center faz quanto a isto e porque é que a resposta não é simplesmente «enviar menos ferramentas».

O Control Center regista cerca de 126 ferramentas. Enviadas na íntegra, as suas definições custam aproximadamente 23 000 tokens em cada pedido — um custo que nenhuma compactação consegue tocar, porque as definições das ferramentas viajam numa parte do pedido separada da conversa.

A fatura dos tokens é a queixa óbvia e, com a cache de prompts, é também a menor. O custo real é a precisão de seleção. As avaliações publicadas sobre chamadas de ferramentas concordam que os modelos escolhem a ferramenta certa de forma fiável até cerca de 30–50 ferramentas em contexto e pioram progressivamente a partir daí. A causa apontada não é a contagem de tokens, mas a sobreposição semântica: quando um catálogo contém várias ferramentas cujas descrições soam iguais, o modelo está a escolher entre parecidas em vez de se lembrar de uma capacidade.

Com 126 ferramentas, um agente está bem para lá dessa faixa em todos os turnos — incluindo os muitos turnos em que só precisava de ler um ficheiro.

Uma execução vê, por isso, duas coisas:

  • um conjunto residente — cerca de duas dúzias de ferramentas, enviadas com esquemas completos em cada pedido;
  • um índice de nomes de todo o resto, agrupado sob títulos como «Tickets and projects» ou «Memory and knowledge», que custa algumas centenas de tokens para o catálogo inteiro.

Medido no catálogo atual, isto faz o bloco de ferramentas passar de ~23,1k tokens para ~5,0k, cerca de 78 % menos, e coloca o conjunto sempre visível dentro da faixa em que a seleção é fiável.

O conjunto residente é o das ferramentas que uma execução usa na maioria das execuções: o vocabulário de ficheiros e shell (read, write, edit, search, bash, …), as ferramentas de descoberta, a lista de tarefas, a pesquisa na memória e o verbo que o modo atual tem de chamar para entregar o seu resultado. O próprio verbo de saída de um modo é sempre residente — uma execução nunca deve ter de procurar a chamada que produz o seu entregável.

É esta a parte que torna o desenho seguro e não apenas barato. Uma ferramenta diferida pode ser chamada desde o primeiro turno. Só o seu esquema fica retido.

O agente vê o nome no seu prompt. Se chamar esse nome diretamente, o harness carrega o esquema e executa a ferramenta no mesmo passo — sem erro, sem ida e volta. O modelo não precisa de saber que a ferramenta alguma vez esteve «descarregada».

Quando o agente conhece a tarefa mas não o nome, o search_tools recebe uma descrição em linguagem natural («atribuir um ticket a alguém»), ordena toda a superfície da execução e devolve as correspondências já com os respetivos esquemas carregados, para que o turno imediatamente seguinte possa chamar uma delas. Se uma pesquisa não encontrar nada, di-lo claramente e sugere outra formulação ou uma pesquisa mais ampla — deliberadamente, porque um agente que lê uma pesquisa vazia como «esta capacidade não existe» vai inventar um substituto em vez de voltar a procurar.

O search_tools existe apenas no harness integrado. Os clientes MCP externos têm, em vez dele, o search_tool_bm25, que ordena o mesmo índice mas apenas descreve as correspondências — esses clientes já receberam todos os esquemas a partir do tools/list, pelo que não há nada a carregar.

O diferimento é aplicado depois do filtro de ferramentas do modo, nunca em vez dele. Esconde um esquema; não consegue revelar uma ferramenta que o modo negou. Uma ferramenta ativada continua a passar pelo pedido de aprovação e pelas barreiras de ação exatamente como uma residente, e uma ferramenta não pode carregar um nome que não estivesse já na superfície da execução.

A superfície MCP que os clientes externos veem não é afetada. O tools/list continua a devolver o catálogo completo. Uma tentativa anterior de o reduzir quebrou os agentes por completo: os clientes MCP validam os nomes das ferramentas contra a sua própria lista em cache e recusam tudo o que não esteja listado sem nunca perguntar ao servidor, pelo que uma ferramenta «escondida mas chamável» era simplesmente inalcançável. O diferimento vive no harness, onde carregar uma ferramenta a meio de uma execução é algo que o harness consegue mesmo fazer.

--tool-deferral=off (ou CC_SERVER_TOOL_DEFERRAL=off) volta a tornar residentes todas as ferramentas admitidas, produzindo exatamente os pedidos que o servidor fazia antes de o diferimento existir. Consulta a referência da CLI do cc_server.

As cargas de trabalho dos agentes são desequilibradas: enviam prompts enormes e recebem respostas pequenas, turno após turno, sempre com o mesmo prefixo. Os fornecedores colocam esse prefixo em cache, e uma leitura de cache custa cerca de um décimo de uma nova. A taxa de acerto de cache é, por isso, uma propriedade de primeira ordem do harness e não uma otimização — e na Anthropic também melhora o débito, porque os tokens em cache não contam para o limite de entrada por minuto.

A cache funciona por correspondência exata de prefixo, o que dá origem a uma regra soberana.

Qualquer byte que mude invalida a cache a partir desse ponto. Por isso o harness só alguma vez acrescenta: mensagens novas no fim e esquemas de ferramentas recém-ativados depois do bloco de ferramentas em cache, em vez de fundidos nele. É essa ordem que torna a ativação barata — o prefixo em cache mantém-se idêntico e a execução paga apenas pelos esquemas que acabou de carregar.

O ciclo também corta a saída de ferramentas obsoleta de turnos mais antigos para recuperar contexto. Espera até haver o suficiente para recuperar que valha a pena a reescrita, pelo que um corte é uma reescrita profunda e rara em vez de uma falha de cache contínua.

Um fornecedor permite um número limitado de marcadores de cache, e o Control Center gasta-os deliberadamente:

Marcador Abrange Duração
Última ferramenta residente O bloco de ferramentas 1 hora
Último bloco de sistema Ferramentas + prompt de sistema 1 hora
Cauda do turno anterior Histórico até ao último pedido 5 min
Cauda do turno atual O histórico completo 5 min

Os dois últimos são um par rotativo, e a razão do par é subtil: uma consulta à cache procura para trás um número limitado de blocos algo que um pedido anterior guardou. Um único turno que execute muitas ferramentas em paralelo pode emitir mais blocos do que essa janela, e nesse momento um marcador de cauda falha silenciosamente e o pedido paga o preço completo sem que nada na resposta o diga. Marcar o ponto exato onde o pedido anterior parou torna o acerto estrutural em vez de uma corrida.

O prefixo de ferramentas e sistema recebe a duração longa porque é constante ao longo de toda a execução, é partilhado por todas as execuções e subagentes com a mesma forma e porque o relógio começa quando um pedido inicia — um turno que transmite durante vários minutos já gastou a maior parte de uma janela curta antes de o pedido seguinte se formar.

Subagentes do mesmo tipo produzem prefixos de prompt idênticos byte a byte, pelo que devem ler uma única entrada de cache em vez de cada um escrever a sua. Mas uma entrada só se torna legível quando o pedido que a escreveu começa a responder, pelo que um fan-out lançado de uma só vez tem todos os filhos a pagar o preço extra por um prefixo que todos partilham.

O harness deixa arrancar o primeiro filho de uma dada forma e depois liberta os seus irmãos assim que este começa a transmitir. A espera é limitada: um primeiro filho lento custa um acerto de cache, nunca o fan-out em si. Pela mesma razão, todos os subagentes recebem o mesmo conjunto residente de ferramentas independentemente do seu perfil — variá-lo por perfil fragmentaria o prefixo partilhado sem qualquer ganho, já que o perfil já decidiu o que o filho pode chamar.

Ambas as metades são observáveis em vez de presumidas:

  • O explorador de contexto de uma conversa indica as ferramentas residentes, o índice diferido e quanto cada esquema retido custaria, construído a partir do mesmo caminho de código que uma execução real usa.
  • Cada execução regista que ferramentas diferidas carregou e o que o desencadeou, pelo que uma pesquisa que não encontra nada é visível como uma falha de recuperação, em vez de desaparecer num agente que faz silenciosamente algo adjacente.
  • A Observabilidade apresenta a Taxa de cache como as leituras de cache sobre todos os tokens de prompt processados, incluindo as escritas de cache — uma execução que não para de reconstruir o seu prefixo obtém uma pontuação baixa, em vez de ser pontuada como uma que nunca precisou de cache.