La description: hacer que el skill dispare cuando debe
La description: hacer que el skill dispare cuando debe
Puedes escribir el mejor SKILL.md del mundo: instrucciones calibradas, gotchas
reales, scripts probados. Si el agente nunca lo abre, ese trabajo vale cero. La
documentación oficial lo dice sin rodeos — “A skill only helps if it gets
activated” — y señala al responsable:
The
descriptionfield in yourSKILL.mdfrontmatter is the primary mechanism agents use to decide whether to load a skill for a given task.
Este capítulo trata exclusivamente de ese campo: por qué carga con todo el peso del disparo, cómo redactarlo y cómo comprobar empíricamente que dispara cuando debe y calla cuando no.
Por qué la description lo decide todo
En el capítulo 3 vimos la divulgación progresiva (progressive disclosure). Recordemos la etapa 1, literal de la especificación:
Metadata (~100 tokens): The
nameanddescriptionfields are loaded at startup for all skills
Al arrancar la sesión el agente no tiene tu SKILL.md, ni tus scripts, ni tus
references/. Tiene dos strings por skill instalado. Con eso, y solo con eso,
decide si vale la pena gastar contexto en abrir el archivo completo. De ahí que
“the description carries the entire burden of triggering. If the description
doesn’t convey when the skill is useful, the agent won’t know to reach for it.”
flowchart TD
A["Inicio de sesión"] --> B["Catálogo en contexto<br/>solo name + description<br/>de cada skill instalado"]
B --> C["Llega el mensaje del usuario"]
C --> D{"¿Alguna description<br/>coincide con la tarea?"}
D -->|No| E["El agente trabaja sin el skill<br/>tus instrucciones nunca se leen"]
D -->|Sí| F["Se carga el cuerpo completo<br/>del SKILL.md"]
F --> G["El agente sigue las instrucciones<br/>y carga recursos si hace falta"]
Todo lo que escribiste siguiendo el
capítulo 5 vive
detrás del rombo de decisión. La description es la llave.
Los dos modos de fallo
| Fallo | Síntoma | Causa típica |
|---|---|---|
| Falso negativo (under-specified) | El usuario pide justo lo que el skill hace y el agente lo ignora | Description demasiado estrecha, en jerga interna, o que solo dice qué hace y no cuándo usarlo |
| Falso positivo (over-broad) | El skill se activa en tareas ajenas y contamina el contexto | Description genérica, sin frontera con capacidades vecinas |
Los falsos positivos no son inocuos: cada activación indebida mete miles de tokens irrelevantes en el contexto y empuja al agente a seguir un procedimiento que no corresponde.
El matiz que explica muchos “no dispara”
Hay un comportamiento documentado que conviene conocer antes de reescribir nada:
One important nuance: agents typically only consult skills for tasks that require knowledge or capabilities beyond what they can handle alone. A simple, one-step request like “read this PDF” may not trigger a PDF skill even if the description matches perfectly, because the agent can handle it with basic tools.
El agente no consulta el catálogo por deporte: lo consulta cuando percibe que la tarea excede lo que resuelve solo. El mismo párrafo dice dónde sí se juega el partido: “tasks that involve specialized knowledge — an unfamiliar API, a domain-specific workflow, or an uncommon format”. Consecuencia práctica: si tu skill cubre algo que el modelo ya hace bien sin ayuda, ninguna redacción va a forzar el disparo de forma fiable. Eso es un problema de alcance del skill, no de la description.
Lo que la especificación exige
Las tres reglas del campo, literales:
- “Must be 1-1024 characters” — DEBE (must)
- “Should describe both what the skill does and when to use it” — DEBERÍA (should)
- “Should include specific keywords that help agents identify relevant tasks” — DEBERÍA (should)
El límite de 1024 es de caracteres, no de tokens ni de palabras, y es duro:
la guía lo llama literalmente hard limit, y skills-ref validate —la librería
de referencia que la propia especificación señala para validar— rechaza la skill
si lo excedes. Todo lo demás en este capítulo son guías de autoría, no requisitos
del formato. El par canónico de ejemplos de la propia especificación:
# Ejemplo bueno (literal de la especificación)
description: Extracts text and tables from PDF files, fills PDF forms, and merges multiple PDFs. Use when working with PDF documents or when the user mentions PDFs, forms, or document extraction.
# Ejemplo pobre (literal de la especificación)
description: Helps with PDFs.
Observa la estructura del bueno: primera oración qué hace (extraer, rellenar, fusionar), segunda oración cuándo usarlo (trabajando con PDFs, o cuando el usuario menciona PDFs, formularios o extracción). Ese patrón de dos mitades es el esqueleto de casi toda description que funciona.
Cuatro principios de redacción
1. Fraseo imperativo
Use imperative phrasing. Frame the description as an instruction to the agent: “Use this skill when…” rather than “This skill does…” The agent is deciding whether to act, so tell it when to act.
# Descriptivo: el agente tiene que inferir el cuándo
description: This skill contains our team's process for reviewing database migrations.
# Imperativo: el cuándo está dicho
description: Review database migration files before they are merged. Use this skill whenever the user is writing, reviewing, or approving a migration, or asks whether a schema change is safe to deploy.
2. Intención del usuario, no implementación
Focus on user intent, not implementation. Describe what the user is trying to achieve, not the skill’s internal mechanics. The agent matches against what the user asked for.
Si tu texto habla de tus clases internas, no hay nada contra qué comparar.
# Implementación: nadie escribe esto en un prompt
description: Wraps the internal ReportBuilder pipeline and invokes the v2 aggregation service with the tenant-scoped credentials resolver.
# Intención: esto sí se parece a lo que pide un humano
description: Generate monthly billing reports for a customer account. Use this skill when the user asks for an invoice summary, a usage breakdown by tenant, or a month-end revenue report.
3. Peca de insistente
Err on the side of being pushy. Explicitly list contexts where the skill applies, including cases where the user doesn’t name the domain directly: “even if they don’t explicitly mention ‘CSV’ or ‘analysis.’”
Este es el principio que más gente omite: la gente no pide las cosas con el vocabulario de tu dominio, sino con el suyo. Lista cinco formas reales en que alguien pediría la tarea antes de escribir nada: “analiza este CSV”, “sácame el promedio de esta planilla”, “mi jefe quiere un gráfico de estos datos”, “¿por qué esta columna tiene celdas vacías?”, “pásame esto a algo que se pueda leer”.
Solo la primera nombra el dominio. Las otras cuatro son la razón por la que la description tiene que cubrir sinónimos, formatos vecinos y la intención sin nombrar.
4. Concisión
Keep it concise. A few sentences to a short paragraph is usually right.
El catálogo se carga entero en cada sesión. La guía de implementación de clientes estima ~50-100 tokens por skill en esa etapa: con treinta skills instalados, una description hinchada es contexto que pagas siempre, uses o no el skill. El techo de 1024 caracteres es un límite, no un objetivo.
Anatomía de una description que dispara
flowchart LR
A["1 · Qué hace<br/>verbos concretos<br/>de la capacidad"] --> B["2 · Cuándo usarlo<br/>Use this skill when..."]
B --> C["3 · Señales del usuario<br/>formatos, sinónimos,<br/>formas de pedirlo"]
C --> D["4 · Frontera<br/>qué NO cubre y cuál es<br/>la capacidad vecina"]
- Qué hace: verbos concretos, no adjetivos. “Compute summary statistics, add derived columns, generate charts” vale más que “helps with data”.
- Cuándo usarlo: la frase imperativa, el ancla de la decisión.
- Señales del usuario: vocabulario real — formatos, extensiones, sinónimos — y el permiso explícito de disparar aunque el usuario no nombre el dominio.
- Frontera: cuándo no. Es el componente que corta falsos positivos. No está en la lista de principios, pero la guía lo introduce en el bucle de optimización como la respuesta estándar al falso positivo:
If should-not-trigger queries are false-triggering, the description may be too broad. Add specificity about what the skill does not do, or clarify the boundary between this skill and adjacent capabilities.
Delimitar cuesta una cláusula:
description: >
Review and fix Terraform plans before they are applied — check for
destructive resource replacements, missing lifecycle rules, and drift
between state and code. Use this skill when the user shares a `terraform
plan` output, asks whether a change is safe to apply, or is preparing an
infrastructure PR. Not for authoring new modules from scratch or for
debugging provider installation issues.
Esa última oración vale más que veinte palabras clave añadidas al principio.
Ejemplos antes y después
El antes/después canónico de la documentación
# Before
description: Process CSV files.
# After
description: >
Analyze CSV and tabular data files — compute summary statistics,
add derived columns, generate charts, and clean messy data. Use this
skill when the user has a CSV, TSV, or Excel file and wants to
explore, transform, or visualize the data, even if they don't
explicitly mention "CSV" or "analysis."
Su lectura, también literal:
The improved description is more specific about what the skill does (summary stats, derived columns, charts, cleaning) and broader about when it applies (CSV, TSV, Excel; even without explicit keywords).
Fíjate en la asimetría: más específica en el qué, más amplia en el cuándo. Es el movimiento contraintuitivo que resuelve la mayoría de los casos. La tentación es hacer lo opuesto: vaguedad en el qué (“procesa datos”) y estrechez en el cuándo (“cuando el usuario dice CSV”).
Antes/después de un skill de dominio interno
El caso más frecuente de falso negativo: la description escrita en jerga que solo existe dentro del equipo.
# Antes: "conciliación FX" no aparece en ningún prompt real
description: Runs the FX reconciliation procedure per the treasury runbook.
# Después: la jerga se conserva, pero se traduce a lo que el usuario dice
description: >
Reconcile foreign-currency transactions against the bank statement — match
payments, explain rate differences, and produce the daily variance report.
Use this skill when the user asks why the balance does not match, why an
amount differs after conversion, or needs to close the books for a day with
transactions in more than one currency, even if they never say
"reconciliation" or "FX".
Regla operativa: conserva el término técnico y añade las paráfrasis. No elijas entre jerga y lenguaje llano; incluye ambos. Para calibrar el tono con descriptions probadas a escala, el curso hermano de Google Skills recorre un catálogo oficial con más de cien skills reales.
Probar el disparo: el set de eval
Hasta aquí, criterio. A partir de aquí, medición. La guía propone un método reproducible: prompts realistas etiquetados con si deberían o no disparar el skill.
[
{ "query": "I've got a spreadsheet in ~/data/q4_results.xlsx with revenue in col C and expenses in col D — can you add a profit margin column and highlight anything under 10%?", "should_trigger": true },
{ "query": "whats the quickest way to convert this json file to yaml", "should_trigger": false }
]
Ese archivo, eval_queries.json, es el punto de partida de todo el método: el
conjunto de prompts etiquetados contra el que se mide cada versión de la
description. Y el tamaño que recomienda la guía: “Aim for about 20 queries: 8-10
that should trigger and 8-10 that shouldn’t.”
Cómo variar las positivas
| Eje | Qué variar | Ejemplo |
|---|---|---|
| Phrasing | Formalidad | Formales, casuales, con erratas o abreviaturas |
| Explicitness | Si nombra el dominio | ”analyze this CSV” frente a “my boss wants a chart from this data file” |
| Detail | Densidad de contexto | Un prompt escueto junto a otro con rutas, nombres de columna y trasfondo |
| Complexity | Número de pasos | Tareas de un paso junto a flujos multi-paso donde el trabajo del skill está enterrado en una cadena mayor |
Y el criterio que separa una eval útil de una decorativa: “the most useful should-trigger queries are ones where the skill would help but the connection isn’t obvious from the query alone. […] if the query already asks for exactly what the skill does, any reasonable description would trigger.” Una query que repite literalmente las palabras de tu description no mide nada: mide tu capacidad de copiar y pegar.
Cómo variar las negativas: los near-misses
The most valuable negative test cases are near-misses — queries that share keywords or concepts with your skill but actually need something different. These test whether the description is precise, not just broad.
Los ejemplos de la guía para un skill de análisis de CSV, literales.
Débiles (no prueban nada): "Write a fibonacci function" es obviamente
irrelevante; "What's the weather today?" no tiene solapamiento de palabras
clave, es demasiado fácil.
Fuertes: "I need to update the formulas in my Excel budget spreadsheet"
comparte “spreadsheet” y el concepto de datos, pero necesita edición de Excel, no
análisis de CSV; "can you write a python script that reads a csv and uploads each row to our postgres database" involucra CSV, pero la tarea es ETL, no
análisis.
Si tus ocho negativas son todas del tipo “¿qué tiempo hace?”, tu eval siempre pasará y no te dirá nada sobre falsos positivos.
Realismo
Qué incluir, según la guía: rutas de archivo (~/Downloads/report_final_v2.xlsx),
contexto personal ("my manager asked me to..."), detalles específicos (nombres
de columna, de empresa, valores) y lenguaje casual, abreviaturas y erratas
ocasionales. Un prompt de test que no se parece a algo que alguien escribiría de
verdad mide una distribución que no existe.
Medir: trigger rate
El procedimiento base: correr cada query con el skill instalado y observar si el agente lo invoca. Cómo observarlo depende del cliente, y la guía es explícita en que esto varía: “most agent clients provide some form of observability — execution logs, tool call histories, or verbose output — that lets you see which skills were consulted during a run.”
Criterio de aprobación por query: should_trigger: true y el skill se invocó, o
should_trigger: false y no se invocó.
Por qué una sola corrida no sirve
Model behavior is nondeterministic — the same query might trigger the skill on one run but not the next.
De ahí el trigger rate: la fracción de corridas en que el skill se invocó.
- Corridas por query: 3 es un punto de partida razonable
- Umbral: 0.5 por defecto
- Una positiva pasa si su trigger rate está por encima; una negativa, si está por debajo
Con 20 queries a 3 corridas son 60 invocaciones. Eso hay que automatizarlo.
El script
Esta es la estructura general que publica la guía. Detecta la invocación usando
la salida JSON de Claude Code; la propia guía indica reemplazar check_triggered
por la lógica de detección de tu cliente.
#!/bin/bash
QUERIES_FILE="${1:?Usage: $0 <queries.json>}"
SKILL_NAME="my-skill"
RUNS=3
# This example uses Claude Code's JSON output to check for Skill tool calls.
# Replace this function with detection logic for your agent client.
# Should return 0 (success) if the skill was invoked, 1 otherwise.
check_triggered() {
local query="$1"
claude -p "$query" --output-format json 2>/dev/null \
| jq -e --arg skill "$SKILL_NAME" \
'any(.messages[].content[]; .type == "tool_use" and .name == "Skill" and .input.skill == $skill)' \
> /dev/null 2>&1
}
count=$(jq length "$QUERIES_FILE")
for i in $(seq 0 $((count - 1))); do
query=$(jq -r ".[$i].query" "$QUERIES_FILE")
should_trigger=$(jq -r ".[$i].should_trigger" "$QUERIES_FILE")
triggers=0
for run in $(seq 1 $RUNS); do
check_triggered "$query" && triggers=$((triggers + 1))
done
jq -n \
--arg query "$query" \
--argjson should_trigger "$should_trigger" \
--argjson triggers "$triggers" \
--argjson runs "$RUNS" \
'{query: $query, should_trigger: $should_trigger, triggers: $triggers, runs: $runs, trigger_rate: ($triggers / $runs)}'
done | jq -s '.'
Un consejo de coste, literal: “you can stop a run early once the outcome is clear”. No necesitas que el agente termine la tarea, solo saber si abrió el skill.
Leer los resultados
| Disparó (rate > 0.5) | No disparó (rate < 0.5) | |
|---|---|---|
should_trigger: true | Verdadero positivo | Falso negativo → description demasiado estrecha |
should_trigger: false | Falso positivo → description demasiado amplia | Verdadero negativo |
Las queries con trigger rate cercano a 0.5 merecen atención aparte: son señal de que la description no da una respuesta inequívoca para ese caso.
Evitar el sobreajuste: train y validation
Si optimizas contra las veinte queries, terminas con una description que funciona para esas veinte formulaciones y falla con cualquier otra.
- Train set (~60%): the queries you use to identify failures and guide improvements.
- Validation set (~40%): queries you set aside and only use to check whether improvements generalize.
Tres reglas sobre el split: mezcla proporcional de positivas y negativas en
ambos conjuntos, barajar al azar, y mantener el split fijo entre
iteraciones. En la práctica, dos archivos — train_queries.json y
validation_queries.json — y el mismo script contra cada uno.
El bucle de optimización
flowchart TD
A["1 · Evaluar la description actual<br/>en train Y en validation"] --> B["2 · Identificar fallos<br/>SOLO en train"]
B --> C["3 · Revisar la description"]
C --> D{"¿Pasa todo el train<br/>o ya no hay mejora?"}
D -->|No| A
D -->|Sí| E["4 · Elegir la mejor iteración<br/>por su validation pass rate"]
E --> F["5 · Aplicar y verificar<br/>con queries frescas"]
1. Evaluar la description actual en train y validation. Train guía los cambios; validation dice si generalizan.
2. Identificar fallos en el train set, con una instrucción tajante: “only use train set failures to guide your changes — whether you’re revising the description yourself or prompting an LLM, keep validation set results out of the process.”
3. Revisar la description, con cinco criterios:
- Si fallan positivas → demasiado estrecha: amplía el alcance o añade contexto sobre cuándo el skill es útil.
- Si disparan negativas → demasiado amplia: añade especificidad sobre lo que el skill no hace, o aclara la frontera con capacidades adyacentes.
- No añadas las palabras clave de las queries que fallaron. Eso es sobreajuste. Busca la categoría o concepto general que representan.
- Si llevas varias iteraciones atascado, prueba un enfoque estructuralmente distinto en vez de retoques incrementales.
- Vigila el límite de 1024 caracteres: “descriptions tend to grow during optimization”.
4. Repetir hasta que pase todo el train set o dejes de ver mejora significativa.
5. Elegir la mejor iteración por su validation pass rate, con una advertencia que conviene subrayar: “the best description may not be the last one you produced; an earlier iteration might have a higher validation pass rate than later ones that overfit to the train set”. Guarda cada iteración con su par de tasas: la ganadora puede ser la número dos.
Sobre cuándo parar: “Five iterations is usually enough. If performance isn’t improving, the issue may be with the queries (too easy, too hard, or poorly labeled) rather than the description.”
La guía menciona además que el skill
skill-creator
automatiza el bucle de punta a punta: parte el set, evalúa trigger rates en
paralelo, propone mejoras con Claude y genera un informe HTML en vivo.
Aplicar el resultado
Tres pasos de cierre: actualizar el campo description en el frontmatter,
verificar que está bajo el límite de 1024 caracteres, y verificar el disparo.
Para el segundo, la validación formal del frontmatter con la librería de referencia oficial:
skills-ref validate ./my-skill
Para el tercero, la guía distingue dos niveles de rigor: “try a few prompts manually as a quick sanity check. For a more rigorous test, write 5-10 fresh queries (a mix of should-trigger and should-not-trigger) and run them through the eval script — since these queries were never part of the optimization process, they give you an honest check on whether the description generalizes.”
Cinco a diez queries nuevas, que nunca tocaron el proceso. Es tu test set de verdad.
Errores comunes
| Error | Por qué falla | Corrección |
|---|---|---|
| ”Helps with X” | No dice qué hace ni cuándo usarlo; incumple las dos cláusulas should de la especificación | Dos mitades: verbos concretos + “Use this skill when…” |
| Describir la implementación | El agente compara contra el mensaje del usuario, no contra tu arquitectura | Reescribir desde la intención del usuario |
| Solo jerga interna | Nadie escribe tu vocabulario de equipo en un prompt | Conservar el término técnico y añadir las paráfrasis |
| Sin frontera | Falsos positivos que contaminan el contexto en tareas vecinas | Una cláusula “Not for…” al final |
| Añadir keywords de las queries fallidas | Sobreajuste: funciona en la eval, falla en producción | Subir a la categoría general que representan |
| Optimizar contra todo el set | No hay forma de saber si generalizó | Split fijo 60/40 y elección por validation pass rate |
| Una sola corrida por query | El comportamiento del modelo no es determinista | 3 corridas, trigger rate, umbral 0.5 |
Una nota sobre el name
La etapa de descubrimiento carga name y description, así que el nombre
también participa en la decisión. Dentro de las reglas de la especificación
(minúsculas, a-z/0-9 y guiones, 1-64 caracteres, coincidiendo con el
directorio padre), elige un nombre legible en el dominio del usuario:
pdf-processing comunica más que proc-v2. Lo que no funciona es compensar una
description floja con un nombre largo lleno de palabras clave. El nombre
identifica; la description decide.
Dónde encaja esto en el ciclo
Este capítulo cubre la mitad del problema: que el skill se active. La otra mitad — que, una vez activo, produzca buenas salidas — tiene su propia metodología con casos de prueba, baseline sin skill, assertions y grading, y es materia del capítulo 9. Un skill puede disparar el 100% de las veces y producir basura, o producir resultados excelentes y no dispararse nunca. Cuando esté afinado en ambos ejes, el paso siguiente es empaquetarlo y repartirlo: el curso hermano de Agent Plugins Spec cubre cómo agrupar skills y servidores MCP en plugins distribuibles.
Resumen
- En la etapa de descubrimiento el agente solo ve
nameydescriptionde cada skill instalado; la description carga con todo el peso del disparo. - Dos modos de fallo: falsos negativos (demasiado estrecha) y falsos positivos (demasiado amplia, contamina el contexto).
- Matiz documentado: los agentes solo consultan skills para tareas que exceden lo que resuelven solos. Un pedido trivial puede no disparar aunque la description encaje perfecto.
- La especificación exige (DEBE, must) 1-1024 caracteres no vacíos, y recomienda (DEBERÍA, should) describir qué hace y cuándo usarlo, con palabras clave específicas.
- Cuatro principios: fraseo imperativo, intención del usuario sobre implementación, pecar de insistente, y concisión. Estructura en cuatro partes: qué hace, cuándo usarlo, señales y sinónimos del usuario, y frontera explícita de lo que no cubre.
- El movimiento clave del antes/después oficial: más específica en el qué, más amplia en el cuándo.
- Set de eval: ~20 queries en
eval_queries.json, 8-10 positivas y 8-10 negativas, conqueryyshould_trigger. Varía las positivas en cuatro ejes — fraseo, explicitud, detalle y complejidad — y haz las negativas near-misses: comparten palabras clave pero necesitan otra cosa. - Realismo obligatorio: rutas de archivo, contexto personal, nombres de columna, lenguaje casual y erratas. Mide con trigger rate: 3 corridas por query, umbral 0.5 (20 queries × 3 corridas = 60 invocaciones).
- Evita el sobreajuste con split fijo: train ~60% para diagnosticar, validation ~40% solo para comprobar generalización. Bucle de 5 pasos, y elige la mejor iteración por validation pass rate — puede no ser la última.
- Nunca añadas las palabras clave de las queries fallidas: sube a la categoría general que representan. Cinco iteraciones suelen bastar; si no mejora, sospecha del set de queries antes que de la description.
- Al aplicar: actualizar el frontmatter, verificar el límite con
skills-ref validate, y comprobar con 5-10 queries frescas que nunca formaron parte de la optimización.
Siguiente: Scripts y comandos dentro de un skill