La description: hacer que el skill dispare cuando debe

Por: Artiko
agent-skillsplugins-de-agentesia-agentesdescriptionevalsdisparooptimizacion

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 description field in your SKILL.md frontmatter 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 name and description fields 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

FalloSíntomaCausa típica
Falso negativo (under-specified)El usuario pide justo lo que el skill hace y el agente lo ignoraDescription 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 contextoDescription 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"]
  1. Qué hace: verbos concretos, no adjetivos. “Compute summary statistics, add derived columns, generate charts” vale más que “helps with data”.
  2. Cuándo usarlo: la frase imperativa, el ancla de la decisión.
  3. Señales del usuario: vocabulario real — formatos, extensiones, sinónimos — y el permiso explícito de disparar aunque el usuario no nombre el dominio.
  4. 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

EjeQué variarEjemplo
PhrasingFormalidadFormales, casuales, con erratas o abreviaturas
ExplicitnessSi nombra el dominio”analyze this CSV” frente a “my boss wants a chart from this data file”
DetailDensidad de contextoUn prompt escueto junto a otro con rutas, nombres de columna y trasfondo
ComplexityNúmero de pasosTareas 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: trueVerdadero positivoFalso negativo → description demasiado estrecha
should_trigger: falseFalso positivo → description demasiado ampliaVerdadero 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

ErrorPor qué fallaCorrección
”Helps with X”No dice qué hace ni cuándo usarlo; incumple las dos cláusulas should de la especificaciónDos mitades: verbos concretos + “Use this skill when…”
Describir la implementaciónEl agente compara contra el mensaje del usuario, no contra tu arquitecturaReescribir desde la intención del usuario
Solo jerga internaNadie escribe tu vocabulario de equipo en un promptConservar el término técnico y añadir las paráfrasis
Sin fronteraFalsos positivos que contaminan el contexto en tareas vecinasUna cláusula “Not for…” al final
Añadir keywords de las queries fallidasSobreajuste: funciona en la eval, falla en producciónSubir a la categoría general que representan
Optimizar contra todo el setNo hay forma de saber si generalizóSplit fijo 60/40 y elección por validation pass rate
Una sola corrida por queryEl comportamiento del modelo no es determinista3 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 name y description de 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, con query y should_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