Os skills que meu agente não conseguia ver
Eu tinha 84 skills instalados e presumia que todos os 84 funcionavam. Cinco não funcionavam. swiftui, testing-philosophy, typeset, web-performance e update-shortcuts-guide chegavam ao modelo como nomes soltos, sem nenhuma descrição anexada, enquanto seus arquivos em disco traziam descrições perfeitamente válidas. Um skill sem descrição não pode ser roteado, porque a descrição é o sinal de roteamento. Aqueles cinco nunca conseguiriam se ativar sozinhos, e nada em lugar nenhum me avisou. Nenhum erro, nenhum aviso, nenhuma linha de log. Eu os encontrei por acaso, e a única razão pela qual consegui provar a causa é que a correção reverteu o problema na minha frente.
{.answer-block}
Resumo
- As descrições de skills entram no contexto de cada turno e dividem um orçamento fixo de caracteres. Se você ultrapassá-lo, descrições são descartadas em silêncio.12
- Eu tinha 84 skills instalados, 82 deles com descrição, somando 21,848 caracteres. Cinco chegaram com o nome presente e a descrição ausente. Em disco, esses cinco tinham de 206 a 336 caracteres cada um.
- Nenhum atributo de arquivo explicava quais cinco foram descartados. Comprimento da descrição, tamanho do arquivo, formato YAML, divergência entre
namee o diretório e data de modificação se sobrepunham entre os descartados e os mantidos. - Reescrevi 74 descrições, baixando o total para 9,885 caracteres. Os cinco skills reapareceram no meio da sessão, na mesma conversa, com as descrições intactas. Hipótese, intervenção, confirmação.
- O orçamento exato não está documentado e hoje é motivo de disputa. A Anthropic tem issues abertas relatando que a fração é calculada contra uma base fixa de 200K e ignora a extensão de contexto de 1M.34
- A regra de reescrita que fez tudo caber: o único trabalho de uma descrição é responder quando isto deve ser invocado. Procedimento, filosofia e caminhos de arquivos pertencem ao corpo, que só é carregado na invocação.
Uma falha sem mensagem de erro
A maioria dos bugs de harness se anuncia sozinha. Um hook termina com código diferente de zero, um servidor MCP se recusa a iniciar, uma chamada de ferramenta devolve um stack trace. O orçamento de descrições não faz nada disso. Ele serve ao modelo, caladinho, uma lista mais curta do que a que está no seu disco, e cada sintoma seguinte parece um problema do modelo em vez de um problema de encanamento.
Percebi lendo a minha própria janela de contexto, e não o meu sistema de arquivos. Ao percorrer a listagem de skills, cinco entradas tinham um nome e nada depois. Todas as outras tinham um nome e uma frase. Fui atrás dos arquivos:
swiftui HAS 322 chars on disk -> DROPPED in context
testing-philosophy HAS 291 chars on disk -> DROPPED in context
typeset HAS 248 chars on disk -> DROPPED in context
web-performance HAS 206 chars on disk -> DROPPED in context
update-shortcuts-guide HAS 336 chars on disk -> DROPPED in context
A consequência é pior do que um skill lento ou errado. Um agente decide se invoca um skill lendo a descrição dele. Tire a descrição e você não degradou o roteamento, você o eliminou. O skill está instalado, é válido e ficou inalcançável. swiftui é o meu skill de padrões do iOS 26, o que significa que toda sessão de Swift que rodei estava voando sem ele.
A Anthropic tem issues abertas descrevendo a mesma falha, inclusive uma intitulada “Skill description budget silently truncates routing information, causing skill routing failures”.2 Ou seja, o comportamento é um bug conhecido, não uma configuração local malfeita. Foi útil descobrir isso, e não me ajudou a achar quais dos meus skills estavam afetados.
Descartando as respostas fáceis
A tentação era adivinhar o mecanismo e corrigir. Tentei primeiro refutar os palpites, porque “cinco skills estão quebrados” e “cinco skills estão quebrados por este motivo” são afirmações bem diferentes.
Se alguma propriedade no nível do arquivo marcasse um skill para descarte, o grupo descartado deveria diferir do grupo mantido em algum ponto mensurável. Comparei os dois:
| Propriedade | Descartados (5) | Mantidos (77) |
|—|—|
| Comprimento médio da descrição | 280 caracteres | 266 caracteres |
| Tamanho médio do arquivo | 9,106 bytes | 7,608 bytes |
| Descrição YAML em escalar de bloco | 2 de 5 | 30 de 77 |
| name diferente do diretório | 1 de 5 | 4 de 77 |
| Data de modificação | de janeiro a julho | de janeiro a julho |
Nada os separava. As descrições descartadas não eram as mais longas, os arquivos não se destacavam pelo tamanho, o estilo de YAML estava misturado nos dois grupos e as datas de modificação cobriam o mesmo intervalo. A posição alfabética também falhou: skills ordenados depois de swiftui mantiveram suas descrições.
Naquele ponto, a posição honesta era que eu tinha um sintoma reproduzível e nenhum mecanismo. Então escrevi isso desse jeito e fui atrás de um teste em vez de uma teoria.
O teste
Se o que importa é o total, então cortar o total deveria restaurar as descrições descartadas, não importa quais arquivos eu cortasse. Essa previsão é refutável e barata.
Reescrevi 74 descrições, levando o total de 21,848 caracteres para 9,885. Os cinco skills antes invisíveis voltaram com a descrição anexada, na mesma sessão, sem reiniciar nada.
É esse o experimento inteiro. Uma previsão, uma intervenção, uma confirmação. O descarte é função do tamanho agregado, e não de qualquer propriedade do arquivo individual, e é exatamente por isso que nenhum atributo por arquivo conseguia distinguir os dois grupos.
Um bug que não deixa rastro ainda deixa um contrafactual. Se você não consegue achar a causa inspecionando a falha, mude uma variável e veja se a falha acompanha.
Quero ser preciso sobre o que não ficou estabelecido. Não sei o orçamento exato, e não vou publicar um número que não consigo sustentar com fonte. A documentação oficial omite o limite.5 Medições da comunidade colocam o teto prático perto de 15,500 a 16,000 caracteres e apontam cerca de 109 caracteres de sobrecarga por entrada vindos das tags XML, do nome do skill e do campo de localização, nada disso capturado por uma contagem crua de caracteres de descrição.6 Com 84 skills, só essa sobrecarga dá cerca de 9,156 caracteres. Enquanto isso, colaboradores da Anthropic relatam que a fração do orçamento é calculada contra uma base fixa de 200K e ignora a extensão de contexto de 1M, então duas sessões na mesma máquina podem receber orçamentos diferentes.34
Minha primeira versão deste achado afirmava que a minha configuração estava “119% acima do orçamento”. Eu tinha multiplicado uma suposição não verificada (1% de uma janela de 1M) por uma medição real e produzido um número confiante sem nada embaixo. Os fatos observados sobrevivem: 21,848 caracteres descartaram cinco descrições, 9,885 não descartaram nenhuma. A porcentagem não sobreviveu, e nunca deveria ter sido escrita.
O único trabalho de uma descrição é rotear
Cortar 12,000 caracteres soa destrutivo. Não foi, porque a maior parte do que morava nessas descrições nunca fazia trabalho de roteamento.
Veja o que o meu skill jiro anunciava, em 686 caracteres:
Filosofia de artesania shokunin para qualidade de código e orgulho profissional. Ativa ao implementar funcionalidades, refatorar código, escrever testes, revisar trabalho ou trabalhar em qualquer mudança não trivial em FastAPI/Python, Swift/SwiftUI, frontends com HTMX e código de infraestrutura. Incorpora três filosofias centrais: Shokunin (excelência nos detalhes invisíveis), Omotenashi (serviço por meio do ofício), Rick Rubin (canalização e destilação criativa). Portão de decisão central: o Evidence Gate (produza prova de qualidade, não sensações sobre ela). Use quando: construir funcionalidades, refatorar, testar, revisar código, corrigir bugs ou qualquer trabalho em que se exija evidência de qualidade antes de relatar a conclusão.
Uns 500 desses caracteres explicam o que o skill contém. Nada disso ajuda a decidir se vale abri-lo. A substituição tem 126 caracteres:
Padrões de artesania e evidência para qualidade de código. Use ao implementar, refatorar, testar, revisar ou corrigir bugs.
As mesmas palavras de gatilho, o mesmo comportamento de roteamento, um quinto do custo. A filosofia não sumiu; ela vive no corpo, que só carrega quando o skill de fato roda. Pagar por ela a cada turno não comprava nada.
O padrão se repetiu no conjunto inteiro. Nove skills update-*-guide carregavam 3,024 caracteres de texto repetido quase idêntico sobre varrer fontes, sincronizar cópias e rodar traduções. Reduzidos a cerca de 115 caracteres cada, eles continuam roteando certo, porque o que os distingue é qual guia atualizam, e não o pipeline que compartilham.
Três regras deram conta do recado:
- Mantenha o gatilho, corte a explicação. Nomes, comandos slash e as palavras que um usuário realmente digitaria ficam. Descrições de procedimento interno saem.
- Caminhos de arquivos pertencem ao corpo. Um caminho não ajuda o modelo a decidir quando invocar alguma coisa.
- Texto repetido compartilhado é sobrecarga pura. Se nove skills dizem a mesma frase, essa frase não distingue nenhum deles.
O segundo imposto: descrições que agem sem serem chamadas
O corte expôs um custo mais sutil. Onze das minhas descrições, 3,808 caracteres no total, traziam linguagem imperativa: ALWAYS, NEVER, MUST, PROACTIVELY, BEFORE. distribute dizia NEVER. no-shortcuts dizia ALWAYS. git-custody dizia BEFORE.
Essas palavras ficam no contexto a cada turno, rodando o skill ou não. Elas são lidas como instruções porque são escritas como instruções, e o modelo não tem jeito confiável de tratar uma descrição como texto de catálogo inerte enquanto trata uma instrução de sistema com a mesma redação como obrigatória.
Um trabalho recente dá nome ao efeito. “The Regression Tax”, medido em cerca de 6,000 execuções sobre dois benchmarks de automação de escritório e três stacks de harness, identifica a osmose de descrições de skills: um skill que muda o comportamento do agente só por estar presente no contexto, mesmo sem nunca ser invocado.1 A conclusão principal é que os melhores skills vencem por regredirem menos, e não por ganharem mais, e que os skills investem demais em orientação procedural enquanto investem de menos em fundamentação e verificação.
A evidência de produção chegou antes da teoria. A Anthropic voltou atrás na ativação automática dos skills embutidos /verify e /code-review na v2.1.215, deixando ambos apenas com invocação explícita.7 Duas versões depois, /deep-research também parou de se autoinvocar.8 São skills pesados cujas execuções não solicitadas custavam mais do que rendiam, ou seja, osmose observada em campo pelo próprio fornecedor e corrigida removendo a ativação em vez de reescrever a descrição.
Então uma descrição grande demais custa duas vezes. Consome orçamento de que outros skills precisam para rotear e exerce uma pressão comportamental que ninguém pediu. Os dois custos caem em turnos nos quais o skill não contribui com nada.
A parte incômoda: o corpo talvez também não governe
“Mova para o corpo” é o conselho que acabei de dar, e ele carrega uma suposição que vale dizer em voz alta: a de que um procedimento carregado pelo agente na invocação de fato governa o que o agente faz. Um novo trabalho de benchmark sugere que essa suposição é mais frágil do que parece.
O HANDBOOK.md testou exatamente isso. Sessenta e cinco tarefas, documentos de políticas de 20 a 124 páginas, agentes trabalhando em e-mail, chat, calendários e comércio dentro de empresas simuladas, com 824 critérios programáticos de avaliação. A melhor de trinta configurações de modelos passou em 36.2% das tentativas, e a maioria das configurações de ponta ficou abaixo de 25%.9
Os modos de falha nomeados são os que importam aqui. Os agentes deixam um pedido plausível vindo do ambiente sobrepor a política vigente. Executam uma verificação obrigatória e depois agem contra o resultado dela. Perdem detalhes das regras em horizontes longos. Nenhuma dessas falhas é de recuperação de informação; o documento esteve disponível o tempo todo.
Então a versão honesta da minha regra é mais estreita que “descrições roteiam, corpos explicam”. Tirar o procedimento da descrição continua correto, porque recupera orçamento de que outros skills precisam para rotear e impede que um texto nunca invocado conduza o comportamento. Os dois são ganhos reais e nenhum depende de o corpo governar bem. O que isso não compra é a confiança de que o procedimento realocado será seguido. Um manual de 124 páginas e um corpo de SKILL.md de 3,000 palavras estão na mesma curva.
A leitura prática: trate o comprimento do corpo como custo, não como vaga de estacionamento gratuita. Se uma regra precisa mesmo valer, uma descrição é o lugar errado para ela e um corpo longo é só um pouquinho melhor. A imposição pertence a algo determinístico (um hook, uma regra de permissão, um teste), e não a uma prosa que se pede a um modelo lembrar enquanto ele faz outra coisa.
Auditando os seus
Comece dentro de uma sessão. Rode /context, que informa se algum skill foi excluído.5 Se ele sinalizar exclusões, você tem o problema e acabou de diagnosticar.
A razão de eu não ter começado por aí é instrutiva: os meus cinco skills não estavam excluídos, eles chegavam com o nome intacto e a descrição removida, uma falha mais silenciosa do que uma entrada ausente e que talvez não apareça do mesmo jeito. Então verifique contra o seu sistema de arquivos de qualquer forma. A checagem não exige ferramenta nenhuma além de um shell:
python3 - <<'PY'
import os, re, glob
rows = []
for f in glob.glob(os.path.expanduser('~/.claude/skills/*/SKILL.md')):
name = os.path.basename(os.path.dirname(f))
fm = re.match(r'^---\s*\n(.*?)\n---\s*\n', open(f, encoding='utf-8', errors='replace').read(), re.S)
if not fm:
continue
d = re.search(r'^description:\s*(.*?)(?=\n[a-zA-Z_-]+:|\Z)', fm.group(1), re.S | re.M)
if not d:
continue
desc = ' '.join(d.group(1).split()).strip('"\'').lstrip('|').strip()
rows.append((len(desc), name))
rows.sort(reverse=True)
print(f'{len(rows)} skills, {sum(r[0] for r in rows)} description chars')
for length, name in rows[:15]:
print(f' {length:4d} {name}')
PY
Depois compare a saída com o que o seu modelo realmente recebeu. A diferença entre as duas é o achado inteiro. Se um skill aparece no seu contexto com um nome e nenhuma frase depois, esse skill está instalado e inalcançável.
Três hábitos saem dessa auditoria:
Faça o orçamento de cada skill novo, não só dos longos. A sobrecarga por entrada acompanha cada skill independentemente do comprimento da descrição, então o décimo skill de 90 caracteres custa mais que 90 caracteres.
Refaça a contagem depois de adicionar skills. Não posso te dar uma margem segura, porque o teto não está documentado e, pelos relatos, varia conforme a fração é calculada.34 Uma checagem empírica ganha de um número de folga calculado que se apoia em uma suposição, que foi exatamente o erro que cometi.
Guarde uma cópia antes de podar. A maioria dos meus diretórios de skills não estava versionada no git, e sete eram links simbólicos para um diretório que nem repositório era, então o git add os recusou com “beyond a symbolic link”. Antes de tudo, escrevi cada descrição original em um arquivo JSON. Controle de versão que você não verificou não é backup.
Pontos principais
- Um skill sem descrição não está degradado, está inalcançável. A descrição carrega a decisão de roteamento inteira.
- A falha é silenciosa por construção. Nenhum erro, nenhum aviso, nenhum log. Rode
/contextpara ver avisos de exclusão e depois compare a listagem do seu contexto com o seu sistema de arquivos, porque uma descrição removida é mais silenciosa do que uma entrada ausente. - Quem provoca o descarte é o tamanho agregado, não as propriedades de cada arquivo. Nenhum atributo do arquivo individual previu quais skills perderam suas descrições.
- Quando a inspeção falha, intervenha. Não consegui achar o mecanismo examinando a falha. Mudar o total e ver a falha se reverter provou o ponto em um passo só.
- Descrições roteiam; corpos explicam. Tudo o que, em uma descrição, não ajuda a decidir quando invocar é pago a cada turno e não rende nada.
- Imperativos em descrições agem sobre você sem serem invocados. ALWAYS e NEVER conduzem o comportamento a partir do catálogo, que é o efeito de osmose medido.1
- Não publique uma porcentagem que você não consegue sustentar com fonte. A minha própria primeira versão multiplicou uma medição real por um orçamento chutado e produziu um número confiante e errado.
Perguntas frequentes
Por que o meu skill do Claude Code não está ativando?
Verifique se o modelo consegue mesmo ver a descrição dele. As descrições de skills entram no contexto de cada turno e dividem um orçamento fixo de caracteres, e ultrapassá-lo descarta descrições em silêncio, sem erro, sem aviso e sem linha de log. Cinco dos meus 84 skills chegavam ao modelo como nomes soltos enquanto seus arquivos em disco traziam descrições perfeitamente válidas. Um skill sem descrição não pode ser roteado.12
Qual é o orçamento de descrições de skills no Claude Code?
O orçamento exato não está documentado e hoje é motivo de disputa, e eu não vou publicar um número que não consigo sustentar com fonte. O que medi: 21,848 caracteres de descrições descartaram cinco descrições, e 9,885 caracteres não descartaram nenhuma. Medições da comunidade colocam o teto prático perto de 15,500 a 16,000 caracteres, com cerca de 109 caracteres de sobrecarga por entrada, e colaboradores da Anthropic relatam que a fração do orçamento é calculada contra uma base fixa de 200K.346
Como auditar quais dos meus skills perderam as descrições?
Comece dentro de uma sessão com /context, que informa se algum skill foi excluído. Depois verifique contra o seu sistema de arquivos mesmo assim, porque os meus cinco não estavam excluídos: chegavam com o nome intacto e a descrição removida, uma falha mais silenciosa do que uma entrada ausente. Some os caracteres de descrição no frontmatter dos seus arquivos SKILL.md e compare essa lista com o que a listagem do seu contexto mostra de fato.5
O que vai na descrição de um skill e o que vai no corpo?
O único trabalho de uma descrição é responder quando o skill deve ser invocado. Mantenha as palavras de gatilho, os nomes e os comandos slash que um usuário realmente digitaria, e mova procedimento, filosofia e caminhos de arquivos para o corpo, que só carrega na invocação. Minha descrição do jiro saiu de 686 caracteres para 126 com o mesmo comportamento de roteamento, porque uns 500 desses caracteres só explicavam o que o skill contém.
As descrições de skills afetam o comportamento mesmo quando o skill nunca roda?
Sim, e esse é o segundo imposto. Onze das minhas descrições traziam ALWAYS, NEVER, MUST, PROACTIVELY e BEFORE, palavras que ficam no contexto a cada turno e são lidas como instruções porque são escritas como instruções. “The Regression Tax” dá a esse efeito o nome de osmose de descrições de skills: um skill que muda o comportamento do agente só por estar presente no contexto, mesmo sem nunca ser invocado.1
Referências
-
“The Regression Tax”, arXiv:2607.22520, 24 de julho de 2026. Aproximadamente 6,000 execuções em dois benchmarks de automação de escritório e três stacks de harness. Nomeia três modos de regressão: osmose de descrições de skills (mudança de comportamento pela presença no contexto, sem invocação), deslocamento da fundamentação e deslocamento da verificação. Conclusão principal: os skills de melhor desempenho superam os demais sobretudo por regredirem menos, e não por ganharem mais. ↩↩↩↩↩
-
Skill description budget silently truncates routing information, causing skill routing failures, issue #64606 de anthropics/claude-code. Veja também Skill descriptions truncated due to context budget constraints, issue #56710. ↩↩↩
-
skillListingBudgetFraction is calculated against a fixed ~200K baseline, not the model’s actual context window, issue #57941 de anthropics/claude-code. ↩↩↩↩
-
Skill description budget uses base context, ignores [1m] extension, issue #57168 de anthropics/claude-code. ↩↩↩↩
-
Extend Claude with skills, documentação do Claude Code. A documentação publicada não informa um orçamento total de caracteres para descrições de skills. Veja também Skills docs omit the 250-character cap for /skills descriptions, issue #40121. ↩↩↩
-
Claude Code skill budget research. Medição da comunidade que coloca o teto prático perto de 15,500 a 16,000 caracteres de metadados totais de skills, com cerca de 109 caracteres de sobrecarga por entrada (tags XML ~85, nome do skill ~20, campo de localização ~4), e que observa que entradas inteiras são ocultadas em vez de truncadas individualmente nos casos medidos. ↩↩
-
Claude Code CHANGELOG, v2.1.215, julho de 2026: os skills embutidos
/verifye/code-reviewnão se autoinvocam mais e exigem invocação explícita. ↩ -
Claude Code CHANGELOG, v2.1.218, 22 de julho de 2026:
/code-reviewroda como subagente em segundo plano e/deep-researchnão se autoinvoca mais. ↩ -
Liudas Panavas, Sebastian Minus, Bradley Monton, Derek Ray, Suhaas Garre, Sushant Mehta e Edwin Chen, “HANDBOOK.md: A Benchmark for Long-Context Agentic Instruction Following”, arXiv:2607.25398, submetido em 28 de julho de 2026. Sessenta e cinco tarefas em cinco domínios (finanças, faturamento médico, seguros, logística, recursos humanos) em dez empresas fictícias, com procedimentos operacionais padrão escritos por especialistas, de 20 a 124 páginas, e 824 critérios programáticos de avaliação. A melhor das trinta configurações de modelos avaliadas passou em 36.2% das tentativas; a maioria das configurações de ponta ficou abaixo de 25%. Padrões de falha nomeados: deixar um pedido plausível vindo do ambiente sobrepor a política vigente, executar uma verificação obrigatória e depois agir contra o resultado dela, e perder detalhes das regras em horizontes longos. ↩