🎚️ El ciclo de optimización de description
La description es el mecanismo principal de activación. El run_loop.py automatiza el ajuste: divide el eval set en 60% train / 40% held-out test, evalúa la description actual (ejecutando cada query 3 veces para una tasa de activación confiable), le pide a Claude que proponga mejoras basadas en lo que falló y vuelve a evaluar, hasta 5 iteraciones.
ejecutar el loop en segundo plano:
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
Usa train para orientar las propuestas y test held-out para decidir. El test nunca se usa para entrenar.
3 ejecuciones por query
La activación es estocástica; ejecutarla 3x da una tasa de activación estable en lugar de un sí o no ruidoso.
Proponer → reevaluar → repetir
Claude ve qué falló y propone una nueva description; el loop vuelve a evaluar en train y test, hasta 5x.
💡 Usa el model ID de la sesión
Pasa el modelo que está ejecutando la sesión actual para que la prueba de activación coincida con lo que realmente experimenta el usuario. Ejecútalo en segundo plano y envía actualizaciones periódicas siguiendo la salida con tail: el bucle demora.
🎯 Consultas: should-trigger / should-not y casos cercanos
Genera ~20 consultas realistas: lo que escribiría un usuario real, con paths, nombres de columnas, contexto previo, a veces en minúsculas o con errores tipográficos. La mitad should-trigger, la otra mitad should-not. El oro está en los near-misses.
✓ debería activarse (8-10)
- ✓La misma intención, formulaciones diferentes (formales/casuales)
- ✓El usuario no menciona «margen», pero la necesita
- ✓Usos poco comunes; conflicto con otra skill en el que esta debe prevalecer
✗ no debería activarse (8-10)
- →Near-miss: "limpia los duplicados de esta hoja de cálculo de ventas" (el mismo archivo, otra tarea)
- →Dominio adyacente, frase ambigua
- →Evita negativos obvios: «escribe un fibonacci» no prueba nada
trigger-eval.json — consultas etiquetadas:
[
{"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 qué importan los casi aciertos
"Margen de error de una investigación" comparte la palabra "margen", pero no tiene nada que ver con las ganancias en una hoja de cálculo. Negativos así obligan a la descripción a discriminar de verdad. Los negativos obvios siempre pasan y no enseñan nada al ciclo. Las consultas de evaluación malas llevan a descripciones malas.
🧲 Cómo funciona realmente el triggering
Las skills aparecen en la lista available_skills con name + description, y Claude decide consultarla según la description. El detalle que lo cambia todo: Claude solo consulta skills para tareas que no puede resolver fácilmente por sí solo.
✗ query débil para probar
"lee este PDF"
"abre este archivo"
Demasiado simple. Claude lo resuelve directamente con herramientas básicas: no activa ninguna skill, por buena que sea la description.
✓ consulta sustantiva
"toma este xlsx de ventas, calcula el margen por SKU y devuélvemelo con formato de %"
De varios pasos y especializada — Claude se beneficia de consultar la skill.
💡 Tus queries de prueba deben ser sustanciales
Si pruebas la activación con "lee el archivo X", concluirás que la description es mala cuando, en realidad, la query nunca activaría ninguna skill. Las queries simples de un solo paso son pésimos casos de prueba. Súmale que Claude tiende a activar menos skills de las debidas: por eso la description debe ser un poco pushy.
⚖️ Comparación a ciegas: ¿lo nuevo es realmente mejor?
Cuando el usuario pregunta "¿la versión nueva es realmente mejor?", existe la comparación a ciegas. La idea: darle dos resultados a un agente independiente sin decir cuál es cuál, dejar que juzgue la calidad y luego analizar por qué ganó la opción vencedora.
Anonimiza los outputs
Output A y Output B, sin etiquetas de versión. Un comparador independiente evalúa sin sesgos.
Evalúa la calidad
El agente elige la mejor opción. Como es ciego, no favorece «lo nuevo» solo por ser nuevo.
Analiza por qué ganó
Entender el motivo es más útil que el puntaje: te dice qué conservar en la próxima iteración.
Opcional, y está bien
La comparación a ciegas requiere subagents y la mayoría de los casos no la necesita: el ciclo de revisión humana suele bastar. Resérvala para cuando la duda «¿realmente mejoró?» sea lo bastante importante como para justificar el rigor adicional.
📈 Leer el benchmark sin engañarte
El benchmark incluye pass_rate, tokens e tiempo por configuración, con media ± desviación y el delta. Pero el número por sí solo engaña. Haz una revisión como analista antes de celebrar.
benchmark.json (resumen) — qué revisar:
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)
✗ trampas de lectura
- ✗La aserción pasa con Y sin la skill → no mide la skill
- ✗Una variación alta en un eval → puede ser flaky, no una mejora real
- ✗Celebrar el pass_rate ignorando la explosión de tokens y tiempo
✓ lectura saludable
- ✓Observar la diferencia entre with_skill y baseline
- ✓Eliminar del conjunto las aserciones que no discriminan
- ✓Sopesa la compensación: ¿la mejora de calidad vale el costo?
💡 Una aserción no discriminante es ruido
Si «el archivo existe» pasa con_skill y sin_skill, infla el pass_rate de ambos por igual y oculta la diferencia real. La señal está en las assertions que solo la skill logra pasar. La pasada de analista existe para revelar exactamente esos patrones que el promedio oculta.
🏆 Consejos profesionales: aplicar best_description y empaquetar
Al final del ciclo, toma el best_description — elegido por el puntaje de prueba, no por el de entrenamiento — aplícalo en el frontmatter y muéstrale al usuario el antes y el después con los puntajes. Después, empaquétalo.
salida del loop + aplicar + empaquetar:
# 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 consejos profesionales
Elige siempre según el test score — el train se infla por overfitting; el held-out es honesto.
Optimiza la description solo después de que la skill tenga buen contenido; no afines el disparador de algo que aún está cambiando.
Revisa el eval set con el usuario antes de ejecutarse: las consultas deficientes generan descriptions deficientes.
Mantén la description persuasiva pero honesta: incluye near-triggers, sí; no prometas lo que la skill no hace.
🎯 Por qué la puntuación de la prueba
Si eligieras la description por el train, premiarías justamente a la que memorizó los ejemplos de entrenamiento. El held-out test simula queries que el loop nunca vio: es el mejor proxy del mundo real. Decidir basándote en él es lo que distingue una description que generaliza de una que solo brilla en el laboratorio.
✅ Resumen del módulo
Próximo:
Ruta 5 — 🧠 Qué Pensar — principios y trampas al decidir qué se convierte en skill, cómo mantenerlas saludables y qué evitar a largo plazo.