Skills do Claude Code Silenciosas? Aqui Está a Correção Real

Skills do Claude Code Silenciosas? Aqui Está a Correção Real

Skills do Claude Code Silenciosas? Aqui Está a Correção Real

Giro uma equipa de dev que vive dentro do Claude Code há quase um ano. Não é "testámos numa sprint" — é "o nosso CI corre nele e os templates de PR são literalmente prompts do Claude". A certa altura, fiquei ambicioso. Construí um conjunto de skills personalizadas para a equipa: `code-review`, `debug-protocol` e `team-conventions`. Vivem em `.claude/skills/`, têm um ar impecável, todo o frontmatter YAML que se possa sonhar — e durante as primeiras semanas, ficaram ali paradas. Mudas. Ignoradas. Como um alarme de incêndio que só toca quando já há fogo.

A parte mais frustrante? Os ficheiros das skills estavam certos. Os caminhos batiam certo. O markdown estava limpo e documentado com esmero. A skill simplesmente nunca disparava. E depois de meses a coçar a cabeça, aprendi a verdade: a culpa nunca foi da skill. Foi minha.

A Armadilha "A Skill Não Disparou"

Para quem nunca olhou para o abismo da configuração de skills do Claude Code, aqui vai a versão curta: skills são pastas em `.claude/skills//SKILL.md`. Cada uma traz um bocado de YAML frontmatter — um nome e uma descrição — seguido das instruções propriamente ditas que o modelo deve seguir quando a skill é ativada.

```markdown
---
name: code-review
description: Usar quando o utilizador pedir uma code review.
---
```

Parece inofensivo. Mas a forma como o Claude Code decide disparar uma skill é lendo *todas* as descrições das skills, metendo-as no system prompt, e fazendo match com o pedido atual. Ou seja, a ativação de skills é essencialmente um jogo de *intent matching*. E se a tua descrição estiver escrita como um gatilho literal de palavras-chave, o jogo está viciado desde o início.

Passámos três semanas a culpar o Claude, a culpar a API, a culpar a fase da lua. Até que fomos ler a documentação oficial de skills em [docs.anthropic.com/en/docs/claude-code/skills](https://docs.anthropic.com/en/docs/claude-code/skills) e percebemos uma coisa desconfortável: o modelo não é preguiçoso, é literal. Só consegue disparar uma skill que *reconheça* como relevante a partir da descrição. E as nossas descrições eram terríveis.

O Problema Real: Descrição Desalinhada

Aqui está a coisa que nos custou demasiado a perceber: **a skill não existe no vácuo.** Existe numa sopa de outras skills, comportamentos built-in, e o que mais estiver no contexto do Claude. Quando um dev escreve algo, o Claude faz um cálculo mental rápido: *"Isto faz match com alguma descrição de skill? Se várias derem match, qual é a mais próxima? Devo só responder diretamente?"*

Se a descrição da tua skill for demasiado estreita, demasiado vaga, ou demasiado focada em keywords, o Claude falha-a. E se a descrição colidir com outra skill ou um comando built-in, o Claude escolhe a errada. O código no teu SKILL.md nunca é o problema. Os metadados é que são.

Aqui estão as três maiores formas disto morder equipas reais.

Cenário 1: A Skill de Code Review Que Não Parava De Dormir

Escrevi a nossa skill `code-review` com a descrição mais óbvia do mundo: *"Usar quando o utilizador pedir uma code review."* Simples, certo? Errado.

Os nossos devs nunca diziam "code review". Diziam:

- "Dás uma olhada no meu PR?"
- "Vê este diff, há qualquer coisa errada."
- "Reveja isto antes de eu fazer merge."
- "Isto não tá over-engineered?"

Adivinhem qual disparou a skill? Nenhuma. O Claude respondia diretamente sem nunca invocar a skill, porque a frase "code review" nunca aparecia na mensagem. A correção foi embaraçosamente simples. Reescrevemos a descrição para ser semântica, não literal:

```yaml
description: >-
Usar para rever alterações de código, pull requests, diffs, ou merge requests.
Disparar em frases como "rever este PR", "verifica o meu diff", "sanity-check
este código", "isto tá bom para merge", ou "olha para estas alterações".
Não para debugging geral ou explicar código.
```

Também adicionámos uma cláusula "Não para". Essa única mudança fez a skill disparar cerca de 80% mais vezes. Skills do Claude Code são fundamentalmente prompt engineering — e o prompt é a descrição.

Cenário 2: O Protocolo de Debug Que Nos Fez Ghosting

A nossa skill `debug-protocol` devia ser o herói da equipa. Um processo estruturado, passo a passo, para reproduzir bugs, ver logs, inspecionar estado, e propor fixes. Era linda. Também nunca disparava.

Porquê? Porque a descrição começava com a palavra "debug". E "debug" está por todo o lado no Claude Code. Há uma flag de debug built-in, há comportamento de debugging a nível de sistema, e provavelmente há mais três skills no mesmo diretório a usar linguagem parecida. Quando os nossos devs diziam "ajuda-me a debuggar este teste que falha", o Claude tinha quatro matches plausíveis e escolhia o que tivesse maior *relevância geral do prompt* — quase sempre o comportamento built-in, não a nossa skill personalizada.

Tirámos duas lições disto:

1. **Dêem nomes únicos e específicos às skills.** `debug-protocol` é genérico. `sentry-repro-protocol` ou `memory-leak-hunt` seriam melhores. Nomes genéricos são atropelados por intenções genéricas.
2. **Usem o override manual.** No Claude Code, podem sempre escrever `/debug-protocol` para forçar a skill a correr. Adicionámos isso às convenções da equipa, e de repente a skill não estava morta — só precisava de um convite direto.

Mas aqui vai a visão mais profunda: o modelo escolheu a skill errada porque *nós* desenhámos uma colisão. Se tiverem duas skills que soam parecidas, o Claude adivinha. Façam as descrições desqualificarem-se mutuamente. Digam ao Claude explicitamente: "usar isto em vez do comportamento geral de debugging quando o assunto envolver logs de servidor."

Cenário 3: A Skill De Convenções Da Equipa Que Esquecia Tudo

O falhanço mais estranho veio da nossa skill `team-conventions`. Guardava as regras para mensagens de commit, naming de branches, e descrições de PR. Funcionava lindamente no início da sessão e parava algures pela mensagem 20. Assumimos que o modelo estava "a esquecer". Não era bug de memória — era contexto.

O Claude Code mete todas as descrições de skills no system prompt. Descrições longas comem contexto. E quando a conversa cresce, o sistema começa a comprimir ou truncar o system prompt para abrir espaço. A nossa descrição de `team-conventions` era um muro de texto — três parágrafos de jargão corporativo. Era a primeira coisa a ser atirada borda fora quando a janela de contexto apertava.

A correção foi emagrecer a descrição para duas ou três frases e meter as regras reais num ficheiro referenciado dentro da pasta da skill. Agora a descrição é só um sinalizador: *"Usar para convenções de commit message, branch naming, e PR. Regras completas em convention.md."* O modelo aguenta isso, e quando a skill dispara, lê o ficheiro completo. Também movemos regras não-skill para o nosso ficheiro `CLAUDE.md` de memória do projeto, que é carregado de forma mais fiável para instruções de equipa.

Correções Práticas Para Começar Hoje

Depois de semanas de dor, aqui está a checklist que eu gostava que alguém me tivesse dado no dia um.

Tratem a Descrição Como Uma Query De Busca

Se alguém pesquisasse a descrição da tua skill, fazia match com a coisa que realmente queres? Escrevam a descrição como uma string de busca semântica. Incluam sinónimos, frases reais que a vossa equipa usa, e exclusões explícitas. Não assumam que o modelo "sabe o que quiseste dizer". Ele só sabe o que escreveste.

Mantenham Os Ficheiros De Skill Magros

Um ficheiro de skill com 500 linhas é um passivo. Come contexto, é truncado, e torna-se pouco fiável. Mantenham o SKILL.md focado na *decisão* de quando disparar. Empurrem os detalhes pesados para ficheiros auxiliares — `prompt.md`, `criteria.md`, `checklist.md` — que o Claude lê só *depois* da skill ativar.

Adicionem Exemplos Negativos

Parece contra-intuitivo, mas funciona. Na descrição, digam explicitamente para o que a skill *não* serve. Escrevam: *"Não para discussões gerais de arquitetura. Não para dúvidas de sintaxe."* Isto reduz falsos positivos e ajuda o modelo a desambiguar entre skills parecidas. Exemplos negativos são a ferramenta mais afiada da caixa.

Usem `/` Para Override Manual

Não importa o quão bons os vossos metadados fiquem, haverá um momento em que a auto-deteção falha. Treinem a equipa a escrever `/nome-da-skill` quando precisarem de forçar a ativação. Não é falhanço — é fallback. As equipas mais espertas tratam o disparo automático de skills como conveniência, não dependência.

Depurem Isto Como Qualquer Outro Código

O Claude Code tem uma flag `--debug`. Usem-na. Inspeccionem o system prompt que é montado no início da sessão e confirmem que as vossas descrições de skills lá estão mesmo. Parece óbvio, mas descobrimos que uma vírgula a mais num dos nossos blocos de YAML frontmatter estava a invalidar silenciosamente o ficheiro todo. A skill nunca carregava. Não por causa de intent-matching — por causa de um erro de parse. O output de debug apanhou-o em dez segundos.

Testem Com Diferentes Formulações

Não testem só a frase exata da vossa documentação. Abram uma sessão nova e escrevam da forma confusa, humana, ambígua como a vossa equipa fala na realidade. "Este PR vai explodir?" devia disparar a vossa skill de review se as descrições estiverem certas. Se não disparar, a descrição ainda não é suficientemente boa.

FAQ

Por que é que a minha skill funciona numa sessão nova mas pára de disparar mais tarde?

Quase sempre é truncamento de contexto. Descrições longas de skills são largadas do system prompt à medida que a conversa cresce. Emagreçam a descrição, ou reestruturem com ficheiro de referência. Não é problema de memória — é problema de imobiliário.

É melhor usar keywords ou linguagem natural nas descrições de skills?

As duas, na proporção certa. Comecem com uma frase semântica de *intenção* ("usar para rever alterações de código"), depois adicionem uma lista de frases-gatilho comuns. Não confiem só em keywords, mas não sejam tão abstratos que nada faz match.

Uma skill personalizada pode fazer override de comportamento built-in do Claude Code?

Não diretamente. Comportamentos built-in estão ligados a um nível que a tua skill não consegue fazer override. Mas podem ganhar o match tornando a descrição da vossa skill mais específica e relevante para a situação real da vossa equipa. Se estiverem presos, usem `/nome-da-skill` para forçar, ou reformulem o pedido para que o caminho built-in deixe de fazer fit.

Como sei se o meu ficheiro de skill está sequer a carregar?

Corram `claude --debug` e inspeccionem o output. Devem ver as vossas skills listadas na montagem do system prompt. Se a skill não estiver listada, verifiquem o YAML frontmatter, a estrutura da pasta, e o nome do ficheiro. Uma pasta de skill sem `SKILL.md` válido é só decoração.

O Fundo Da Questão

Aqui vai a verdade desconfortável: quando uma skill não dispara, o ficheiro da skill quase nunca é o problema. O problema é quão bem traduziram a intenção humana — "reveja o meu trabalho, siga as nossas regras, fixe este bug da forma que combinámos" — nos metadados que o Claude lê de facto. Não é sobre escrever melhor código. É sobre escrever melhores *sinalizadores*.

Se estão frustrados com skills mudas, não reescrevam o vosso markdown do zero. Reescrevam as descrições. Adicionem exemplos reais. Adicionem exclusões. Mantenham o ficheiro magro. E quando tudo o resto falhar, escrevam `/nome-da-skill` directamente e sigam com o vosso dia.

A skill não está partida. E acreditem ou não, o Claude também não. Nós é que nos esquecemos que o modelo precisa de ser convidado para a festa com mais do que um vago aceno de cabeça do outro lado da sala.

Comments (0)

No comments yet. Be the first to comment!

Leave a Comment