🎚️ O loop de otimização de description
A description é o mecanismo primário de disparo. O run_loop.py automatiza a afinação: divide o eval set em 60% train / 40% held-out test, avalia a description atual (rodando cada query 3 vezes para um trigger rate confiável), chama o Claude para propor melhorias com base no que falhou e reavalia — até 5 iterações.
rodar o loop em background:
python -m scripts.run_loop \ --eval-set trigger-eval.json \ --skill-path ./margem-xlsx \ --model <model-id-da-sessão> \ --max-iterations 5 \ --verbose
Split 60/40
Train para guiar as propostas, test held-out para decidir. O test nunca treina.
3 runs por query
Disparo é estocástico; rodar 3x dá um trigger rate estável em vez de um sim/não barulhento.
Propor → reavaliar → repetir
O Claude vê o que falhou e propõe nova description; o loop reavalia em train e test, até 5x.
💡 Use o model ID da sessão
Passe o model que está rodando a sessão atual, para o teste de disparo bater com o que o usuário realmente experimenta. Rode em background e dê updates periódicos tailando a saída — o loop demora.
🎯 Queries: should-trigger / should-not e near-misses
Gere ~20 queries realistas — o que um usuário real digitaria, com paths, nomes de coluna, backstory, às vezes em minúsculas ou com typos. Metade should-trigger, metade should-not. O ouro está nos near-misses.
✓ should-trigger (8-10)
- ✓Mesmo intent, fraseados diferentes (formal/casual)
- ✓Usuário não nomeia "margem" mas precisa dela
- ✓Usos incomuns; disputa com outra skill onde esta deve vencer
✗ should-not-trigger (8-10)
- →Near-miss: "limpe os duplicados dessa planilha de vendas" (mesmo arquivo, outra tarefa)
- →Domínio adjacente, frase ambígua
- →Evite negativos óbvios: "escreva um fibonacci" não testa nada
trigger-eval.json — queries rotuladas:
[
{"query": "boss mandou Q4 sales.xlsx, quer margem de lucro em %",
"should_trigger": true},
{"query": "remove as linhas duplicadas dessa planilha de vendas",
"should_trigger": false},
{"query": "qual a margem de erro dessa pesquisa de satisfação?",
"should_trigger": false}
]
Por que near-misses pesam
"Margem de erro de uma pesquisa" compartilha a palavra "margem" mas não tem nada a ver com lucro em planilha. Negativos assim forçam a description a discriminar de verdade. Negativos óbvios passam sempre e não ensinam nada ao loop. Bad eval queries levam a bad descriptions.
🧲 Como o triggering realmente funciona
Skills aparecem na lista available_skills com name + description, e o Claude decide consultar pela description. O detalhe que muda tudo: o Claude só consulta skills para tarefas que não resolve fácil sozinho.
✗ query fraca pra testar
"leia este PDF"
"abra esse arquivo"
Simples demais. O Claude resolve direto com ferramentas básicas — não dispara skill, por melhor que a description seja.
✓ query substantiva
"pega esse xlsx de vendas, calcula a margem por SKU e me devolve formatado em %"
Multi-step e especializada — o Claude se beneficia de consultar a skill.
💡 Suas queries de teste precisam ser substantivas
Se você testar disparo com "leia o arquivo X", vai concluir que a description está ruim quando na verdade a query nunca dispararia skill nenhuma. Queries simples e de um passo só são péssimos casos de teste. Combine isso com o fato de o Claude tender a subdisparar: por isso a description deve ser um pouco pushy.
⚖️ Blind comparison: o novo é mesmo melhor?
Quando o usuário pergunta "a versão nova é realmente melhor?", existe a comparação cega. A ideia: dar dois outputs a um agente independente sem dizer qual é qual, deixar ele julgar qualidade, e depois analisar por que o vencedor venceu.
Anonimize os outputs
Output A e Output B, sem rótulo de versão. Um comparador independente avalia sem viés.
Julgue a qualidade
O agente escolhe o melhor. Por ser cego, não favorece "o novo" só por ser novo.
Analise por que venceu
Entender o motivo é mais útil que o placar — diz o que manter na próxima iteração.
Opcional, e tudo bem
Blind comparison exige subagents e a maioria dos casos não precisa — o loop de review humano costuma bastar. Guarde para quando a dúvida "melhorou de verdade?" for cara o suficiente para justificar o rigor extra.
📈 Ler o benchmark sem se enganar
O benchmark traz pass_rate, tokens e tempo por configuração, com média ± desvio e o delta. Mas o número sozinho mente. Faça uma passada de analista antes de comemorar.
benchmark.json (resumo) — o que olhar:
with_skill: pass_rate 0.92 ± 0.05 | 84.8k tok | 23.3s without_skill: pass_rate 0.41 ± 0.18 | 61.2k tok | 18.1s delta: +0.51 pass | +23.6k tok | +5.2s # leia também: assertions que passam em AMBOS (não discriminam) # e evals com desvio alto (possivelmente flaky)
✗ armadilhas de leitura
- ✗Assertion passa com E sem skill → não mede a skill
- ✗Desvio alto num eval → pode ser flaky, não melhora real
- ✗Comemorar pass_rate ignorando explosão de tokens/tempo
✓ leitura saudável
- ✓Olhar o delta entre with_skill e baseline
- ✓Cortar assertions não-discriminantes do set
- ✓Pesar tradeoff: ganho de qualidade vale o custo?
💡 Assertion não-discriminante é ruído
Se "arquivo existe" passa em with_skill e em without_skill, ela infla o pass_rate dos dois igualmente e esconde a diferença real. O sinal está nas assertions que só a skill faz passar. A passada de analista existe para revelar exatamente esses padrões que a média esconde.
🏆 Pro tips: aplicar best_description e empacotar
No fim do loop, pegue o best_description — escolhido pelo test score, não pelo train — aplique no frontmatter e mostre o antes/depois ao usuário com os scores. Depois, empacote.
saída do loop + aplicar + empacotar:
# run_loop retorna:
{ "best_description": "...nova description afinada...",
"train_score": 0.94, "test_score": 0.89, "iterations": 4 }
# aplique no SKILL.md (frontmatter) e mostre antes/depois
# depois empacote a skill final:
python -m scripts.package_skill ./margem-xlsx
# → margem-xlsx.skill (pronto para instalar)
Checklist de pro tips
Escolha sempre pelo test score — o train infla por overfit, o held-out é honesto.
Otimize a description só depois de a skill estar boa no conteúdo; não afine o gatilho de algo que ainda muda.
Revise o eval set com o usuário antes de rodar — queries ruins geram descriptions ruins.
Mantenha a description pushy mas honesta — cobrir near-triggers sim, prometer o que a skill não faz não.
🎯 Por que o test score
Se você escolhesse a description pelo train, premiaria justamente a que decorou os exemplos de treino. O held-out test simula queries que o loop nunca viu — é a melhor proxy do mundo real. Decidir por ele é o que separa uma description que generaliza de uma que só brilha no laboratório.
✅ Resumo do Módulo
Próximo:
Trilha 5 — 🧠 O Que Pensar — princípios e armadilhas ao decidir o que vira skill, como mantê-las saudáveis e o que evitar no longo prazo.