Vamos construir uma skill de verdade do começo ao fim: "margem-xlsx" — recebe uma planilha de vendas e adiciona uma coluna de margem de lucro em %. Acompanhe cada estágio.
🎯 Estágio 1 — Capturar o intent (4 perguntas)
Antes de escrever uma linha, o skill-creator faz 4 perguntas. Se a conversa já tem o workflow, extraia das mensagens e só pergunte o que falta. Confirme antes de seguir.
as 4 perguntas → respostas do nosso caso:
1. O que habilita? → adicionar coluna de margem (%) num xlsx de vendas 2. Quando dispara? → usuário menciona planilha, margem, lucro, vendas 3. Formato saída? → mesmo xlsx + nova coluna formatada como % 4. Vale testar? → SIM (saída objetivamente verificável)
💡 Saída verificável → vale testar
A pergunta 4 decide o resto do walkthrough. Transformações de arquivo, extração de dados e geração de código têm saída objetiva — merecem evals. Skills de estilo/arte se avaliam só qualitativamente. Como o nosso caso é uma transformação de planilha, vamos full evals.
📝 Estágio 2 — Draft do SKILL.md
Com o intent fechado, escreva o draft: name, description (o gatilho — pushy, com o que faz E quando usar) e o corpo no imperativo, explicando o porquê.
SKILL.md — draft inicial:
--- name: margem-xlsx description: Adiciona uma coluna de margem de lucro (%) a planilhas de vendas .xlsx. Use sempre que o usuário enviar uma planilha e mencionar margem, lucro, rentabilidade ou comparar receita e custos — mesmo sem pedir "coluna" explicitamente. --- # Margem XLSX Calcule a margem como (receita - custo) / receita e grave numa nova coluna formatada como porcentagem. ## Passos 1. Abra o .xlsx e identifique as colunas de receita e custo (pergunte se ambíguo — não chute). 2. Crie a coluna "Margem" à direita, formatada como %. 3. Preserve abas, fórmulas e formatação existentes. 4. Salve mantendo o nome original com sufixo "-margem".
✗ description fraca
"Mexe em planilhas de vendas."
Vaga, não diz quando disparar, vai subdisparar.
✓ description pushy
Lista verbos + contextos: "margem, lucro, rentabilidade... mesmo sem pedir coluna".
O que faz E quando usar, com near-triggers cobertos.
🧪 Estágio 3 — 2-3 test prompts realistas
Crie de 2 a 3 prompts como um usuário real escreveria — com backstory, paths e detalhes. Mostre ao usuário, salve em evals/evals.json sem assertions ainda.
evals/evals.json — TEMPLATE pronto (só prompts):
{
"skill_name": "margem-xlsx",
"evals": [
{
"id": 1,
"prompt": "minha chefe mandou 'Q4 sales final FINAL v2.xlsx' (tá em Downloads) e quer margem de lucro em %. receita na col C, custo na D acho",
"expected_output": "xlsx com coluna Margem em % à direita",
"files": ["Q4 sales final FINAL v2.xlsx"]
},
{
"id": 2,
"prompt": "tenho esse relatorio de vendas mensal, da pra ver quanto a gente lucra de verdade em cada produto? planilha anexa",
"expected_output": "coluna de rentabilidade por linha em %",
"files": ["vendas_mensal.xlsx"]
},
{
"id": 3,
"prompt": "preciso comparar receita vs custo por SKU nessa planilha e ver a margem",
"expected_output": "coluna Margem = (receita-custo)/receita",
"files": ["skus.xlsx"]
}
]
}
🎯 Valide antes de rodar
Diga ao usuário: "Aqui estão os casos de teste que quero tentar. Estão certos ou quer adicionar mais?". Prompts ruins geram avaliação enganosa — esta confirmação é barata e evita rodar tudo à toa.
📊 Estágio 4 — Assertions verificáveis
Enquanto as runs rodam (não fique parado), escreva as assertions: objetivamente verificáveis, com nomes descritivos, de preferência checadas por script. Cada test case ganha um eval_metadata.json.
eval_metadata.json — TEMPLATE pronto (com assertions):
{
"eval_id": 0,
"eval_name": "margem-q4-receita-custo",
"prompt": "...margem de lucro em %. receita col C, custo D...",
"assertions": [
"Arquivo .xlsx de saída existe com sufixo -margem",
"Coluna 'Margem' presente à direita das demais",
"Coluna Margem formatada como porcentagem (%)",
"Valores batem com (C - D) / C por linha",
"Abas e formatação originais preservadas"
]
}
✗ assertion ruim
- ✗"a planilha ficou boa" (subjetivo)
- ✗"check_1" (nome opaco no viewer)
- ✗"arquivo existe" (passa com ou sem skill)
✓ assertion boa
- ✓"Valores batem com (C-D)/C" (script confere)
- ✓Nome legível: "coluna formatada como %"
- ✓Discrimina with_skill de baseline
⚖️ Estágio 5 — Rodar com-skill vs baseline
Para cada test case, dispare dois subagents no mesmo turno: um com a skill, um sem (baseline = sem skill, pois é skill nova). Organize a saída por iteração e por eval. Capture total_tokens e duration_ms da notificação assim que cada run terminar.
estrutura do workspace + timing.json:
margem-xlsx-workspace/
└── iteration-1/
├── margem-q4-receita-custo/
│ ├── with_skill/outputs/ ← saída com a skill
│ ├── without_skill/outputs/ ← baseline
│ └── timing.json
└── benchmark.json ← gerado pela agregação
# timing.json
{ "total_tokens": 84852, "duration_ms": 23332,
"total_duration_seconds": 23.3 }
Por que no mesmo turno
Lance with_skill e without_skill juntos para terminarem por volta do mesmo tempo. Não rode os com-skill primeiro e volte depois para os baselines — isso introduz viés e dificulta comparar. O timing.json só pode ser capturado quando a notificação chega; processe cada uma na hora.
🔁 Estágio 6 — Avaliar e iterar (timeline)
Com tudo rodado, feche o loop. A timeline numerada abaixo é o ciclo do skill-creator, do grading até a próxima iteração.
Grade cada run
Um grader avalia cada assertion → grading.json com campos text, passed, evidence. Para checagens programáticas, rode um script em vez de olhar no olho.
Agregue o benchmark
python -m scripts.aggregate_benchmark iteration-1 --skill-name margem-xlsx → pass_rate, tempo e tokens por config, com média ± desvio e delta.
Abra o viewer ANTES de você julgar
generate_review.py com --benchmark. Ponha os outputs na frente do humano primeiro. Não escreva HTML próprio.
Leia o feedback e generalize
Feedback vazio = ok. Onde há reclamação, generalize a correção (não overfit), mantenha enxuto, explique o porquê. Script repetido nas 3 runs → bundle em scripts/.
Rerode em iteration-2 e repita
Nova iteração com baselines, reviewer com --previous-workspace. Pare quando o usuário estiver feliz, o feedback vazio ou sem progresso.
💡 O que aconteceu no nosso caso
As 3 runs com-skill escreveram um calc_margem.py quase idêntico — sinal forte de bundlar. Na iteração 2, o script foi para scripts/ e o SKILL.md passou a apontá-lo. Resultado: pass_rate subiu e os tokens por run caíram, porque cada invocação parou de reinventar a roda.
✅ Resumo do Módulo
Próximo:
Módulo 4.5 — 🚀 Dicas Avançadas: Otimização de Description e Benchmark — split 60/40, near-misses, blind comparison e como ler o benchmark sem se enganar.