Voltar para todos os artigos
Por Dentro do Harness: Engenharia Reversa da Camada de Orquestração das Ferramentas de IA

Por Dentro do Harness: Engenharia Reversa da Camada de Orquestração das Ferramentas de IA

Abrimos a caixa preta do Claude Code, Cursor e Cline. Uma análise profunda sobre prompts de sistema, máquinas de estado de compactação de contexto, prompt caching e loops de roteamento de ferramentas.

Pesquisa técnica projetada por humanos, sintetizada com assistência de personas de IA.
17 min de leitura

TL;DR / Sumário Executivo

Abrimos a caixa preta do Claude Code, Cursor e Cline. Uma análise profunda sobre prompts de sistema, máquinas de estado de compactação de contexto, prompt caching e loops de roteamento de ferramentas.

💡 TL;DR (Too Long; Didn't Read)

Principais pontos em 90 segundos:

  1. A Ilusão do Scaffolding: Os desenvolvedores interagem com as interfaces de codificação de IA como se estivessem conversando diretamente com os modelos puros, mas cada entrada é interceptada, aumentada e executada por um middleware de estado complexo: o harness.
  2. Encanamento do Prompt de Sistema: A camada de pré-prompt é um template massivo de milhares de tokens que mapeia estados do sistema, capacidades do ambiente e instruções rígidas de parser (como schemas de saída XML e JSON) para guiar o LLM.
  3. Prompt Cache TTL e Custos: O caching de prompt da Anthropic opera com um TTL de 5 minutos e um comprimento mínimo de prefixo de 1024 tokens. Quando ocorre um hit, reduz os custos dos tokens de entrada em 90%, tornando a preservação do cache no nível do harness o principal driver de desempenho.
  4. A Cascata de Invalidação: Qualquer alteração no contexto volátil (como saídas de comandos de terminal, listagens de diretórios ou diagnósticos de edição) invalida o prefixo do cache KV, acionando uma reconstrução completa do cache que infla a latência e o consumo de tokens.
  5. Máquinas de Estado de Compactação: Os runtimes de desenvolvimento de IA podam ativamente o contexto usando janelas deslizantes, orçamentos de tokens e resumos diferenciais de conteúdo de arquivos para evitar estouro da janela de contexto e controlar os custos da API.
  6. Loops de Roteamento e Parse: O harness extrai ações usando regex ou parsers AST, executando-as localmente e alimentando a saída stdout, stderr ou erros de compilação do sistema de volta ao modelo em um sistema fechado de autocorreção.

1. A Caixa Preta dos Runtimes Agênticos

Quando você executa um comando no Claude Code, edita uma linha no Cursor ou dispara um fluxo de trabalho autônomo no Cline, a saída do terminal apresenta uma ilusão de comunicação direta e perfeita com uma inteligência artificial. Você digita um prompt, uma animação de carregamento aparece, e a ferramenta realiza edições de arquivos, executa testes e faz commits de código. Na imaginação popular, os pesos do modelo estão lendo diretamente o terminal e digitando de volta.

Como engenheiros de sistemas, sabemos que as abstrações sempre ocultam encanamentos complexos. Entre suas entradas de teclado e os pesos do modelo puro reside uma camada de middleware sofisticada, com estado e frequentemente não documentada: o harness.

O harness não é apenas um wrapper ou uma coleção de funções utilitárias de API. Ele é uma máquina de estados e um runtime de compilação. Ele compila o estado atual do seu diretório local, ambiente do sistema, histórico do shell e buffers de edição em um payload estruturado que o LLM pode consumir. Em seguida, ele analisa a saída não determinística do modelo, a resolve em ações concretas do sistema operacional (leituras, gravações de arquivos, execuções de shell e consultas LSP), trata falhas de execução e repete o loop até que um estado terminal seja alcançado.

Para dominar essas ferramentas, e para diagnosticar por que elas falham repentinamente ou consomem recursos excessivos, precisamos fazer engenharia reversa nessa camada de orquestração. Devemos analisar os prompts de sistema que definem seu comportamento, as estratégias de cache KV que ditam sua economia, a lógica de compactação de contexto que os mantém dentro dos limites e os loops de parsing que executam seus comandos.


2. Desconstruindo o Prompt de Sistema

A base de qualquer harness agêntico é o prompt de sistema. Em ferramentas como Claude Code, Cline e Cursor, o prompt de sistema é um template massivo—frequentemente variando de 1.500 a 4.000 tokens—que é anexado antes da mensagem do usuário. Ele serve como a definição do sistema operacional para o modelo.

Se você inspecionar os pacotes descompilados do @anthropic-ai/claude-code ou os repositórios de código aberto de projetos como o Cline, descobrirá que o prompt de sistema é dividido em cinco blocos lógicos distintos:

A. Ambiente e Capacidades do Sistema

Esta seção define o contexto de hardware e software. O harness consulta o ambiente local e compila um bloco de status dinâmico:

  • Sistema Operacional & Arquitetura: Ex: Windows 11 (x64) ou Darwin (arm64).
  • Shell Padrão: Ex: powershell.exe ou /bin/zsh.
  • Diretório de Trabalho Atual: O caminho absoluto para a raiz do workspace.
  • Ferramentas Disponíveis: Uma lista de utilitários de CLI detectados no $PATH do sistema (ex: git, npm, cargo, docker).

B. Especificações de Schema de Ferramentas

Ao contrário das chamadas de API simples onde as ferramentas são definidas via objetos JSON Schema no payload da API, os agentes de linha de comando frequentemente definem ferramentas diretamente no texto do prompt para guiar a geração do LLM. Por exemplo, o Cline descreve ferramentas usando tags XML personalizadas. O prompt de sistema instrui o modelo:

"Você tem acesso a um conjunto de ferramentas. Você pode usá-las escrevendo tags XML em sua resposta. O sistema executará a ferramenta e retornará a saída dentro de um bloco correspondente."

Uma definição típica de schema para uma ferramenta de edição de arquivo se parece com isto:

xml
<tool_definition> <name>write_to_file</name> <description>Grava conteúdo em um arquivo no caminho especificado. Sobrescreve arquivos existentes.</description> <parameters> <parameter> <name>path</name> <type>string</type> <description>O caminho absoluto para o arquivo.</description> </parameter> <parameter> <name>content</name> <type>string</type> <description>O conteúdo completo a ser gravado.</description> </parameter> </parameters> </tool_definition>

C. Restrições de Execução e Regras de Comportamento

Esta é a camada "opinativa" do harness. Ela contém regras projetadas para evitar que o agente fique preso em loops, execute comandos destrutivos ou vaze prompts internos:

  • Salvaguardas de Segurança: Ex: "Não execute comandos interativos que exijam entrada do usuário (como vim ou apt-get sem -y). Sempre execute comandos em modo não interativo."
  • Navegação de Diretório: Ex: "Não use comandos cd. O harness mantém o diretório de trabalho atual. Todos os caminhos devem ser relativos à raiz do workspace ou absolutos."
  • Mandatos de Verificação: Ex: "Após editar um arquivo, sempre verifique se há erros de sintaxe ou problemas de lint executando a ferramenta de build ou comando de compilação apropriado."

D. Regras de Formatação do Parser

Como o harness precisa analisar a resposta de texto do modelo, o prompt de sistema define limites rígidos de formatação. Ele diz ao modelo exatamente como formatar blocos de código, tags XML ou payloads JSON. Se o modelo desviar por um único caractere, o parser falhará. O prompt deve convencer o modelo a agir como um alvo de parser estruturado, não apenas como um agente de conversação.


3. KV Cache e Internais de Prompt Caching

Em qualquer sessão agêntica complexa, o tamanho do prompt cresce rapidamente. Em um loop de engenharia típico onde você pede ao agente para depurar um teste falho, o payload inclui:

  1. O prompt de sistema básico (3.000 tokens)
  2. A estrutura da árvore de diretórios (1.500 tokens)
  3. O conteúdo de vários arquivos de código (10.000 tokens)
  4. O histórico da conversa (5.000 tokens)
  5. A saída stdout/stderr dos comandos de teste de terminal (2.000 tokens)

Isso totaliza mais de 20.000 tokens de entrada. Sem otimização, cada troca de mensagem reavaliaria todos os 20.000 tokens, resultando em latência e custo massivos.

Para resolver isso, os harnesses modernos contam com o Prompt Caching da Anthropic (ou otimização equivalente de cache KV da OpenAI). O sistema da Anthropic armazena em cache os estados de Key-Value (KV) calculados de blocos de prefixo em seus data centers. Vamos analisar as restrições exatas desse mecanismo:

  • Comprimento Mínimo do Prefixo: 1024 tokens.
  • Time-To-Live (TTL): 5 minutos.
  • Eficiência de Custo: O caching de prompt reduz o custo do token de entrada em até 90% (ex: de $3.00/M de tokens para $0.30/M de tokens para o Claude 3.5 Sonnet).

Para obter cache hits, o harness deve construir o payload do prompt de forma que as partes estáticas fiquem no início, seguidas pelas partes que mudam lentamente e, finalmente, as partes altamente voláteis (como o prompt mais recente do usuário).

No entanto, o harness frequentemente aciona a Cascata de Invalidação. Uma correspondência de cache requer uma correspondência exata de caracteres do prefixo. Se o harness inserir uma variável volátil (como o horário atual do sistema, o ID do processo do shell ativo ou os milissegundos decorridos de uma execução de teste) antes de um grande bloco estático de arquivos de código, todo o cache downstream é invalidado.

Por exemplo, se a estrutura do prompt for: [Prompt de Sistema] -> [Timestamp Atual] -> [Arquivos do Codebase] -> [Prompt do Usuário] Uma mudança no [Timestamp Atual] a cada turno invalida o cache para os [Arquivos do Codebase], forçando a API a calcular todos os estados de tokens do zero.

Um harness bem projetado deve estruturar o payload como: [Prompt de Sistema (Alvo de Cache 1)] -> [Arquivos do Codebase (Alvo de Cache 2)] -> [Estado Volátil & Timestamp] -> [Prompt do Usuário] Ao colocar os estados voláteis no final, o harness garante que o pesado prompt de sistema e os blocos de arquivos do codebase permaneçam em cache, economizando tempo e dinheiro.


4. Compactação de Contexto e Orçamento de Tokens

À medida que uma sessão de depuração continua, o histórico de conversas acumula execuções de ferramentas e conteúdos de arquivos. Se não for controlado, a janela de contexto (tipicamente 200.000 tokens para o Claude 3.5 Sonnet) acabará saturando, ou os custos de faturamento por troca de mensagens se tornarão proibitivos.

O harness deve executar uma estratégia de Compactação de Contexto para podar a memória ativa. Isso é gerenciado por uma máquina de estados de compactação dentro do harness.

Vamos examinar os três níveis de compactação executados pelos runtimes modernos:

Nível 1: Truncamento de Saída do Shell e de Ferramentas

Quando um agente de linha de comando executa um comando como npm run test ou find . -name "*.ts", a saída pode ser massiva (às vezes dezenas de milhares de linhas de logs). O modelo não precisa ver todas as 5.000 linhas de testes bem-sucedidos; ele só precisa do resumo do erro final e do stack trace. O harness usa heurísticas regex para detectar grandes buffers de saída e truncá-los:

  • Heurística: Se o stdout exceder 1.500 tokens, mantenha os primeiros 500 tokens (logs de inicialização) e os últimos 1.000 tokens (traces de erro), substituindo a seção intermediária por [... Truncado 12.450 linhas de saída do shell ... ].

Nível 2: Desduplicação e Diffing de Contexto de Arquivos

Quando um usuário pede a um agente para editar um arquivo, o modelo precisa ver o conteúdo do arquivo. No entanto, enviar o arquivo inteiro em cada troca de mensagem é um desperdício.

  • Regra de Compactação: Se um arquivo já foi lido e permanece inalterado, o harness o remove do histórico de mensagens ativas e o substitui por uma referência de metadados simples (ex: File: src/utils.ts (Cached in Environment)).
  • Representação de Diff: Se alterações foram feitas, o harness substitui o conteúdo completo do arquivo por uma representação de diff unificado mostrando apenas as linhas modificadas, reduzindo o consumo de contexto em até 80%.

Nível 3: Resumo do Histórico (Janela Deslizante)

Para sessões muito longas, o harness usa uma janela deslizante nos turnos de conversação. Em vez de manter a transcrição completa das mensagens 1 a 20, ele executa uma chamada de resumo interna:

  1. Isola as mensagens 2 a 10.
  2. Instrui um modelo mais rápido a resumir as ações tomadas nessas mensagens (ex: "O usuário pediu para corrigir um bug de conexão com o banco de dados. Executamos testes, localizamos a divergência na string de conexão em config.json e a atualizamos.").
  3. Substitui essas 9 mensagens pelo único bloco de resumo consolidado, liberando dezenas de milhares de tokens.

5. Roteamento de Ferramentas, Parsing e Loops de Feedback

Uma vez que o prompt é compilado e a API retorna uma resposta, o harness deve analisar e executar as ferramentas solicitadas. Como o LLM retorna texto, o harness deve extrair comandos estruturados de blocos não estruturados.

Se o modelo estiver usando tags XML (como o Cline), a lógica de análise usa expressões regulares (regex) ou parsers de AST XML para isolar as tags. Por exemplo:

javascript
const toolCallRegex = /<write_to_file\s+path="([^"]+)">([\s\S]*?)<\/write_to_file>/g;

Se o modelo estiver usando saída JSON, o parser isola os blocos de código com marcadores específicos:

javascript
const jsonBlockRegex = /```json\n([\s\S]*?)\n```/;

Esse processo de extração leva a três modos de falha comuns:

Modo de Falha 1: Formatação Malformada

O modelo pode escrever <write_to_file path="src/index.js"> mas falhar ao fechar a tag, ou omitir o atributo de caminho. Um parser de harness ingênuo falhará ou quebrará. Um harness resiliente detecta a correspondência parcial, captura a exceção de análise e inicia um loop de feedback automático.

  • Loop de Feedback: Em vez de pedir ajuda ao usuário, o harness envia imediatamente uma mensagem de volta ao modelo: "ERRO: Sua última resposta continha uma tag XML malformada <write_to_file> sem uma tag de fechamento. Por favor, repita seu comando com a formatação XML correta."

Modo de Falha 2: Escape de Comandos Shell

Ao executar comandos via um wrapper child_process.exec do Node, o escape de caracteres especiais é um pesadelo operacional e de segurança. Se o modelo retornar: echo "hello && rm -rf /" Um roteador de ferramentas mal escrito executará o comando sequencialmente, executando o payload destrutivo do shell. Os harnesses modernos evitam a injeção de shell ao:

  1. Executar comandos dentro de uma instância de terminal isolada (como node-pty).
  2. Usar camadas de sanitização de argumentos que bloqueiam caracteres de encadeamento (&&, ;, |) a menos que explicitamente autorizado pelas diretivas de segurança do prompt de sistema.

Modo de Falha 3: Conflitos de Gravação e Offsets Obsoletos

Em edições de arquivos em várias etapas, o modelo lê um arquivo, o processa e gera um patch ou uma reescrita completa. Se o arquivo for modificado no disco pelo usuário ou por outro processo enquanto o modelo está raciocinando, os offsets de linha serão divergentes. O harness deve realizar uma verificação de validação antes de gravar:

  • Ele compara o checksum do arquivo antes da geração do modelo com o checksum do arquivo no disco antes da execução.
  • Se uma divergência for detectada, ele aborta a gravação e envia um aviso de colisão ao modelo: "ERRO: O arquivo src/index.js foi modificado no disco durante a sua geração. Por favor, releia o arquivo para obter o conteúdo mais recente antes de editá-lo."

6. O Guia do Arquiteto para Runtimes Guia Soberanos

“Para dominar uma ferramenta, você precisa entender como ela foi construída.”

Ao dissecar o funcionamento interno do Claude Code, Cursor e Cline, percebemos que a experiência do desenvolvedor é inteiramente moldada pelas decisões tomadas dentro do harness. A latência que experimentamos, os custos que incorremos em nossas contas de API e as regressões repentinas no raciocínio são quase nunca devido aos pesos dos modelos. São bugs e escolhas arquiteturais dentro do middleware de orquestração.

Para organizações de engenharia que buscam escalar ferramentas de IA, essa engenharia reversa destaca três práticas vitais:

  1. Audite o Fluxo de Tokens: Se sua equipe usa agentes de desenvolvimento personalizados, monitore as taxas de cache hit do prompt. Se a taxa de hit do cache estiver abaixo de 70%, analise a compilação do seu payload para identificar variáveis voláteis que estão acionando cascatas de invalidação.
  2. Imponha Parsers de Saída Rígidos: Não dependa de LLMs para gerar JSON ou XML perfeitamente limpos. Construa parsers defensivos e tolerantes a erros que possam autocorrigir tags malformadas por meio de loops de feedback localizados, sem interromper o fluxo do desenvolvedor.
  3. Planeje a Soberania: Confiar inteiramente em runtimes fornecidos por terceiros prende sua empresa às suas estruturas de prompts e modelos de custo específicos. Compreender esses padrões de orquestração é o primeiro passo para construir seus próprios runtimes leves, auto-hospedados e transparentes.

Na parte final desta série, levaremos esse conhecimento à sua conclusão lógica: construiremos nosso próprio harness do zero, alcançando total soberania de software sobre nossos fluxos de trabalho agênticos.


Fontes Externas

Leituras Relacionadas no gsstk

Este artigo foi humanamente arquitetado e sintetizado com assistência de IA sob a persona de Daedalus (AI).

Receba novos artigos

Cadastre-se para receber notificações sobre novos artigos direto no seu email

Não enviaremos spam. Você pode cancelar a inscrição a qualquer momento.