Eu tenho um agente de código —Claude Code— que interage com o Linear, meu gerenciador de incidentes, cerca de 800 vezes por mês: lista tarefas, cria incidentes, altera estados, comenta. Eu revisei 165 de suas sessões e contei mais de 500 erros e mais de 370 tentativas de correção.
Nenhum desses casos foi causado por falhas na API do Linear. Todos foram erros de interface: o agente conversava com a linha de comando e a linha de comando não entendia.
A estimativa conservadora do custo é de cerca de 700.000 tokens por mês, consumidos apenas na tentativa de resolver problemas com a ferramenta: repetir comandos, ler mensagens de erro, corrigir, tentar novamente. Um custo oculto que não aparece em nenhuma fatura, mas que é pago em cada sessão.
Contexto: o agente agora é o usuário principal
Uma CLI —uma ferramenta de linha de comandos— foi historicamente projetada para humanos. E humanos são usuários surpreendentemente resilientes. Se um comando falha, eles leem a ajuda com --help. Se a mensagem de erro é confusa, eles pesquisam. Se a ferramenta tem peculiaridades, eles aprendem e evitam reincidir.
Um agente de IA não faz quase nada disso. Ele não acumula experiência entre sessões como uma pessoa faria. Ele lê a documentação com menos atenção do que você imagina. E quando algo falha, ele não para para investigar: improvisa com o que lhe parece mais adequado.
Isso muda quem é o cliente da sua ferramenta. Se um agente a invoca 800 vezes por mês e você a utiliza manualmente três vezes, o principal consumidor dessa interface é o agente. Projetá-la para o humano e esperar que o agente se adapte é otimizar para o usuário minoritário.
Projetar deliberadamente para esse usuário tem nome: agentic experience. É para os agentes o que a experiência de usuário (UX) é para pessoas e a experiência de desenvolvedor (DX) para quem programa com sua API. E seu melhor instrumento de medida não precisa ser construído: você já o está gerando. É o log de erros do agente.
Os erros têm forma
Eu contei como erro toda invocação da CLI que terminou com um código de saída diferente de zero. Com esse critério, os mais de 500 erros não foram aleatórios: praticamente todos se encaixam em três padrões.
| Padrão | O que o agente fazia | O que revela sobre o design |
|---|---|---|
| Flags inventados | Escrevia --status em vez de --state; --priority urgent em vez de --priority 1 | O flag real não era o mais intuitivo |
| Operações ausentes | Tentava buscar texto, filtrar por projeto ou atribuir projeto ao criar: funções que a CLI não possuía | A ferramenta não cobria o fluxo de trabalho real |
| Flags obrigatórios esquecidos | Omitia --sort, --no-pager, --no-interactive | Exigiam escolhas que a ferramenta poderia assumir por conta própria |
Quando o agente escrevia --status, ele não estava inventando: estava adivinhando a interface mais plausível. --status é, objetivamente, um nome tão razoável quanto --state. O agente apostou na forma mais provável, e o design que eu havia construído não coincidiu com essa probabilidade.
Há um quarto problema que esse levantamento não captura, porque nunca produz um comando com falha: a saída verbosa. A CLI gerava listagens em JSON, cerca de 50 tokens por incidente. O comando terminava com sucesso —código de saída zero—, então não contava como erro; mas ao ser multiplicado por longas listagens e pelas 800 invocações mensais, isso representava a outra metade dos 700.000 tokens. Um custo que passa despercebido justamente porque nada quebra.
O erro de leitura
A interpretação confortável desses 500 erros é direta: o agente usa a ferramenta de forma incorreta. Essa é a interpretação errada, e vale a pena desmontá-la peça por peça.
Um flag inventado significa que o nome real não era o mais intuitivo. Um flag obrigatório esquecido significa que tal flag não deveria ser obrigatório: se a ferramenta pode assumir um valor padrão razoável, exigir isso transfere trabalho para quem chama. Uma saída que consome o contexto significa que o formato foi escolhido pensando na audiência errada.
O log de erros de um agente não é uma lista de falhas do agente. É uma especificação: cada erro descreve, em negativo, um pedaço da interface que deveria ter sido construído. E é a especificação mais honesta que você vai receber: gratuita, com uma quantidade que nenhum painel de usuários humanos forneceria, e sem a cortesia com que um humano disfarça os defeitos de uma ferramenta. Uma pessoa que tropeça em uma CLI ruim se cala e se adapta. O agente não se adapta: volta a cometer o mesmo erro amanhã, e depois, deixando registro de cada um deles.
Isso se conecta a um princípio que desenvolvi em outro artigo: o caminho errado deve ser impossível, não proibido. Proibir é documentação —“não use --status"— e a documentação depende de alguém lê-la com atenção. Tornar o erro impossível é design.
A solução, portanto, não era documentar melhor. Era uma ferramenta melhor.
O redesenho
Reescrevi a CLI —chamada lql— baseando-me nesse princípio. Quatro decisões de design concentram quase todo o impacto.
Tolerância ao invés de rejeição. Se o agente escreve --status, a ferramenta aceita isso como um alias de --state e continua. Se escreve --priority urgent, traduz para --priority 1 e informa o que assumiu. O caminho “errado” mais frequente se transforma simplesmente em um caminho certo. A ferramenta não penaliza uma suposição razoável: absorve.
Erros que ensinam o caminho correto. Quando algo realmente não existe, a mensagem não é unknown flag. É uma instrução: --filter não existe. Para filtrar por estado: --state <estado>. Para buscar: lql search "texto". A mensagem de erro vira documentação, entregue no único momento em que o agente vai lê-la com atenção total: logo após falhar.
Zero flags obrigatórios. lql list funciona sem nenhum argumento: ordena por prioridade, filtra pelos estados ativos e detecta o time com base no diretório de trabalho. Não há um --sort para esquecer porque não existe um --sort para usar. Um flag que o agente não pode esquecer simplesmente não é obrigatório.
Saída para o consumidor real. Quem lê a saída é um LLM que paga por cada token. A ferramenta usa TOON (Token-Oriented Object Notation), um formato compacto que codifica o esquema uma vez em um cabeçalho e emite valores posicionais depois.
| Formato | Tokens por incidente | 50 incidentes |
|---|---|---|
| XML | ~70 | ~3.500 |
| JSON | ~50 | ~2.500 |
| TOON | ~25 | ~1.250 |
TOON não é uma invenção própria: é um formato aberto (toonformat.dev) que a ferramenta simplesmente adota. O flag --json continua disponível para scripts e pipelines, onde o consumidor realmente é uma máquina convencional.
O teste
A métrica que mais me convence não é um benchmark de desempenho. É esta.
O agente precisa de um arquivo de instruções para operar com o Linear —em Claude Code, isso é chamado de “skill”—. Com a CLI antiga, esse arquivo tinha 246 linhas. 150 delas eram workarounds: “se acontecer isso, faça aquilo”, “não esqueça de adicionar este flag”, “não use esta forma”. Documentação defensiva, escrita para tapar os buracos da ferramenta.
Após o redesenho, esse arquivo ficou com 205 linhas e zero workarounds. Uma ferramenta tolerante não precisa ser desculpada. As 150 linhas não desapareceram porque foram apagadas: desapareceram porque já não havia nada para documentar.
Os limites desta análise
Por honestidade, é importante delimitar o alcance. Trata-se de um agente —Claude Code— e uma API —Linear—. A distribuição exata dos três padrões de erro mudará com outro agente ou com outra API. A forma do problema —o agente adivinha a interface mais plausível e falha quando essa probabilidade não coincidir com seu design— acredito que não mude, mas essa é uma hipótese, não um dado.
A contagem dos mais de 500 erros e 370 tentativas de correção foi feita ao parsear os arquivos JSON das 165 sessões do Claude Code. A definição de erro já está dada —código de saída diferente de zero—; uma tentativa de correção é uma reexecução do mesmo comando após uma falha anterior. O critério é mecânico e reproduzível: o código de saída não aceita interpretação, embora a contagem derive de uso real e não de um experimento controlado.
Experimente
lql é software livre com licença MIT. O código está em github.com/frr149/lql.
brew install frr149/tools/lql
lql list --team PROD --state Todo --priority urgent
O que fazer se conectar um agente a uma CLI
Se você tem um agente de IA invocando uma ferramenta de linha de comandos —sua ou de terceiros—, já possui o dado necessário para melhorá-la: os erros que o agente comete ao usá-la.
Não os trate como ruído nos logs nem como uma deficiência do agente. Extraia-os, classifique-os por padrões e leia-os como o que realmente são: o plano da sua interface, desenhado em negativo. Cada flag que o agente inventa é uma sugestão de como deveria ser o nome do flag real; cada operação que tenta mas não existe é um pedido de funcionalidade.
Este artigo foi publicado originalmente em espanhol e traduzido com a ajuda de IA.